From e485252045d808f298e73ce23a2787fe8b11e266 Mon Sep 17 00:00:00 2001 From: MioShirosaki Date: Thu, 7 Jul 2022 11:26:00 +0800 Subject: [PATCH] update --- Hin2n/CMakeLists.txt | 153 + Hin2n/build.gradle | 11 + Hin2n/src/main/cpp/edge_jni/edge_android_v2.c | 1124 +++ Hin2n/src/main/cpp/edge_jni/edge_jni.c | 709 ++ Hin2n/src/main/cpp/edge_jni/edge_jni.h | 96 + .../src/main/cpp/edge_jni/tuntap_android_v2.c | 94 + Hin2n/src/main/cpp/n2n_v1 | 1 + Hin2n/src/main/cpp/n2n_v2 | 1 + Hin2n/src/main/cpp/n2n_v2s | 1 + Hin2n/src/main/cpp/n2n_v3 | 1 + Hin2n/src/main/cpp/slog | 1 + Hin2n/src/main/cpp/tun2tap | 1 + Hin2n/src/main/cpp/uip | 1 + Hin2n/src/main/jniLibs/arm64-v8a/libBugly.so | Bin 190656 -> 0 bytes Hin2n/src/main/jniLibs/arm64-v8a/libcrypto.so | Bin 2473552 -> 2853368 bytes .../src/main/jniLibs/arm64-v8a/libedge_jni.so | Bin 22352 -> 0 bytes .../src/main/jniLibs/arm64-v8a/libedge_v1.so | Bin 30560 -> 0 bytes .../src/main/jniLibs/arm64-v8a/libedge_v2.so | Bin 325632 -> 0 bytes .../src/main/jniLibs/arm64-v8a/libedge_v2s.so | Bin 67488 -> 0 bytes .../src/main/jniLibs/arm64-v8a/libedge_v3.so | Bin 310200 -> 0 bytes Hin2n/src/main/jniLibs/arm64-v8a/libn2n_v1.so | Bin 63432 -> 0 bytes .../src/main/jniLibs/arm64-v8a/libn2n_v2s.so | Bin 88008 -> 0 bytes Hin2n/src/main/jniLibs/arm64-v8a/libslog.so | Bin 9992 -> 0 bytes Hin2n/src/main/jniLibs/arm64-v8a/libuip.so | Bin 30544 -> 0 bytes .../jniLibs/armeabi-v7a/include/openssl/aes.h | 92 + .../armeabi-v7a/include/openssl/asn1.h | 886 +++ .../armeabi-v7a/include/openssl/asn1_mac.h | 10 + .../armeabi-v7a/include/openssl/asn1err.h | 256 + .../armeabi-v7a/include/openssl/asn1t.h | 945 +++ .../armeabi-v7a/include/openssl/async.h | 76 + .../armeabi-v7a/include/openssl/asyncerr.h | 42 + .../jniLibs/armeabi-v7a/include/openssl/bio.h | 801 +++ .../armeabi-v7a/include/openssl/bioerr.h | 124 + .../armeabi-v7a/include/openssl/blowfish.h | 61 + .../jniLibs/armeabi-v7a/include/openssl/bn.h | 539 ++ .../armeabi-v7a/include/openssl/bnerr.h | 100 + .../armeabi-v7a/include/openssl/buffer.h | 58 + .../armeabi-v7a/include/openssl/buffererr.h | 34 + .../armeabi-v7a/include/openssl/camellia.h | 83 + .../armeabi-v7a/include/openssl/cast.h | 53 + .../armeabi-v7a/include/openssl/cmac.h | 41 + .../jniLibs/armeabi-v7a/include/openssl/cms.h | 339 + .../armeabi-v7a/include/openssl/cmserr.h | 202 + .../armeabi-v7a/include/openssl/comp.h | 53 + .../armeabi-v7a/include/openssl/comperr.h | 44 + .../armeabi-v7a/include/openssl/conf.h | 168 + .../armeabi-v7a/include/openssl/conf_api.h | 40 + .../armeabi-v7a/include/openssl/conferr.h | 76 + .../armeabi-v7a/include/openssl/crypto.h | 445 ++ .../armeabi-v7a/include/openssl/cryptoerr.h | 57 + .../jniLibs/armeabi-v7a/include/openssl/ct.h | 474 ++ .../armeabi-v7a/include/openssl/cterr.h | 80 + .../jniLibs/armeabi-v7a/include/openssl/des.h | 174 + .../jniLibs/armeabi-v7a/include/openssl/dh.h | 340 + .../armeabi-v7a/include/openssl/dherr.h | 88 + .../jniLibs/armeabi-v7a/include/openssl/dsa.h | 244 + .../armeabi-v7a/include/openssl/dsaerr.h | 72 + .../armeabi-v7a/include/openssl/dtls1.h | 55 + .../armeabi-v7a/include/openssl/e_os2.h | 300 + .../armeabi-v7a/include/openssl/ebcdic.h | 33 + .../jniLibs/armeabi-v7a/include/openssl/ec.h | 1479 ++++ .../armeabi-v7a/include/openssl/ecdh.h | 10 + .../armeabi-v7a/include/openssl/ecdsa.h | 10 + .../armeabi-v7a/include/openssl/ecerr.h | 275 + .../armeabi-v7a/include/openssl/engine.h | 751 ++ .../armeabi-v7a/include/openssl/engineerr.h | 111 + .../jniLibs/armeabi-v7a/include/openssl/err.h | 274 + .../jniLibs/armeabi-v7a/include/openssl/evp.h | 1666 +++++ .../armeabi-v7a/include/openssl/evperr.h | 205 + .../armeabi-v7a/include/openssl/hmac.h | 51 + .../armeabi-v7a/include/openssl/idea.h | 64 + .../jniLibs/armeabi-v7a/include/openssl/kdf.h | 97 + .../armeabi-v7a/include/openssl/kdferr.h | 55 + .../armeabi-v7a/include/openssl/lhash.h | 241 + .../jniLibs/armeabi-v7a/include/openssl/md2.h | 44 + .../jniLibs/armeabi-v7a/include/openssl/md4.h | 51 + .../jniLibs/armeabi-v7a/include/openssl/md5.h | 50 + .../armeabi-v7a/include/openssl/mdc2.h | 42 + .../armeabi-v7a/include/openssl/modes.h | 208 + .../armeabi-v7a/include/openssl/obj_mac.h | 5198 ++++++++++++++ .../armeabi-v7a/include/openssl/objects.h | 175 + .../armeabi-v7a/include/openssl/objectserr.h | 42 + .../armeabi-v7a/include/openssl/ocsp.h | 352 + .../armeabi-v7a/include/openssl/ocsperr.h | 78 + .../armeabi-v7a/include/openssl/opensslconf.h | 195 + .../armeabi-v7a/include/openssl/opensslv.h | 101 + .../armeabi-v7a/include/openssl/ossl_typ.h | 197 + .../jniLibs/armeabi-v7a/include/openssl/pem.h | 378 + .../armeabi-v7a/include/openssl/pem2.h | 13 + .../armeabi-v7a/include/openssl/pemerr.h | 103 + .../armeabi-v7a/include/openssl/pkcs12.h | 223 + .../armeabi-v7a/include/openssl/pkcs12err.h | 81 + .../armeabi-v7a/include/openssl/pkcs7.h | 319 + .../armeabi-v7a/include/openssl/pkcs7err.h | 103 + .../armeabi-v7a/include/openssl/rand.h | 77 + .../armeabi-v7a/include/openssl/rand_drbg.h | 130 + .../armeabi-v7a/include/openssl/randerr.h | 94 + .../jniLibs/armeabi-v7a/include/openssl/rc2.h | 51 + .../jniLibs/armeabi-v7a/include/openssl/rc4.h | 36 + .../jniLibs/armeabi-v7a/include/openssl/rc5.h | 63 + .../armeabi-v7a/include/openssl/ripemd.h | 47 + .../jniLibs/armeabi-v7a/include/openssl/rsa.h | 513 ++ .../armeabi-v7a/include/openssl/rsaerr.h | 167 + .../armeabi-v7a/include/openssl/safestack.h | 207 + .../armeabi-v7a/include/openssl/seed.h | 96 + .../jniLibs/armeabi-v7a/include/openssl/sha.h | 119 + .../jniLibs/armeabi-v7a/include/openssl/srp.h | 135 + .../armeabi-v7a/include/openssl/srtp.h | 50 + .../jniLibs/armeabi-v7a/include/openssl/ssl.h | 2438 +++++++ .../armeabi-v7a/include/openssl/ssl2.h | 24 + .../armeabi-v7a/include/openssl/ssl3.h | 339 + .../armeabi-v7a/include/openssl/sslerr.h | 773 ++ .../armeabi-v7a/include/openssl/stack.h | 83 + .../armeabi-v7a/include/openssl/store.h | 266 + .../armeabi-v7a/include/openssl/storeerr.h | 91 + .../armeabi-v7a/include/openssl/symhacks.h | 37 + .../armeabi-v7a/include/openssl/tls1.h | 1237 ++++ .../jniLibs/armeabi-v7a/include/openssl/ts.h | 559 ++ .../armeabi-v7a/include/openssl/tserr.h | 132 + .../armeabi-v7a/include/openssl/txt_db.h | 57 + .../jniLibs/armeabi-v7a/include/openssl/ui.h | 368 + .../armeabi-v7a/include/openssl/uierr.h | 65 + .../armeabi-v7a/include/openssl/whrlpool.h | 48 + .../armeabi-v7a/include/openssl/x509.h | 1047 +++ .../armeabi-v7a/include/openssl/x509_vfy.h | 628 ++ .../armeabi-v7a/include/openssl/x509err.h | 130 + .../armeabi-v7a/include/openssl/x509v3.h | 937 +++ .../armeabi-v7a/include/openssl/x509v3err.h | 162 + .../src/main/jniLibs/armeabi-v7a/libcrypto.so | Bin 0 -> 2698244 bytes .../main/jniLibs/x86/include/openssl/aes.h | 92 + .../main/jniLibs/x86/include/openssl/asn1.h | 886 +++ .../jniLibs/x86/include/openssl/asn1_mac.h | 10 + .../jniLibs/x86/include/openssl/asn1err.h | 256 + .../main/jniLibs/x86/include/openssl/asn1t.h | 945 +++ .../main/jniLibs/x86/include/openssl/async.h | 76 + .../jniLibs/x86/include/openssl/asyncerr.h | 42 + .../main/jniLibs/x86/include/openssl/bio.h | 801 +++ .../main/jniLibs/x86/include/openssl/bioerr.h | 124 + .../jniLibs/x86/include/openssl/blowfish.h | 61 + .../src/main/jniLibs/x86/include/openssl/bn.h | 539 ++ .../main/jniLibs/x86/include/openssl/bnerr.h | 100 + .../main/jniLibs/x86/include/openssl/buffer.h | 58 + .../jniLibs/x86/include/openssl/buffererr.h | 34 + .../jniLibs/x86/include/openssl/camellia.h | 83 + .../main/jniLibs/x86/include/openssl/cast.h | 53 + .../main/jniLibs/x86/include/openssl/cmac.h | 41 + .../main/jniLibs/x86/include/openssl/cms.h | 339 + .../main/jniLibs/x86/include/openssl/cmserr.h | 202 + .../main/jniLibs/x86/include/openssl/comp.h | 53 + .../jniLibs/x86/include/openssl/comperr.h | 44 + .../main/jniLibs/x86/include/openssl/conf.h | 168 + .../jniLibs/x86/include/openssl/conf_api.h | 40 + .../jniLibs/x86/include/openssl/conferr.h | 76 + .../main/jniLibs/x86/include/openssl/crypto.h | 445 ++ .../jniLibs/x86/include/openssl/cryptoerr.h | 57 + .../src/main/jniLibs/x86/include/openssl/ct.h | 474 ++ .../main/jniLibs/x86/include/openssl/cterr.h | 80 + .../main/jniLibs/x86/include/openssl/des.h | 174 + .../src/main/jniLibs/x86/include/openssl/dh.h | 340 + .../main/jniLibs/x86/include/openssl/dherr.h | 88 + .../main/jniLibs/x86/include/openssl/dsa.h | 244 + .../main/jniLibs/x86/include/openssl/dsaerr.h | 72 + .../main/jniLibs/x86/include/openssl/dtls1.h | 55 + .../main/jniLibs/x86/include/openssl/e_os2.h | 300 + .../main/jniLibs/x86/include/openssl/ebcdic.h | 33 + .../src/main/jniLibs/x86/include/openssl/ec.h | 1479 ++++ .../main/jniLibs/x86/include/openssl/ecdh.h | 10 + .../main/jniLibs/x86/include/openssl/ecdsa.h | 10 + .../main/jniLibs/x86/include/openssl/ecerr.h | 275 + .../main/jniLibs/x86/include/openssl/engine.h | 751 ++ .../jniLibs/x86/include/openssl/engineerr.h | 111 + .../main/jniLibs/x86/include/openssl/err.h | 274 + .../main/jniLibs/x86/include/openssl/evp.h | 1666 +++++ .../main/jniLibs/x86/include/openssl/evperr.h | 205 + .../main/jniLibs/x86/include/openssl/hmac.h | 51 + .../main/jniLibs/x86/include/openssl/idea.h | 64 + .../main/jniLibs/x86/include/openssl/kdf.h | 97 + .../main/jniLibs/x86/include/openssl/kdferr.h | 55 + .../main/jniLibs/x86/include/openssl/lhash.h | 241 + .../main/jniLibs/x86/include/openssl/md2.h | 44 + .../main/jniLibs/x86/include/openssl/md4.h | 51 + .../main/jniLibs/x86/include/openssl/md5.h | 50 + .../main/jniLibs/x86/include/openssl/mdc2.h | 42 + .../main/jniLibs/x86/include/openssl/modes.h | 208 + .../jniLibs/x86/include/openssl/obj_mac.h | 5198 ++++++++++++++ .../jniLibs/x86/include/openssl/objects.h | 175 + .../jniLibs/x86/include/openssl/objectserr.h | 42 + .../main/jniLibs/x86/include/openssl/ocsp.h | 352 + .../jniLibs/x86/include/openssl/ocsperr.h | 78 + .../jniLibs/x86/include/openssl/opensslconf.h | 195 + .../jniLibs/x86/include/openssl/opensslv.h | 101 + .../jniLibs/x86/include/openssl/ossl_typ.h | 197 + .../main/jniLibs/x86/include/openssl/pem.h | 378 + .../main/jniLibs/x86/include/openssl/pem2.h | 13 + .../main/jniLibs/x86/include/openssl/pemerr.h | 103 + .../main/jniLibs/x86/include/openssl/pkcs12.h | 223 + .../jniLibs/x86/include/openssl/pkcs12err.h | 81 + .../main/jniLibs/x86/include/openssl/pkcs7.h | 319 + .../jniLibs/x86/include/openssl/pkcs7err.h | 103 + .../main/jniLibs/x86/include/openssl/rand.h | 77 + .../jniLibs/x86/include/openssl/rand_drbg.h | 130 + .../jniLibs/x86/include/openssl/randerr.h | 94 + .../main/jniLibs/x86/include/openssl/rc2.h | 51 + .../main/jniLibs/x86/include/openssl/rc4.h | 36 + .../main/jniLibs/x86/include/openssl/rc5.h | 63 + .../main/jniLibs/x86/include/openssl/ripemd.h | 47 + .../main/jniLibs/x86/include/openssl/rsa.h | 513 ++ .../main/jniLibs/x86/include/openssl/rsaerr.h | 167 + .../jniLibs/x86/include/openssl/safestack.h | 207 + .../main/jniLibs/x86/include/openssl/seed.h | 96 + .../main/jniLibs/x86/include/openssl/sha.h | 119 + .../main/jniLibs/x86/include/openssl/srp.h | 135 + .../main/jniLibs/x86/include/openssl/srtp.h | 50 + .../main/jniLibs/x86/include/openssl/ssl.h | 2438 +++++++ .../main/jniLibs/x86/include/openssl/ssl2.h | 24 + .../main/jniLibs/x86/include/openssl/ssl3.h | 339 + .../main/jniLibs/x86/include/openssl/sslerr.h | 773 ++ .../main/jniLibs/x86/include/openssl/stack.h | 83 + .../main/jniLibs/x86/include/openssl/store.h | 266 + .../jniLibs/x86/include/openssl/storeerr.h | 91 + .../jniLibs/x86/include/openssl/symhacks.h | 37 + .../main/jniLibs/x86/include/openssl/tls1.h | 1237 ++++ .../src/main/jniLibs/x86/include/openssl/ts.h | 559 ++ .../main/jniLibs/x86/include/openssl/tserr.h | 132 + .../main/jniLibs/x86/include/openssl/txt_db.h | 57 + .../src/main/jniLibs/x86/include/openssl/ui.h | 368 + .../main/jniLibs/x86/include/openssl/uierr.h | 65 + .../jniLibs/x86/include/openssl/whrlpool.h | 48 + .../main/jniLibs/x86/include/openssl/x509.h | 1047 +++ .../jniLibs/x86/include/openssl/x509_vfy.h | 628 ++ .../jniLibs/x86/include/openssl/x509err.h | 130 + .../main/jniLibs/x86/include/openssl/x509v3.h | 937 +++ .../jniLibs/x86/include/openssl/x509v3err.h | 162 + Hin2n/src/main/jniLibs/x86/libcrypto.so | Bin 0 -> 3240184 bytes .../main/jniLibs/x86_64/include/openssl/aes.h | 92 + .../jniLibs/x86_64/include/openssl/asn1.h | 886 +++ .../jniLibs/x86_64/include/openssl/asn1_mac.h | 10 + .../jniLibs/x86_64/include/openssl/asn1err.h | 256 + .../jniLibs/x86_64/include/openssl/asn1t.h | 945 +++ .../jniLibs/x86_64/include/openssl/async.h | 76 + .../jniLibs/x86_64/include/openssl/asyncerr.h | 42 + .../main/jniLibs/x86_64/include/openssl/bio.h | 801 +++ .../jniLibs/x86_64/include/openssl/bioerr.h | 124 + .../jniLibs/x86_64/include/openssl/blowfish.h | 61 + .../main/jniLibs/x86_64/include/openssl/bn.h | 539 ++ .../jniLibs/x86_64/include/openssl/bnerr.h | 100 + .../jniLibs/x86_64/include/openssl/buffer.h | 58 + .../x86_64/include/openssl/buffererr.h | 34 + .../jniLibs/x86_64/include/openssl/camellia.h | 83 + .../jniLibs/x86_64/include/openssl/cast.h | 53 + .../jniLibs/x86_64/include/openssl/cmac.h | 41 + .../main/jniLibs/x86_64/include/openssl/cms.h | 339 + .../jniLibs/x86_64/include/openssl/cmserr.h | 202 + .../jniLibs/x86_64/include/openssl/comp.h | 53 + .../jniLibs/x86_64/include/openssl/comperr.h | 44 + .../jniLibs/x86_64/include/openssl/conf.h | 168 + .../jniLibs/x86_64/include/openssl/conf_api.h | 40 + .../jniLibs/x86_64/include/openssl/conferr.h | 76 + .../jniLibs/x86_64/include/openssl/crypto.h | 445 ++ .../x86_64/include/openssl/cryptoerr.h | 57 + .../main/jniLibs/x86_64/include/openssl/ct.h | 474 ++ .../jniLibs/x86_64/include/openssl/cterr.h | 80 + .../main/jniLibs/x86_64/include/openssl/des.h | 174 + .../main/jniLibs/x86_64/include/openssl/dh.h | 340 + .../jniLibs/x86_64/include/openssl/dherr.h | 88 + .../main/jniLibs/x86_64/include/openssl/dsa.h | 244 + .../jniLibs/x86_64/include/openssl/dsaerr.h | 72 + .../jniLibs/x86_64/include/openssl/dtls1.h | 55 + .../jniLibs/x86_64/include/openssl/e_os2.h | 300 + .../jniLibs/x86_64/include/openssl/ebcdic.h | 33 + .../main/jniLibs/x86_64/include/openssl/ec.h | 1479 ++++ .../jniLibs/x86_64/include/openssl/ecdh.h | 10 + .../jniLibs/x86_64/include/openssl/ecdsa.h | 10 + .../jniLibs/x86_64/include/openssl/ecerr.h | 275 + .../jniLibs/x86_64/include/openssl/engine.h | 751 ++ .../x86_64/include/openssl/engineerr.h | 111 + .../main/jniLibs/x86_64/include/openssl/err.h | 274 + .../main/jniLibs/x86_64/include/openssl/evp.h | 1666 +++++ .../jniLibs/x86_64/include/openssl/evperr.h | 205 + .../jniLibs/x86_64/include/openssl/hmac.h | 51 + .../jniLibs/x86_64/include/openssl/idea.h | 64 + .../main/jniLibs/x86_64/include/openssl/kdf.h | 97 + .../jniLibs/x86_64/include/openssl/kdferr.h | 55 + .../jniLibs/x86_64/include/openssl/lhash.h | 241 + .../main/jniLibs/x86_64/include/openssl/md2.h | 44 + .../main/jniLibs/x86_64/include/openssl/md4.h | 51 + .../main/jniLibs/x86_64/include/openssl/md5.h | 50 + .../jniLibs/x86_64/include/openssl/mdc2.h | 42 + .../jniLibs/x86_64/include/openssl/modes.h | 208 + .../jniLibs/x86_64/include/openssl/obj_mac.h | 5198 ++++++++++++++ .../jniLibs/x86_64/include/openssl/objects.h | 175 + .../x86_64/include/openssl/objectserr.h | 42 + .../jniLibs/x86_64/include/openssl/ocsp.h | 352 + .../jniLibs/x86_64/include/openssl/ocsperr.h | 78 + .../x86_64/include/openssl/opensslconf.h | 195 + .../jniLibs/x86_64/include/openssl/opensslv.h | 101 + .../jniLibs/x86_64/include/openssl/ossl_typ.h | 197 + .../main/jniLibs/x86_64/include/openssl/pem.h | 378 + .../jniLibs/x86_64/include/openssl/pem2.h | 13 + .../jniLibs/x86_64/include/openssl/pemerr.h | 103 + .../jniLibs/x86_64/include/openssl/pkcs12.h | 223 + .../x86_64/include/openssl/pkcs12err.h | 81 + .../jniLibs/x86_64/include/openssl/pkcs7.h | 319 + .../jniLibs/x86_64/include/openssl/pkcs7err.h | 103 + .../jniLibs/x86_64/include/openssl/rand.h | 77 + .../x86_64/include/openssl/rand_drbg.h | 130 + .../jniLibs/x86_64/include/openssl/randerr.h | 94 + .../main/jniLibs/x86_64/include/openssl/rc2.h | 51 + .../main/jniLibs/x86_64/include/openssl/rc4.h | 36 + .../main/jniLibs/x86_64/include/openssl/rc5.h | 63 + .../jniLibs/x86_64/include/openssl/ripemd.h | 47 + .../main/jniLibs/x86_64/include/openssl/rsa.h | 513 ++ .../jniLibs/x86_64/include/openssl/rsaerr.h | 167 + .../x86_64/include/openssl/safestack.h | 207 + .../jniLibs/x86_64/include/openssl/seed.h | 96 + .../main/jniLibs/x86_64/include/openssl/sha.h | 119 + .../main/jniLibs/x86_64/include/openssl/srp.h | 135 + .../jniLibs/x86_64/include/openssl/srtp.h | 50 + .../main/jniLibs/x86_64/include/openssl/ssl.h | 2438 +++++++ .../jniLibs/x86_64/include/openssl/ssl2.h | 24 + .../jniLibs/x86_64/include/openssl/ssl3.h | 339 + .../jniLibs/x86_64/include/openssl/sslerr.h | 773 ++ .../jniLibs/x86_64/include/openssl/stack.h | 83 + .../jniLibs/x86_64/include/openssl/store.h | 266 + .../jniLibs/x86_64/include/openssl/storeerr.h | 91 + .../jniLibs/x86_64/include/openssl/symhacks.h | 37 + .../jniLibs/x86_64/include/openssl/tls1.h | 1237 ++++ .../main/jniLibs/x86_64/include/openssl/ts.h | 559 ++ .../jniLibs/x86_64/include/openssl/tserr.h | 132 + .../jniLibs/x86_64/include/openssl/txt_db.h | 57 + .../main/jniLibs/x86_64/include/openssl/ui.h | 368 + .../jniLibs/x86_64/include/openssl/uierr.h | 65 + .../jniLibs/x86_64/include/openssl/whrlpool.h | 48 + .../jniLibs/x86_64/include/openssl/x509.h | 1047 +++ .../jniLibs/x86_64/include/openssl/x509_vfy.h | 628 ++ .../jniLibs/x86_64/include/openssl/x509err.h | 130 + .../jniLibs/x86_64/include/openssl/x509v3.h | 937 +++ .../x86_64/include/openssl/x509v3err.h | 162 + Hin2n/src/main/jniLibs/x86_64/libcrypto.so | Bin 0 -> 3448344 bytes bundles/n2n_meyerd/.gitignore | 18 + bundles/n2n_meyerd/README | 13 + bundles/n2n_meyerd/n2n_v1/COPYING | 674 ++ bundles/n2n_meyerd/n2n_v1/HACKING | 273 + bundles/n2n_meyerd/n2n_v1/INSTALL | 50 + bundles/n2n_meyerd/n2n_v1/README | 95 + .../n2n_v1/android/tuntap_android.c | 108 + .../n2n_meyerd/n2n_v1/debian/README.Debian | 7 + bundles/n2n_meyerd/n2n_v1/debian/changelog | 12 + bundles/n2n_meyerd/n2n_v1/debian/compat | 1 + bundles/n2n_meyerd/n2n_v1/debian/control | 22 + bundles/n2n_meyerd/n2n_v1/debian/copyright | 23 + bundles/n2n_meyerd/n2n_v1/debian/n2n.dirs | 4 + bundles/n2n_meyerd/n2n_v1/debian/n2n.docs | 3 + bundles/n2n_meyerd/n2n_v1/debian/n2n.install | 2 + bundles/n2n_meyerd/n2n_v1/debian/n2n.manpages | 2 + bundles/n2n_meyerd/n2n_v1/debian/rules | 9 + bundles/n2n_meyerd/n2n_v1/edge.8 | 116 + bundles/n2n_meyerd/n2n_v1/edge.c | 1832 +++++ bundles/n2n_meyerd/n2n_v1/lzoconf.h | 417 ++ bundles/n2n_meyerd/n2n_v1/lzodefs.h | 1807 +++++ bundles/n2n_meyerd/n2n_v1/minilzo.c | 4112 +++++++++++ bundles/n2n_meyerd/n2n_v1/minilzo.h | 106 + bundles/n2n_meyerd/n2n_v1/n2n.c | 966 +++ bundles/n2n_meyerd/n2n_v1/n2n.h | 308 + bundles/n2n_meyerd/n2n_v1/n2n.spec | 47 + bundles/n2n_meyerd/n2n_v1/scripts/mk_SRPM.sh | 30 + bundles/n2n_meyerd/n2n_v1/scripts/mk_deb.sh | 46 + bundles/n2n_meyerd/n2n_v1/scripts/mk_tar.sh | 104 + bundles/n2n_meyerd/n2n_v1/supernode.1 | 40 + bundles/n2n_meyerd/n2n_v1/supernode.c | 528 ++ bundles/n2n_meyerd/n2n_v1/tuntap_freebsd.c | 125 + bundles/n2n_meyerd/n2n_v1/tuntap_linux.c | 122 + bundles/n2n_meyerd/n2n_v1/tuntap_osx.c | 125 + bundles/n2n_meyerd/n2n_v1/twofish.c | 1031 +++ bundles/n2n_meyerd/n2n_v1/twofish.h | 281 + bundles/n2n_meyerd/n2n_v1/version.c | 3 + .../n2n_meyerd/n2n_v1/win32/DotNet/n2n.sln | 26 + .../n2n_meyerd/n2n_v1/win32/DotNet/n2n.suo | Bin 0 -> 24576 bytes .../n2n_meyerd/n2n_v1/win32/DotNet/n2n.vcproj | 263 + bundles/n2n_meyerd/n2n_v1/win32/getopt.c | 1074 +++ bundles/n2n_meyerd/n2n_v1/win32/getopt.h | 169 + bundles/n2n_meyerd/n2n_v1/win32/getopt1.c | 188 + bundles/n2n_meyerd/n2n_v1/win32/n2n_win32.h | 74 + bundles/n2n_meyerd/n2n_v1/win32/wintap.c | 283 + bundles/n2n_meyerd/n2n_v1/win32/wintap.h | 67 + bundles/n2n_meyerd/n2n_v2/CMakeLists.txt | 162 + bundles/n2n_meyerd/n2n_v2/COPYING | 674 ++ bundles/n2n_meyerd/n2n_v2/HACKING | 259 + bundles/n2n_meyerd/n2n_v2/INSTALL | 63 + bundles/n2n_meyerd/n2n_v2/NEW_FEATURES.txt | 6 + bundles/n2n_meyerd/n2n_v2/README | 111 + .../n2n_v2/android/tuntap_android.c | 113 + bundles/n2n_meyerd/n2n_v2/benchmark.c | 108 + .../n2n_meyerd/n2n_v2/benchmark_hashtable.c | 25 + .../cmake/CMakeToolchainFileMingw32.cmake | 17 + .../n2n_meyerd/n2n_v2/debian/README.Debian | 7 + bundles/n2n_meyerd/n2n_v2/debian/changelog | 27 + bundles/n2n_meyerd/n2n_v2/debian/compat | 1 + bundles/n2n_meyerd/n2n_v2/debian/control | 51 + bundles/n2n_meyerd/n2n_v2/debian/copyright | 23 + .../n2n_meyerd/n2n_v2/debian/n2n-edge.default | 34 + .../n2n_meyerd/n2n_v2/debian/n2n-edge.docs | 1 + .../n2n_meyerd/n2n_v2/debian/n2n-edge.init | 156 + .../n2n_meyerd/n2n_v2/debian/n2n-edge.install | 1 + .../n2n_v2/debian/n2n-edge.manpages | 2 + .../n2n_v2/debian/n2n-supernode.default | 9 + .../n2n_v2/debian/n2n-supernode.init | 126 + .../n2n_v2/debian/n2n-supernode.install | 1 + .../n2n_v2/debian/n2n-supernode.manpages | 1 + bundles/n2n_meyerd/n2n_v2/debian/rules | 5 + bundles/n2n_meyerd/n2n_v2/edge.8 | 221 + bundles/n2n_meyerd/n2n_v2/edge.c | 3238 +++++++++ bundles/n2n_meyerd/n2n_v2/gen_keyfile.py | 44 + bundles/n2n_meyerd/n2n_v2/lzoconf.h | 417 ++ bundles/n2n_meyerd/n2n_v2/lzodefs.h | 1807 +++++ bundles/n2n_meyerd/n2n_v2/minilzo.c | 4112 +++++++++++ bundles/n2n_meyerd/n2n_v2/minilzo.h | 106 + bundles/n2n_meyerd/n2n_v2/munin/n2n-supernode | 110 + bundles/n2n_meyerd/n2n_v2/n2n.c | 536 ++ bundles/n2n_meyerd/n2n_v2/n2n.h | 315 + bundles/n2n_meyerd/n2n_v2/n2n.spec | 52 + bundles/n2n_meyerd/n2n_v2/n2n_keyfile.c | 203 + bundles/n2n_meyerd/n2n_v2/n2n_keyfile.h | 101 + bundles/n2n_meyerd/n2n_v2/n2n_test.c | 24 + bundles/n2n_meyerd/n2n_v2/n2n_transforms.h | 78 + bundles/n2n_meyerd/n2n_v2/n2n_v2.7 | 156 + bundles/n2n_meyerd/n2n_v2/n2n_wire.h | 380 + bundles/n2n_meyerd/n2n_v2/scm.h | 24 + bundles/n2n_meyerd/n2n_v2/scripts/mk_SRPM.sh | 30 + bundles/n2n_meyerd/n2n_v2/scripts/mk_deb.sh | 46 + bundles/n2n_meyerd/n2n_v2/scripts/mk_tar.sh | 116 + bundles/n2n_meyerd/n2n_v2/sglib.h | 1951 +++++ bundles/n2n_meyerd/n2n_v2/sn.c | 895 +++ bundles/n2n_meyerd/n2n_v2/supernode.1 | 43 + bundles/n2n_meyerd/n2n_v2/transform_aes.c | 597 ++ bundles/n2n_meyerd/n2n_v2/transform_null.c | 84 + bundles/n2n_meyerd/n2n_v2/transform_tf.c | 491 ++ bundles/n2n_meyerd/n2n_v2/tuntap_freebsd.c | 132 + bundles/n2n_meyerd/n2n_v2/tuntap_linux.c | 164 + bundles/n2n_meyerd/n2n_v2/tuntap_netbsd.c | 146 + bundles/n2n_meyerd/n2n_v2/tuntap_osx.c | 132 + bundles/n2n_meyerd/n2n_v2/twofish.c | 1031 +++ bundles/n2n_meyerd/n2n_v2/twofish.h | 292 + bundles/n2n_meyerd/n2n_v2/unix-scm.c | 52 + bundles/n2n_meyerd/n2n_v2/version.c | 5 + .../n2n_meyerd/n2n_v2/win32/CMakeLists.txt | 7 + .../n2n_meyerd/n2n_v2/win32/DotNet/n2n.sln | 26 + .../n2n_meyerd/n2n_v2/win32/DotNet/n2n.suo | Bin 0 -> 24576 bytes .../n2n_meyerd/n2n_v2/win32/DotNet/n2n.vcproj | 304 + .../n2n_v2/win32/DotNet/supernode.vcproj | 226 + bundles/n2n_meyerd/n2n_v2/win32/getopt.c | 1074 +++ bundles/n2n_meyerd/n2n_v2/win32/getopt.h | 169 + bundles/n2n_meyerd/n2n_v2/win32/getopt1.c | 188 + bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.c | 19 + bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.h | 117 + .../n2n_meyerd/n2n_v2/win32/version-msvc.c | 3 + bundles/n2n_meyerd/n2n_v2/win32/win-scm.c | 255 + bundles/n2n_meyerd/n2n_v2/win32/wintap.c | 310 + bundles/n2n_meyerd/n2n_v2/win32/wintap.h | 68 + bundles/n2n_meyerd/n2n_v2/wire.c | 507 ++ bundles/n2n_meyerd/n2n_v2/wireshark/AUTHORS | 2 + .../n2n_v2/wireshark/CMakeLists.txt | 65 + bundles/n2n_meyerd/n2n_v2/wireshark/COPYING | 340 + bundles/n2n_meyerd/n2n_v2/wireshark/ChangeLog | 0 .../n2n_meyerd/n2n_v2/wireshark/Makefile.am | 131 + .../n2n_v2/wireshark/Makefile.common | 39 + .../n2n_v2/wireshark/Makefile.nmake | 104 + .../n2n_meyerd/n2n_v2/wireshark/moduleinfo.h | 17 + .../n2n_v2/wireshark/moduleinfo.nmake | 28 + .../n2n_meyerd/n2n_v2/wireshark/packet-n2n.c | 153 + .../n2n_meyerd/n2n_v2/wireshark/plugin.rc.in | 34 + bundles/n2n_ntop_v2/.gitignore | 27 + bundles/n2n_ntop_v2/CHANGELOG.md | 89 + bundles/n2n_ntop_v2/CMakeLists.txt | 213 + bundles/n2n_ntop_v2/COPYING | 674 ++ bundles/n2n_ntop_v2/INSTALL | 50 + bundles/n2n_ntop_v2/LICENSE | 674 ++ bundles/n2n_ntop_v2/Makefile.in | 144 + bundles/n2n_ntop_v2/README.md | 126 + bundles/n2n_ntop_v2/autogen.sh | 21 + bundles/n2n_ntop_v2/community.list | 5 + bundles/n2n_ntop_v2/configure.seed | 113 + bundles/n2n_ntop_v2/contributors.txt | 10 + bundles/n2n_ntop_v2/doc/Crypto.md | 202 + bundles/n2n_ntop_v2/doc/HACKING | 267 + bundles/n2n_ntop_v2/doc/IPv6.md | 25 + bundles/n2n_ntop_v2/doc/MTU.md | 54 + bundles/n2n_ntop_v2/doc/Routing.md | 188 + bundles/n2n_ntop_v2/doc/Windows.md | 73 + bundles/n2n_ntop_v2/doc/macOS.md | 12 + bundles/n2n_ntop_v2/doc/n2n_gateway.sh | 76 + bundles/n2n_ntop_v2/doc/new-features.md | 4 + bundles/n2n_ntop_v2/doc/rpm-packaging.md | 11 + bundles/n2n_ntop_v2/edge.8 | 234 + .../n2n_ntop_v2/include/edge_utils_win32.h | 44 + .../n2n_ntop_v2/include/header_encryption.h | 32 + bundles/n2n_ntop_v2/include/lzoconf.h | 417 ++ bundles/n2n_ntop_v2/include/lzodefs.h | 1807 +++++ bundles/n2n_ntop_v2/include/minilzo.h | 106 + bundles/n2n_ntop_v2/include/n2n.h | 485 ++ bundles/n2n_ntop_v2/include/n2n_define.h | 114 + bundles/n2n_ntop_v2/include/n2n_transforms.h | 68 + bundles/n2n_ntop_v2/include/n2n_wire.h | 338 + bundles/n2n_ntop_v2/include/pearson.h | 25 + bundles/n2n_ntop_v2/include/portable_endian.h | 226 + bundles/n2n_ntop_v2/include/random_numbers.h | 38 + bundles/n2n_ntop_v2/include/speck.h | 80 + bundles/n2n_ntop_v2/include/twofish.h | 285 + bundles/n2n_ntop_v2/include/uthash.h | 1230 ++++ bundles/n2n_ntop_v2/legacy/README.md | 33 + bundles/n2n_ntop_v2/legacy/edge_keyschedule.c | 103 + bundles/n2n_ntop_v2/legacy/gen_keyfile.py | 44 + bundles/n2n_ntop_v2/legacy/n2n_keyfile.c | 216 + bundles/n2n_ntop_v2/legacy/n2n_keyfile.h | 117 + bundles/n2n_ntop_v2/legacy/transform_aes.c | 730 ++ bundles/n2n_ntop_v2/legacy/transform_tf.c | 467 ++ bundles/n2n_ntop_v2/n2n.7 | 156 + bundles/n2n_ntop_v2/packages/centos | 1 + .../n2n_ntop_v2/packages/debian/Makefile.in | 38 + bundles/n2n_ntop_v2/packages/debian/README | 21 + .../n2n_ntop_v2/packages/debian/configure.in | 50 + .../packages/debian/debian/COPYRIGHT | 674 ++ .../n2n_ntop_v2/packages/debian/debian/README | 2 + .../packages/debian/debian/changelog.in | 4 + .../n2n_ntop_v2/packages/debian/debian/compat | 1 + .../packages/debian/debian/conffiles | 2 + .../packages/debian/debian/control.in | 25 + .../n2n_ntop_v2/packages/debian/debian/dirs | 3 + .../n2n_ntop_v2/packages/debian/debian/docs | 1 + .../packages/debian/debian/files.in | 1 + .../packages/debian/debian/n2n.debhelper.log | 13 + .../debian/debian/n2n.postrm.debhelper | 6 + .../packages/debian/debian/n2n.substvars | 2 + .../packages/debian/debian/postinst | 56 + .../n2n_ntop_v2/packages/debian/debian/postrm | 11 + .../packages/debian/debian/preinst | 31 + .../n2n_ntop_v2/packages/debian/debian/prerm | 18 + .../packages/debian/debian/rules.in | 59 + .../packages/debian/debian/templates | 7 + .../packages/etc/n2n/edge.conf.sample | 41 + .../packages/etc/n2n/supernode.conf.sample | 14 + .../systemd/system/edge-ntopng@.service.in | 16 + .../etc/systemd/system/edge.service.in | 15 + .../etc/systemd/system/edge@.service.in | 15 + .../etc/systemd/system/supernode.service.in | 16 + .../n2n_ntop_v2/packages/openwrt/README.md | 39 + bundles/n2n_ntop_v2/packages/rpm/Makefile.in | 26 + bundles/n2n_ntop_v2/packages/rpm/configure.in | 58 + bundles/n2n_ntop_v2/packages/rpm/n2n.spec.in | 98 + bundles/n2n_ntop_v2/packages/rpm/rpm-sign.exp | 10 + bundles/n2n_ntop_v2/packages/ubuntu | 1 + bundles/n2n_ntop_v2/src/edge.c | 972 +++ bundles/n2n_ntop_v2/src/edge_utils.c | 2626 +++++++ bundles/n2n_ntop_v2/src/edge_utils_win32.c | 49 + bundles/n2n_ntop_v2/src/example_edge_embed.c | 75 + .../src/example_edge_embed_quick_edge_init.c | 54 + bundles/n2n_ntop_v2/src/example_sn_embed.c | 50 + bundles/n2n_ntop_v2/src/header_encryption.c | 113 + bundles/n2n_ntop_v2/src/minilzo.c | 4112 +++++++++++ bundles/n2n_ntop_v2/src/n2n.c | 468 ++ bundles/n2n_ntop_v2/src/pearson.c | 338 + bundles/n2n_ntop_v2/src/random_numbers.c | 176 + bundles/n2n_ntop_v2/src/sn.c | 442 ++ bundles/n2n_ntop_v2/src/sn_utils.c | 1038 +++ bundles/n2n_ntop_v2/src/speck.c | 883 +++ bundles/n2n_ntop_v2/src/transform_aes.c | 480 ++ bundles/n2n_ntop_v2/src/transform_cc20.c | 292 + bundles/n2n_ntop_v2/src/transform_null.c | 87 + bundles/n2n_ntop_v2/src/transform_speck.c | 218 + bundles/n2n_ntop_v2/src/transform_tf.c | 212 + bundles/n2n_ntop_v2/src/tuntap_freebsd.c | 133 + bundles/n2n_ntop_v2/src/tuntap_linux.c | 275 + bundles/n2n_ntop_v2/src/tuntap_netbsd.c | 145 + bundles/n2n_ntop_v2/src/tuntap_osx.c | 134 + bundles/n2n_ntop_v2/src/twofish.c | 1015 +++ bundles/n2n_ntop_v2/src/wire.c | 532 ++ bundles/n2n_ntop_v2/supernode.1 | 43 + bundles/n2n_ntop_v2/tools/Makefile.in | 46 + bundles/n2n_ntop_v2/tools/benchmark.c | 199 + bundles/n2n_ntop_v2/tools/n2n_decode.c | 371 + bundles/n2n_ntop_v2/win32/CMakeLists.txt | 5 + bundles/n2n_ntop_v2/win32/DotNet/n2n.sln | 26 + bundles/n2n_ntop_v2/win32/DotNet/n2n.suo | Bin 0 -> 24576 bytes bundles/n2n_ntop_v2/win32/DotNet/n2n.vcproj | 300 + .../n2n_ntop_v2/win32/DotNet/supernode.vcproj | 226 + bundles/n2n_ntop_v2/win32/getopt.c | 1074 +++ bundles/n2n_ntop_v2/win32/getopt.h | 169 + bundles/n2n_ntop_v2/win32/getopt1.c | 188 + bundles/n2n_ntop_v2/win32/n2n_win32.h | 113 + bundles/n2n_ntop_v2/win32/version-msvc.c | 3 + bundles/n2n_ntop_v2/win32/winconfig.h | 8 + bundles/n2n_ntop_v2/win32/wintap.c | 433 ++ bundles/n2n_ntop_v2/win32/wintap.h | 69 + bundles/n2n_ntop_v2/wireshark/README.md | 9 + bundles/n2n_ntop_v2/wireshark/n2n.lua | 316 + bundles/n2n_ntop_v3/.ci/build-project.ps1 | 45 + bundles/n2n_ntop_v3/.ci/install-vcpkg.ps1 | 38 + .../.github/workflows/cmake-linux.yml | 59 + .../n2n_ntop_v3/.github/workflows/tests.yml | 558 ++ bundles/n2n_ntop_v3/.gitignore | 52 + bundles/n2n_ntop_v3/.travis.yml | 26 + bundles/n2n_ntop_v3/.yamllint.yml | 8 + bundles/n2n_ntop_v3/CHANGELOG.md | 89 + bundles/n2n_ntop_v3/CMakeLists.txt | 276 + bundles/n2n_ntop_v3/COPYING | 674 ++ bundles/n2n_ntop_v3/INSTALL | 50 + bundles/n2n_ntop_v3/LICENSE | 674 ++ bundles/n2n_ntop_v3/Makefile.in | 284 + bundles/n2n_ntop_v3/README.md | 120 + bundles/n2n_ntop_v3/autogen.sh | 17 + bundles/n2n_ntop_v3/community.list | 63 + bundles/n2n_ntop_v3/configure.seed | 138 + bundles/n2n_ntop_v3/contributors.txt | 9 + bundles/n2n_ntop_v3/doc/Advanced.md | 41 + bundles/n2n_ntop_v3/doc/Authentication.md | 105 + bundles/n2n_ntop_v3/doc/Building.md | 227 + bundles/n2n_ntop_v3/doc/Communities.md | 81 + bundles/n2n_ntop_v3/doc/ConfigurationFiles.md | 73 + bundles/n2n_ntop_v3/doc/Crypto.md | 216 + bundles/n2n_ntop_v3/doc/Faq.md | 72 + bundles/n2n_ntop_v3/doc/Federation.md | 39 + bundles/n2n_ntop_v3/doc/Hacking.md | 262 + bundles/n2n_ntop_v3/doc/ManagementAPI.md | 188 + bundles/n2n_ntop_v3/doc/Routing.md | 188 + bundles/n2n_ntop_v3/doc/Scratchpad.md | 61 + bundles/n2n_ntop_v3/doc/Scripts.md | 55 + bundles/n2n_ntop_v3/doc/TapConfiguration.md | 151 + .../n2n_ntop_v3/doc/TrafficRestrictions.md | 41 + bundles/n2n_ntop_v3/edge.8 | 285 + bundles/n2n_ntop_v3/include/aes.h | 88 + bundles/n2n_ntop_v3/include/auth.h | 43 + bundles/n2n_ntop_v3/include/cc20.h | 78 + bundles/n2n_ntop_v3/include/curve25519.h | 20 + .../n2n_ntop_v3/include/edge_utils_win32.h | 52 + .../n2n_ntop_v3/include/header_encryption.h | 35 + bundles/n2n_ntop_v3/include/hexdump.h | 6 + bundles/n2n_ntop_v3/include/lzoconf.h | 453 ++ bundles/n2n_ntop_v3/include/lzodefs.h | 3268 +++++++++ bundles/n2n_ntop_v3/include/minilzo.h | 106 + bundles/n2n_ntop_v3/include/n2n.h | 284 + bundles/n2n_ntop_v3/include/n2n_define.h | 215 + bundles/n2n_ntop_v3/include/n2n_regex.h | 76 + bundles/n2n_ntop_v3/include/n2n_typedefs.h | 846 +++ bundles/n2n_ntop_v3/include/n2n_wire.h | 226 + .../include/network_traffic_filter.h | 37 + bundles/n2n_ntop_v3/include/pearson.h | 36 + bundles/n2n_ntop_v3/include/portable_endian.h | 226 + bundles/n2n_ntop_v3/include/random_numbers.h | 69 + bundles/n2n_ntop_v3/include/sn_selection.h | 46 + bundles/n2n_ntop_v3/include/speck.h | 142 + bundles/n2n_ntop_v3/include/tf.h | 87 + bundles/n2n_ntop_v3/include/uthash.h | 1230 ++++ bundles/n2n_ntop_v3/legacy/README.md | 33 + bundles/n2n_ntop_v3/legacy/edge_keyschedule.c | 103 + bundles/n2n_ntop_v3/legacy/gen_keyfile.py | 44 + bundles/n2n_ntop_v3/legacy/n2n_keyfile.c | 216 + bundles/n2n_ntop_v3/legacy/n2n_keyfile.h | 117 + bundles/n2n_ntop_v3/legacy/transform_aes.c | 730 ++ bundles/n2n_ntop_v3/legacy/transform_tf.c | 467 ++ bundles/n2n_ntop_v3/n2n.7 | 132 + bundles/n2n_ntop_v3/packages/centos | 1 + .../n2n_ntop_v3/packages/debian/Makefile.in | 41 + bundles/n2n_ntop_v3/packages/debian/README | 21 + .../n2n_ntop_v3/packages/debian/configure.in | 62 + .../packages/debian/debian/COPYRIGHT | 674 ++ .../n2n_ntop_v3/packages/debian/debian/README | 2 + .../packages/debian/debian/changelog.in | 4 + .../n2n_ntop_v3/packages/debian/debian/compat | 1 + .../packages/debian/debian/conffiles | 2 + .../packages/debian/debian/control.in | 25 + .../n2n_ntop_v3/packages/debian/debian/dirs | 3 + .../n2n_ntop_v3/packages/debian/debian/docs | 1 + .../packages/debian/debian/files.in | 1 + .../packages/debian/debian/n2n.substvars | 2 + .../packages/debian/debian/postinst | 56 + .../n2n_ntop_v3/packages/debian/debian/postrm | 11 + .../packages/debian/debian/preinst | 31 + .../n2n_ntop_v3/packages/debian/debian/prerm | 18 + .../packages/debian/debian/rules.in | 59 + .../packages/debian/debian/templates | 7 + .../packages/etc/n2n/edge.conf.sample | 41 + .../packages/etc/n2n/supernode.conf.sample | 15 + .../systemd/system/edge-ntopng@.service.in | 16 + .../etc/systemd/system/edge.service.in | 15 + .../etc/systemd/system/edge@.service.in | 15 + .../etc/systemd/system/supernode.service.in | 16 + bundles/n2n_ntop_v3/packages/openwrt/Makefile | 86 + .../n2n_ntop_v3/packages/openwrt/README.md | 39 + .../packages/openwrt/patches/001-fix-cc.patch | 11 + bundles/n2n_ntop_v3/packages/rpm/Makefile.in | 26 + bundles/n2n_ntop_v3/packages/rpm/configure.in | 58 + bundles/n2n_ntop_v3/packages/rpm/n2n.spec.in | 107 + bundles/n2n_ntop_v3/packages/rpm/rpm-sign.exp | 10 + bundles/n2n_ntop_v3/packages/ubuntu | 1 + bundles/n2n_ntop_v3/scripts/README.md | 9 + .../n2n_ntop_v3/scripts/hack_fakeautoconf.sh | 24 + bundles/n2n_ntop_v3/scripts/indent.sh | 60 + bundles/n2n_ntop_v3/scripts/n2n-ctl | 253 + bundles/n2n_ntop_v3/scripts/n2n-gateway.sh | 76 + bundles/n2n_ntop_v3/scripts/n2n-httpd | 543 ++ bundles/n2n_ntop_v3/scripts/test_harness.sh | 39 + bundles/n2n_ntop_v3/src/aes.c | 1313 ++++ bundles/n2n_ntop_v3/src/auth.c | 179 + bundles/n2n_ntop_v3/src/cc20.c | 421 ++ bundles/n2n_ntop_v3/src/curve25519.c | 356 + bundles/n2n_ntop_v3/src/edge.c | 1366 ++++ bundles/n2n_ntop_v3/src/edge_management.c | 457 ++ bundles/n2n_ntop_v3/src/edge_utils.c | 3829 ++++++++++ bundles/n2n_ntop_v3/src/edge_utils_win32.c | 111 + bundles/n2n_ntop_v3/src/example_edge_embed.c | 78 + .../src/example_edge_embed_quick_edge_init.c | 55 + bundles/n2n_ntop_v3/src/example_sn_embed.c | 51 + bundles/n2n_ntop_v3/src/header_encryption.c | 170 + bundles/n2n_ntop_v3/src/hexdump.c | 45 + bundles/n2n_ntop_v3/src/minilzo.c | 6365 +++++++++++++++++ bundles/n2n_ntop_v3/src/n2n.c | 951 +++ bundles/n2n_ntop_v3/src/n2n_regex.c | 486 ++ .../n2n_ntop_v3/src/network_traffic_filter.c | 783 ++ bundles/n2n_ntop_v3/src/pearson.c | 224 + bundles/n2n_ntop_v3/src/random_numbers.c | 244 + bundles/n2n_ntop_v3/src/sn_management.c | 441 ++ bundles/n2n_ntop_v3/src/sn_selection.c | 253 + bundles/n2n_ntop_v3/src/sn_utils.c | 2930 ++++++++ bundles/n2n_ntop_v3/src/speck.c | 1026 +++ bundles/n2n_ntop_v3/src/supernode.c | 674 ++ bundles/n2n_ntop_v3/src/tf.c | 619 ++ bundles/n2n_ntop_v3/src/transform_aes.c | 246 + bundles/n2n_ntop_v3/src/transform_cc20.c | 170 + bundles/n2n_ntop_v3/src/transform_null.c | 91 + bundles/n2n_ntop_v3/src/transform_speck.c | 174 + bundles/n2n_ntop_v3/src/transform_tf.c | 232 + bundles/n2n_ntop_v3/src/tuntap_freebsd.c | 136 + bundles/n2n_ntop_v3/src/tuntap_linux.c | 281 + bundles/n2n_ntop_v3/src/tuntap_netbsd.c | 148 + bundles/n2n_ntop_v3/src/tuntap_osx.c | 134 + bundles/n2n_ntop_v3/src/wire.c | 727 ++ bundles/n2n_ntop_v3/supernode.1 | 133 + .../n2n_ntop_v3/tests/tests-compress.expected | 44 + .../n2n_ntop_v3/tests/tests-elliptic.expected | 11 + .../n2n_ntop_v3/tests/tests-hashing.expected | 36 + .../tests/tests-transform.expected | 225 + bundles/n2n_ntop_v3/tests/tests-wire.expected | 51 + bundles/n2n_ntop_v3/tools/Makefile.in | 42 + bundles/n2n_ntop_v3/tools/n2n-benchmark.c | 428 ++ bundles/n2n_ntop_v3/tools/n2n-decode.c | 371 + bundles/n2n_ntop_v3/tools/n2n-keygen.c | 76 + bundles/n2n_ntop_v3/tools/tests-compress.c | 165 + bundles/n2n_ntop_v3/tools/tests-elliptic.c | 56 + bundles/n2n_ntop_v3/tools/tests-hashing.c | 67 + bundles/n2n_ntop_v3/tools/tests-transform.c | 164 + bundles/n2n_ntop_v3/tools/tests-wire.c | 201 + bundles/n2n_ntop_v3/uncrustify.cfg | 34 + bundles/n2n_ntop_v3/win32/CMakeLists.txt | 5 + bundles/n2n_ntop_v3/win32/DotNet/n2n.sln | 26 + bundles/n2n_ntop_v3/win32/DotNet/n2n.suo | Bin 0 -> 24576 bytes bundles/n2n_ntop_v3/win32/DotNet/n2n.vcproj | 300 + .../n2n_ntop_v3/win32/DotNet/supernode.vcproj | 226 + bundles/n2n_ntop_v3/win32/Makefile | 19 + bundles/n2n_ntop_v3/win32/getopt.c | 1074 +++ bundles/n2n_ntop_v3/win32/getopt.h | 169 + bundles/n2n_ntop_v3/win32/getopt1.c | 188 + bundles/n2n_ntop_v3/win32/n2n_win32.h | 132 + bundles/n2n_ntop_v3/win32/version-msvc.c | 3 + bundles/n2n_ntop_v3/win32/winconfig.h | 15 + bundles/n2n_ntop_v3/win32/wintap.c | 517 ++ bundles/n2n_ntop_v3/win32/wintap.h | 72 + bundles/n2n_ntop_v3/wireshark/README.md | 9 + bundles/n2n_ntop_v3/wireshark/n2n.lua | 316 + bundles/slog/slog.c | 133 + bundles/slog/slog.h | 24 + bundles/tun2tap/tun2tap.c | 9 + bundles/tun2tap/tun2tap.h | 53 + bundles/tun2tap/tun2tap_appdef.h | 13 + bundles/tun2tap/uip-conf.h | 163 + bundles/uip/README | 13 + bundles/uip/apps/README | 2 + bundles/uip/apps/dhcpc/Makefile.dhcpc | 1 + bundles/uip/apps/dhcpc/dhcpc.c | 356 + bundles/uip/apps/dhcpc/dhcpc.h | 68 + .../uip/apps/hello-world/Makefile.hello-world | 1 + bundles/uip/apps/hello-world/hello-world.c | 100 + bundles/uip/apps/hello-world/hello-world.h | 52 + bundles/uip/apps/resolv/Makefile.resolv | 1 + bundles/uip/apps/resolv/resolv.c | 464 ++ bundles/uip/apps/resolv/resolv.h | 75 + bundles/uip/apps/smtp/Makefile.smtp | 1 + bundles/uip/apps/smtp/makestrings | 40 + bundles/uip/apps/smtp/smtp-strings | 11 + bundles/uip/apps/smtp/smtp-strings.c | 70 + bundles/uip/apps/smtp/smtp-strings.h | 46 + bundles/uip/apps/smtp/smtp.c | 262 + bundles/uip/apps/smtp/smtp.h | 103 + bundles/uip/apps/telnetd/Makefile.telnetd | 1 + bundles/uip/apps/telnetd/shell.c | 123 + bundles/uip/apps/telnetd/shell.h | 104 + bundles/uip/apps/telnetd/telnetd.c | 350 + bundles/uip/apps/telnetd/telnetd.h | 63 + bundles/uip/apps/webclient/Makefile.webclient | 1 + bundles/uip/apps/webclient/makestrings | 40 + bundles/uip/apps/webclient/webclient-strings | 31 + .../uip/apps/webclient/webclient-strings.c | 93 + .../uip/apps/webclient/webclient-strings.h | 31 + bundles/uip/apps/webclient/webclient.c | 439 ++ bundles/uip/apps/webclient/webclient.h | 228 + bundles/uip/apps/webserver/Makefile.webserver | 1 + bundles/uip/apps/webserver/http-strings | 35 + bundles/uip/apps/webserver/http-strings.c | 102 + bundles/uip/apps/webserver/http-strings.h | 34 + bundles/uip/apps/webserver/httpd-cgi.c | 203 + bundles/uip/apps/webserver/httpd-cgi.h | 84 + bundles/uip/apps/webserver/httpd-fs.c | 132 + bundles/uip/apps/webserver/httpd-fs.h | 57 + bundles/uip/apps/webserver/httpd-fs/404.html | 8 + bundles/uip/apps/webserver/httpd-fs/fade.png | Bin 0 -> 196 bytes .../uip/apps/webserver/httpd-fs/files.shtml | 35 + .../uip/apps/webserver/httpd-fs/footer.html | 2 + .../uip/apps/webserver/httpd-fs/header.html | 18 + .../uip/apps/webserver/httpd-fs/index.html | 29 + .../apps/webserver/httpd-fs/processes.shtml | 5 + .../uip/apps/webserver/httpd-fs/stats.shtml | 31 + bundles/uip/apps/webserver/httpd-fs/style.css | 92 + bundles/uip/apps/webserver/httpd-fs/tcp.shtml | 5 + bundles/uip/apps/webserver/httpd-fsdata.c | 607 ++ bundles/uip/apps/webserver/httpd-fsdata.h | 64 + bundles/uip/apps/webserver/httpd.c | 338 + bundles/uip/apps/webserver/httpd.h | 62 + bundles/uip/apps/webserver/makefsdata | 78 + bundles/uip/apps/webserver/makestrings | 40 + bundles/uip/apps/webserver/webserver.h | 49 + bundles/uip/lib/memb.c | 104 + bundles/uip/lib/memb.h | 142 + bundles/uip/uip-1.0-changelog.txt | 98 + bundles/uip/uip/Makefile.include | 47 + bundles/uip/uip/clock.h | 88 + bundles/uip/uip/lc-addrlabels.h | 83 + bundles/uip/uip/lc-switch.h | 76 + bundles/uip/uip/lc.h | 131 + bundles/uip/uip/psock.c | 338 + bundles/uip/uip/psock.h | 380 + bundles/uip/uip/pt.h | 323 + bundles/uip/uip/timer.c | 127 + bundles/uip/uip/timer.h | 86 + bundles/uip/uip/uip-fw.c | 532 ++ bundles/uip/uip/uip-fw.h | 176 + bundles/uip/uip/uip-neighbor.c | 158 + bundles/uip/uip/uip-neighbor.h | 61 + bundles/uip/uip/uip-split.c | 136 + bundles/uip/uip/uip-split.h | 96 + bundles/uip/uip/uip.c | 1897 +++++ bundles/uip/uip/uip.h | 1603 +++++ bundles/uip/uip/uip_arch.h | 138 + bundles/uip/uip/uip_arp.c | 423 ++ bundles/uip/uip/uip_arp.h | 144 + bundles/uip/uip/uiplib.c | 74 + bundles/uip/uip/uiplib.h | 71 + bundles/uip/uip/uipopt.h | 541 ++ bundles/uip/unix/Makefile | 44 + bundles/uip/unix/clock-arch.c | 55 + bundles/uip/unix/clock-arch.h | 40 + bundles/uip/unix/main.c | 218 + bundles/uip/unix/tapdev.c | 152 + bundles/uip/unix/tapdev.h | 45 + bundles/uip/unix/uip-conf.h | 157 + link.bat | 27 + n2n_v1 | 1 + n2n_v2 | 1 + n2n_v2s | 1 + n2n_v3 | 1 + slog | 1 + tun2tap | 1 + uip | 1 + 871 files changed, 230937 insertions(+) create mode 100644 Hin2n/CMakeLists.txt create mode 100644 Hin2n/src/main/cpp/edge_jni/edge_android_v2.c create mode 100644 Hin2n/src/main/cpp/edge_jni/edge_jni.c create mode 100644 Hin2n/src/main/cpp/edge_jni/edge_jni.h create mode 100644 Hin2n/src/main/cpp/edge_jni/tuntap_android_v2.c create mode 120000 Hin2n/src/main/cpp/n2n_v1 create mode 120000 Hin2n/src/main/cpp/n2n_v2 create mode 120000 Hin2n/src/main/cpp/n2n_v2s create mode 120000 Hin2n/src/main/cpp/n2n_v3 create mode 120000 Hin2n/src/main/cpp/slog create mode 120000 Hin2n/src/main/cpp/tun2tap create mode 120000 Hin2n/src/main/cpp/uip delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libBugly.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libedge_jni.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libedge_v1.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2s.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libedge_v3.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libn2n_v1.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libn2n_v2s.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libslog.so delete mode 100644 Hin2n/src/main/jniLibs/arm64-v8a/libuip.so create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/aes.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1_mac.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1t.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/async.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asyncerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bio.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bioerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/blowfish.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bn.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bnerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffer.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffererr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/camellia.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cast.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmac.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cms.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmserr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comp.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comperr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf_api.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conferr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/crypto.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cryptoerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ct.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cterr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/des.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dh.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dherr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsa.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsaerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dtls1.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/e_os2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ebcdic.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ec.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdh.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdsa.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engine.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engineerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evp.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evperr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/hmac.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/idea.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdf.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdferr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/lhash.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md4.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md5.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/mdc2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/modes.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/obj_mac.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objects.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objectserr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsp.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsperr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslconf.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslv.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ossl_typ.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pemerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand_drbg.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/randerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc4.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc5.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ripemd.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsa.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsaerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/safestack.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/seed.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sha.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srp.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srtp.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl2.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl3.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sslerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/stack.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/store.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/storeerr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/symhacks.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tls1.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ts.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tserr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/txt_db.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ui.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/uierr.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/whrlpool.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509_vfy.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3err.h create mode 100644 Hin2n/src/main/jniLibs/armeabi-v7a/libcrypto.so create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/aes.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/asn1.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/asn1_mac.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/asn1err.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/asn1t.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/async.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/asyncerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/bio.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/bioerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/blowfish.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/bn.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/bnerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/buffer.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/buffererr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/camellia.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cast.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cmac.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cms.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cmserr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/comp.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/comperr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/conf.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/conf_api.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/conferr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/crypto.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cryptoerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ct.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/cterr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/des.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/dh.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/dherr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/dsa.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/dsaerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/dtls1.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/e_os2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ebcdic.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ec.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ecdh.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ecdsa.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ecerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/engine.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/engineerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/err.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/evp.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/evperr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/hmac.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/idea.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/kdf.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/kdferr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/lhash.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/md2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/md4.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/md5.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/mdc2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/modes.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/obj_mac.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/objects.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/objectserr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ocsp.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ocsperr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/opensslconf.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/opensslv.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ossl_typ.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pem.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pem2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pemerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12err.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7err.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rand.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rand_drbg.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/randerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rc2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rc4.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rc5.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ripemd.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rsa.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/rsaerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/safestack.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/seed.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/sha.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/srp.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/srtp.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ssl.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ssl2.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ssl3.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/sslerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/stack.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/store.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/storeerr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/symhacks.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/tls1.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ts.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/tserr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/txt_db.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/ui.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/uierr.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/whrlpool.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/x509.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/x509_vfy.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/x509err.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/x509v3.h create mode 100644 Hin2n/src/main/jniLibs/x86/include/openssl/x509v3err.h create mode 100644 Hin2n/src/main/jniLibs/x86/libcrypto.so create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/aes.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1_mac.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1t.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/async.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/asyncerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/bio.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/bioerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/blowfish.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/bn.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/bnerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/buffer.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/buffererr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/camellia.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cast.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cmac.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cms.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cmserr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/comp.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/comperr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/conf.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/conf_api.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/conferr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/crypto.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cryptoerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ct.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/cterr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/des.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/dh.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/dherr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/dsa.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/dsaerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/dtls1.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/e_os2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ebcdic.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ec.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdh.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdsa.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ecerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/engine.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/engineerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/evp.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/evperr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/hmac.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/idea.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/kdf.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/kdferr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/lhash.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/md2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/md4.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/md5.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/mdc2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/modes.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/obj_mac.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/objects.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/objectserr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsp.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsperr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslconf.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslv.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ossl_typ.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pem.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pem2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pemerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rand.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rand_drbg.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/randerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rc2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rc4.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rc5.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ripemd.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rsa.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/rsaerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/safestack.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/seed.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/sha.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/srp.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/srtp.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl2.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl3.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/sslerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/stack.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/store.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/storeerr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/symhacks.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/tls1.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ts.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/tserr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/txt_db.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/ui.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/uierr.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/whrlpool.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/x509.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/x509_vfy.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/x509err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3err.h create mode 100644 Hin2n/src/main/jniLibs/x86_64/libcrypto.so create mode 100644 bundles/n2n_meyerd/.gitignore create mode 100644 bundles/n2n_meyerd/README create mode 100644 bundles/n2n_meyerd/n2n_v1/COPYING create mode 100644 bundles/n2n_meyerd/n2n_v1/HACKING create mode 100644 bundles/n2n_meyerd/n2n_v1/INSTALL create mode 100644 bundles/n2n_meyerd/n2n_v1/README create mode 100644 bundles/n2n_meyerd/n2n_v1/android/tuntap_android.c create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/README.Debian create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/changelog create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/compat create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/control create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/copyright create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/n2n.dirs create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/n2n.docs create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/n2n.install create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/n2n.manpages create mode 100644 bundles/n2n_meyerd/n2n_v1/debian/rules create mode 100644 bundles/n2n_meyerd/n2n_v1/edge.8 create mode 100644 bundles/n2n_meyerd/n2n_v1/edge.c create mode 100644 bundles/n2n_meyerd/n2n_v1/lzoconf.h create mode 100644 bundles/n2n_meyerd/n2n_v1/lzodefs.h create mode 100644 bundles/n2n_meyerd/n2n_v1/minilzo.c create mode 100644 bundles/n2n_meyerd/n2n_v1/minilzo.h create mode 100644 bundles/n2n_meyerd/n2n_v1/n2n.c create mode 100644 bundles/n2n_meyerd/n2n_v1/n2n.h create mode 100644 bundles/n2n_meyerd/n2n_v1/n2n.spec create mode 100644 bundles/n2n_meyerd/n2n_v1/scripts/mk_SRPM.sh create mode 100644 bundles/n2n_meyerd/n2n_v1/scripts/mk_deb.sh create mode 100644 bundles/n2n_meyerd/n2n_v1/scripts/mk_tar.sh create mode 100644 bundles/n2n_meyerd/n2n_v1/supernode.1 create mode 100644 bundles/n2n_meyerd/n2n_v1/supernode.c create mode 100644 bundles/n2n_meyerd/n2n_v1/tuntap_freebsd.c create mode 100644 bundles/n2n_meyerd/n2n_v1/tuntap_linux.c create mode 100644 bundles/n2n_meyerd/n2n_v1/tuntap_osx.c create mode 100644 bundles/n2n_meyerd/n2n_v1/twofish.c create mode 100644 bundles/n2n_meyerd/n2n_v1/twofish.h create mode 100644 bundles/n2n_meyerd/n2n_v1/version.c create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.sln create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.suo create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.vcproj create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/getopt.c create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/getopt.h create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/getopt1.c create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/n2n_win32.h create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/wintap.c create mode 100644 bundles/n2n_meyerd/n2n_v1/win32/wintap.h create mode 100644 bundles/n2n_meyerd/n2n_v2/CMakeLists.txt create mode 100644 bundles/n2n_meyerd/n2n_v2/COPYING create mode 100644 bundles/n2n_meyerd/n2n_v2/HACKING create mode 100644 bundles/n2n_meyerd/n2n_v2/INSTALL create mode 100644 bundles/n2n_meyerd/n2n_v2/NEW_FEATURES.txt create mode 100644 bundles/n2n_meyerd/n2n_v2/README create mode 100644 bundles/n2n_meyerd/n2n_v2/android/tuntap_android.c create mode 100644 bundles/n2n_meyerd/n2n_v2/benchmark.c create mode 100644 bundles/n2n_meyerd/n2n_v2/benchmark_hashtable.c create mode 100644 bundles/n2n_meyerd/n2n_v2/cmake/CMakeToolchainFileMingw32.cmake create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/README.Debian create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/changelog create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/compat create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/control create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/copyright create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.default create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.docs create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.init create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.install create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.manpages create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.default create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.init create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.install create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.manpages create mode 100644 bundles/n2n_meyerd/n2n_v2/debian/rules create mode 100644 bundles/n2n_meyerd/n2n_v2/edge.8 create mode 100644 bundles/n2n_meyerd/n2n_v2/edge.c create mode 100644 bundles/n2n_meyerd/n2n_v2/gen_keyfile.py create mode 100644 bundles/n2n_meyerd/n2n_v2/lzoconf.h create mode 100644 bundles/n2n_meyerd/n2n_v2/lzodefs.h create mode 100644 bundles/n2n_meyerd/n2n_v2/minilzo.c create mode 100644 bundles/n2n_meyerd/n2n_v2/minilzo.h create mode 100644 bundles/n2n_meyerd/n2n_v2/munin/n2n-supernode create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n.c create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n.h create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n.spec create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_keyfile.c create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_keyfile.h create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_test.c create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_transforms.h create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_v2.7 create mode 100644 bundles/n2n_meyerd/n2n_v2/n2n_wire.h create mode 100644 bundles/n2n_meyerd/n2n_v2/scm.h create mode 100644 bundles/n2n_meyerd/n2n_v2/scripts/mk_SRPM.sh create mode 100644 bundles/n2n_meyerd/n2n_v2/scripts/mk_deb.sh create mode 100644 bundles/n2n_meyerd/n2n_v2/scripts/mk_tar.sh create mode 100644 bundles/n2n_meyerd/n2n_v2/sglib.h create mode 100644 bundles/n2n_meyerd/n2n_v2/sn.c create mode 100644 bundles/n2n_meyerd/n2n_v2/supernode.1 create mode 100644 bundles/n2n_meyerd/n2n_v2/transform_aes.c create mode 100644 bundles/n2n_meyerd/n2n_v2/transform_null.c create mode 100644 bundles/n2n_meyerd/n2n_v2/transform_tf.c create mode 100644 bundles/n2n_meyerd/n2n_v2/tuntap_freebsd.c create mode 100644 bundles/n2n_meyerd/n2n_v2/tuntap_linux.c create mode 100644 bundles/n2n_meyerd/n2n_v2/tuntap_netbsd.c create mode 100644 bundles/n2n_meyerd/n2n_v2/tuntap_osx.c create mode 100644 bundles/n2n_meyerd/n2n_v2/twofish.c create mode 100644 bundles/n2n_meyerd/n2n_v2/twofish.h create mode 100644 bundles/n2n_meyerd/n2n_v2/unix-scm.c create mode 100644 bundles/n2n_meyerd/n2n_v2/version.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/CMakeLists.txt create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.sln create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.suo create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.vcproj create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/DotNet/supernode.vcproj create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/getopt.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/getopt.h create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/getopt1.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.h create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/version-msvc.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/win-scm.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/wintap.c create mode 100644 bundles/n2n_meyerd/n2n_v2/win32/wintap.h create mode 100644 bundles/n2n_meyerd/n2n_v2/wire.c create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/AUTHORS create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/CMakeLists.txt create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/COPYING create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/ChangeLog create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.am create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.common create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.nmake create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.h create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.nmake create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/packet-n2n.c create mode 100644 bundles/n2n_meyerd/n2n_v2/wireshark/plugin.rc.in create mode 100644 bundles/n2n_ntop_v2/.gitignore create mode 100644 bundles/n2n_ntop_v2/CHANGELOG.md create mode 100644 bundles/n2n_ntop_v2/CMakeLists.txt create mode 100644 bundles/n2n_ntop_v2/COPYING create mode 100644 bundles/n2n_ntop_v2/INSTALL create mode 100644 bundles/n2n_ntop_v2/LICENSE create mode 100644 bundles/n2n_ntop_v2/Makefile.in create mode 100644 bundles/n2n_ntop_v2/README.md create mode 100644 bundles/n2n_ntop_v2/autogen.sh create mode 100644 bundles/n2n_ntop_v2/community.list create mode 100644 bundles/n2n_ntop_v2/configure.seed create mode 100644 bundles/n2n_ntop_v2/contributors.txt create mode 100644 bundles/n2n_ntop_v2/doc/Crypto.md create mode 100644 bundles/n2n_ntop_v2/doc/HACKING create mode 100644 bundles/n2n_ntop_v2/doc/IPv6.md create mode 100644 bundles/n2n_ntop_v2/doc/MTU.md create mode 100644 bundles/n2n_ntop_v2/doc/Routing.md create mode 100644 bundles/n2n_ntop_v2/doc/Windows.md create mode 100644 bundles/n2n_ntop_v2/doc/macOS.md create mode 100644 bundles/n2n_ntop_v2/doc/n2n_gateway.sh create mode 100644 bundles/n2n_ntop_v2/doc/new-features.md create mode 100644 bundles/n2n_ntop_v2/doc/rpm-packaging.md create mode 100644 bundles/n2n_ntop_v2/edge.8 create mode 100644 bundles/n2n_ntop_v2/include/edge_utils_win32.h create mode 100644 bundles/n2n_ntop_v2/include/header_encryption.h create mode 100644 bundles/n2n_ntop_v2/include/lzoconf.h create mode 100644 bundles/n2n_ntop_v2/include/lzodefs.h create mode 100644 bundles/n2n_ntop_v2/include/minilzo.h create mode 100644 bundles/n2n_ntop_v2/include/n2n.h create mode 100644 bundles/n2n_ntop_v2/include/n2n_define.h create mode 100644 bundles/n2n_ntop_v2/include/n2n_transforms.h create mode 100644 bundles/n2n_ntop_v2/include/n2n_wire.h create mode 100644 bundles/n2n_ntop_v2/include/pearson.h create mode 100644 bundles/n2n_ntop_v2/include/portable_endian.h create mode 100644 bundles/n2n_ntop_v2/include/random_numbers.h create mode 100644 bundles/n2n_ntop_v2/include/speck.h create mode 100644 bundles/n2n_ntop_v2/include/twofish.h create mode 100644 bundles/n2n_ntop_v2/include/uthash.h create mode 100644 bundles/n2n_ntop_v2/legacy/README.md create mode 100644 bundles/n2n_ntop_v2/legacy/edge_keyschedule.c create mode 100644 bundles/n2n_ntop_v2/legacy/gen_keyfile.py create mode 100644 bundles/n2n_ntop_v2/legacy/n2n_keyfile.c create mode 100644 bundles/n2n_ntop_v2/legacy/n2n_keyfile.h create mode 100644 bundles/n2n_ntop_v2/legacy/transform_aes.c create mode 100644 bundles/n2n_ntop_v2/legacy/transform_tf.c create mode 100644 bundles/n2n_ntop_v2/n2n.7 create mode 100644 bundles/n2n_ntop_v2/packages/centos create mode 100644 bundles/n2n_ntop_v2/packages/debian/Makefile.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/README create mode 100644 bundles/n2n_ntop_v2/packages/debian/configure.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/COPYRIGHT create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/README create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/changelog.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/compat create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/conffiles create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/control.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/dirs create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/docs create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/files.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/n2n.debhelper.log create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/n2n.postrm.debhelper create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/n2n.substvars create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/postinst create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/postrm create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/preinst create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/prerm create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/rules.in create mode 100644 bundles/n2n_ntop_v2/packages/debian/debian/templates create mode 100644 bundles/n2n_ntop_v2/packages/etc/n2n/edge.conf.sample create mode 100644 bundles/n2n_ntop_v2/packages/etc/n2n/supernode.conf.sample create mode 100644 bundles/n2n_ntop_v2/packages/etc/systemd/system/edge-ntopng@.service.in create mode 100644 bundles/n2n_ntop_v2/packages/etc/systemd/system/edge.service.in create mode 100644 bundles/n2n_ntop_v2/packages/etc/systemd/system/edge@.service.in create mode 100644 bundles/n2n_ntop_v2/packages/etc/systemd/system/supernode.service.in create mode 100644 bundles/n2n_ntop_v2/packages/openwrt/README.md create mode 100644 bundles/n2n_ntop_v2/packages/rpm/Makefile.in create mode 100644 bundles/n2n_ntop_v2/packages/rpm/configure.in create mode 100644 bundles/n2n_ntop_v2/packages/rpm/n2n.spec.in create mode 100644 bundles/n2n_ntop_v2/packages/rpm/rpm-sign.exp create mode 100644 bundles/n2n_ntop_v2/packages/ubuntu create mode 100644 bundles/n2n_ntop_v2/src/edge.c create mode 100644 bundles/n2n_ntop_v2/src/edge_utils.c create mode 100644 bundles/n2n_ntop_v2/src/edge_utils_win32.c create mode 100644 bundles/n2n_ntop_v2/src/example_edge_embed.c create mode 100644 bundles/n2n_ntop_v2/src/example_edge_embed_quick_edge_init.c create mode 100644 bundles/n2n_ntop_v2/src/example_sn_embed.c create mode 100644 bundles/n2n_ntop_v2/src/header_encryption.c create mode 100644 bundles/n2n_ntop_v2/src/minilzo.c create mode 100644 bundles/n2n_ntop_v2/src/n2n.c create mode 100644 bundles/n2n_ntop_v2/src/pearson.c create mode 100644 bundles/n2n_ntop_v2/src/random_numbers.c create mode 100644 bundles/n2n_ntop_v2/src/sn.c create mode 100644 bundles/n2n_ntop_v2/src/sn_utils.c create mode 100644 bundles/n2n_ntop_v2/src/speck.c create mode 100644 bundles/n2n_ntop_v2/src/transform_aes.c create mode 100644 bundles/n2n_ntop_v2/src/transform_cc20.c create mode 100644 bundles/n2n_ntop_v2/src/transform_null.c create mode 100644 bundles/n2n_ntop_v2/src/transform_speck.c create mode 100644 bundles/n2n_ntop_v2/src/transform_tf.c create mode 100644 bundles/n2n_ntop_v2/src/tuntap_freebsd.c create mode 100644 bundles/n2n_ntop_v2/src/tuntap_linux.c create mode 100644 bundles/n2n_ntop_v2/src/tuntap_netbsd.c create mode 100644 bundles/n2n_ntop_v2/src/tuntap_osx.c create mode 100644 bundles/n2n_ntop_v2/src/twofish.c create mode 100644 bundles/n2n_ntop_v2/src/wire.c create mode 100644 bundles/n2n_ntop_v2/supernode.1 create mode 100644 bundles/n2n_ntop_v2/tools/Makefile.in create mode 100644 bundles/n2n_ntop_v2/tools/benchmark.c create mode 100644 bundles/n2n_ntop_v2/tools/n2n_decode.c create mode 100644 bundles/n2n_ntop_v2/win32/CMakeLists.txt create mode 100644 bundles/n2n_ntop_v2/win32/DotNet/n2n.sln create mode 100644 bundles/n2n_ntop_v2/win32/DotNet/n2n.suo create mode 100644 bundles/n2n_ntop_v2/win32/DotNet/n2n.vcproj create mode 100644 bundles/n2n_ntop_v2/win32/DotNet/supernode.vcproj create mode 100644 bundles/n2n_ntop_v2/win32/getopt.c create mode 100644 bundles/n2n_ntop_v2/win32/getopt.h create mode 100644 bundles/n2n_ntop_v2/win32/getopt1.c create mode 100644 bundles/n2n_ntop_v2/win32/n2n_win32.h create mode 100644 bundles/n2n_ntop_v2/win32/version-msvc.c create mode 100644 bundles/n2n_ntop_v2/win32/winconfig.h create mode 100644 bundles/n2n_ntop_v2/win32/wintap.c create mode 100644 bundles/n2n_ntop_v2/win32/wintap.h create mode 100644 bundles/n2n_ntop_v2/wireshark/README.md create mode 100644 bundles/n2n_ntop_v2/wireshark/n2n.lua create mode 100644 bundles/n2n_ntop_v3/.ci/build-project.ps1 create mode 100644 bundles/n2n_ntop_v3/.ci/install-vcpkg.ps1 create mode 100644 bundles/n2n_ntop_v3/.github/workflows/cmake-linux.yml create mode 100644 bundles/n2n_ntop_v3/.github/workflows/tests.yml create mode 100644 bundles/n2n_ntop_v3/.gitignore create mode 100644 bundles/n2n_ntop_v3/.travis.yml create mode 100644 bundles/n2n_ntop_v3/.yamllint.yml create mode 100644 bundles/n2n_ntop_v3/CHANGELOG.md create mode 100644 bundles/n2n_ntop_v3/CMakeLists.txt create mode 100644 bundles/n2n_ntop_v3/COPYING create mode 100644 bundles/n2n_ntop_v3/INSTALL create mode 100644 bundles/n2n_ntop_v3/LICENSE create mode 100644 bundles/n2n_ntop_v3/Makefile.in create mode 100644 bundles/n2n_ntop_v3/README.md create mode 100644 bundles/n2n_ntop_v3/autogen.sh create mode 100644 bundles/n2n_ntop_v3/community.list create mode 100644 bundles/n2n_ntop_v3/configure.seed create mode 100644 bundles/n2n_ntop_v3/contributors.txt create mode 100644 bundles/n2n_ntop_v3/doc/Advanced.md create mode 100644 bundles/n2n_ntop_v3/doc/Authentication.md create mode 100644 bundles/n2n_ntop_v3/doc/Building.md create mode 100644 bundles/n2n_ntop_v3/doc/Communities.md create mode 100644 bundles/n2n_ntop_v3/doc/ConfigurationFiles.md create mode 100644 bundles/n2n_ntop_v3/doc/Crypto.md create mode 100644 bundles/n2n_ntop_v3/doc/Faq.md create mode 100644 bundles/n2n_ntop_v3/doc/Federation.md create mode 100644 bundles/n2n_ntop_v3/doc/Hacking.md create mode 100644 bundles/n2n_ntop_v3/doc/ManagementAPI.md create mode 100644 bundles/n2n_ntop_v3/doc/Routing.md create mode 100644 bundles/n2n_ntop_v3/doc/Scratchpad.md create mode 100644 bundles/n2n_ntop_v3/doc/Scripts.md create mode 100644 bundles/n2n_ntop_v3/doc/TapConfiguration.md create mode 100644 bundles/n2n_ntop_v3/doc/TrafficRestrictions.md create mode 100644 bundles/n2n_ntop_v3/edge.8 create mode 100644 bundles/n2n_ntop_v3/include/aes.h create mode 100644 bundles/n2n_ntop_v3/include/auth.h create mode 100644 bundles/n2n_ntop_v3/include/cc20.h create mode 100644 bundles/n2n_ntop_v3/include/curve25519.h create mode 100644 bundles/n2n_ntop_v3/include/edge_utils_win32.h create mode 100644 bundles/n2n_ntop_v3/include/header_encryption.h create mode 100644 bundles/n2n_ntop_v3/include/hexdump.h create mode 100644 bundles/n2n_ntop_v3/include/lzoconf.h create mode 100644 bundles/n2n_ntop_v3/include/lzodefs.h create mode 100644 bundles/n2n_ntop_v3/include/minilzo.h create mode 100644 bundles/n2n_ntop_v3/include/n2n.h create mode 100644 bundles/n2n_ntop_v3/include/n2n_define.h create mode 100644 bundles/n2n_ntop_v3/include/n2n_regex.h create mode 100644 bundles/n2n_ntop_v3/include/n2n_typedefs.h create mode 100644 bundles/n2n_ntop_v3/include/n2n_wire.h create mode 100644 bundles/n2n_ntop_v3/include/network_traffic_filter.h create mode 100644 bundles/n2n_ntop_v3/include/pearson.h create mode 100644 bundles/n2n_ntop_v3/include/portable_endian.h create mode 100644 bundles/n2n_ntop_v3/include/random_numbers.h create mode 100644 bundles/n2n_ntop_v3/include/sn_selection.h create mode 100644 bundles/n2n_ntop_v3/include/speck.h create mode 100644 bundles/n2n_ntop_v3/include/tf.h create mode 100644 bundles/n2n_ntop_v3/include/uthash.h create mode 100644 bundles/n2n_ntop_v3/legacy/README.md create mode 100644 bundles/n2n_ntop_v3/legacy/edge_keyschedule.c create mode 100644 bundles/n2n_ntop_v3/legacy/gen_keyfile.py create mode 100644 bundles/n2n_ntop_v3/legacy/n2n_keyfile.c create mode 100644 bundles/n2n_ntop_v3/legacy/n2n_keyfile.h create mode 100644 bundles/n2n_ntop_v3/legacy/transform_aes.c create mode 100644 bundles/n2n_ntop_v3/legacy/transform_tf.c create mode 100644 bundles/n2n_ntop_v3/n2n.7 create mode 100644 bundles/n2n_ntop_v3/packages/centos create mode 100644 bundles/n2n_ntop_v3/packages/debian/Makefile.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/README create mode 100644 bundles/n2n_ntop_v3/packages/debian/configure.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/COPYRIGHT create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/README create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/changelog.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/compat create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/conffiles create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/control.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/dirs create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/docs create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/files.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/n2n.substvars create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/postinst create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/postrm create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/preinst create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/prerm create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/rules.in create mode 100644 bundles/n2n_ntop_v3/packages/debian/debian/templates create mode 100644 bundles/n2n_ntop_v3/packages/etc/n2n/edge.conf.sample create mode 100644 bundles/n2n_ntop_v3/packages/etc/n2n/supernode.conf.sample create mode 100644 bundles/n2n_ntop_v3/packages/etc/systemd/system/edge-ntopng@.service.in create mode 100644 bundles/n2n_ntop_v3/packages/etc/systemd/system/edge.service.in create mode 100644 bundles/n2n_ntop_v3/packages/etc/systemd/system/edge@.service.in create mode 100644 bundles/n2n_ntop_v3/packages/etc/systemd/system/supernode.service.in create mode 100644 bundles/n2n_ntop_v3/packages/openwrt/Makefile create mode 100644 bundles/n2n_ntop_v3/packages/openwrt/README.md create mode 100644 bundles/n2n_ntop_v3/packages/openwrt/patches/001-fix-cc.patch create mode 100644 bundles/n2n_ntop_v3/packages/rpm/Makefile.in create mode 100644 bundles/n2n_ntop_v3/packages/rpm/configure.in create mode 100644 bundles/n2n_ntop_v3/packages/rpm/n2n.spec.in create mode 100644 bundles/n2n_ntop_v3/packages/rpm/rpm-sign.exp create mode 100644 bundles/n2n_ntop_v3/packages/ubuntu create mode 100644 bundles/n2n_ntop_v3/scripts/README.md create mode 100644 bundles/n2n_ntop_v3/scripts/hack_fakeautoconf.sh create mode 100644 bundles/n2n_ntop_v3/scripts/indent.sh create mode 100644 bundles/n2n_ntop_v3/scripts/n2n-ctl create mode 100644 bundles/n2n_ntop_v3/scripts/n2n-gateway.sh create mode 100644 bundles/n2n_ntop_v3/scripts/n2n-httpd create mode 100644 bundles/n2n_ntop_v3/scripts/test_harness.sh create mode 100644 bundles/n2n_ntop_v3/src/aes.c create mode 100644 bundles/n2n_ntop_v3/src/auth.c create mode 100644 bundles/n2n_ntop_v3/src/cc20.c create mode 100644 bundles/n2n_ntop_v3/src/curve25519.c create mode 100644 bundles/n2n_ntop_v3/src/edge.c create mode 100644 bundles/n2n_ntop_v3/src/edge_management.c create mode 100644 bundles/n2n_ntop_v3/src/edge_utils.c create mode 100644 bundles/n2n_ntop_v3/src/edge_utils_win32.c create mode 100644 bundles/n2n_ntop_v3/src/example_edge_embed.c create mode 100644 bundles/n2n_ntop_v3/src/example_edge_embed_quick_edge_init.c create mode 100644 bundles/n2n_ntop_v3/src/example_sn_embed.c create mode 100644 bundles/n2n_ntop_v3/src/header_encryption.c create mode 100644 bundles/n2n_ntop_v3/src/hexdump.c create mode 100644 bundles/n2n_ntop_v3/src/minilzo.c create mode 100644 bundles/n2n_ntop_v3/src/n2n.c create mode 100644 bundles/n2n_ntop_v3/src/n2n_regex.c create mode 100644 bundles/n2n_ntop_v3/src/network_traffic_filter.c create mode 100644 bundles/n2n_ntop_v3/src/pearson.c create mode 100644 bundles/n2n_ntop_v3/src/random_numbers.c create mode 100644 bundles/n2n_ntop_v3/src/sn_management.c create mode 100644 bundles/n2n_ntop_v3/src/sn_selection.c create mode 100644 bundles/n2n_ntop_v3/src/sn_utils.c create mode 100644 bundles/n2n_ntop_v3/src/speck.c create mode 100644 bundles/n2n_ntop_v3/src/supernode.c create mode 100644 bundles/n2n_ntop_v3/src/tf.c create mode 100644 bundles/n2n_ntop_v3/src/transform_aes.c create mode 100644 bundles/n2n_ntop_v3/src/transform_cc20.c create mode 100644 bundles/n2n_ntop_v3/src/transform_null.c create mode 100644 bundles/n2n_ntop_v3/src/transform_speck.c create mode 100644 bundles/n2n_ntop_v3/src/transform_tf.c create mode 100644 bundles/n2n_ntop_v3/src/tuntap_freebsd.c create mode 100644 bundles/n2n_ntop_v3/src/tuntap_linux.c create mode 100644 bundles/n2n_ntop_v3/src/tuntap_netbsd.c create mode 100644 bundles/n2n_ntop_v3/src/tuntap_osx.c create mode 100644 bundles/n2n_ntop_v3/src/wire.c create mode 100644 bundles/n2n_ntop_v3/supernode.1 create mode 100644 bundles/n2n_ntop_v3/tests/tests-compress.expected create mode 100644 bundles/n2n_ntop_v3/tests/tests-elliptic.expected create mode 100644 bundles/n2n_ntop_v3/tests/tests-hashing.expected create mode 100644 bundles/n2n_ntop_v3/tests/tests-transform.expected create mode 100644 bundles/n2n_ntop_v3/tests/tests-wire.expected create mode 100644 bundles/n2n_ntop_v3/tools/Makefile.in create mode 100644 bundles/n2n_ntop_v3/tools/n2n-benchmark.c create mode 100644 bundles/n2n_ntop_v3/tools/n2n-decode.c create mode 100644 bundles/n2n_ntop_v3/tools/n2n-keygen.c create mode 100644 bundles/n2n_ntop_v3/tools/tests-compress.c create mode 100644 bundles/n2n_ntop_v3/tools/tests-elliptic.c create mode 100644 bundles/n2n_ntop_v3/tools/tests-hashing.c create mode 100644 bundles/n2n_ntop_v3/tools/tests-transform.c create mode 100644 bundles/n2n_ntop_v3/tools/tests-wire.c create mode 100644 bundles/n2n_ntop_v3/uncrustify.cfg create mode 100644 bundles/n2n_ntop_v3/win32/CMakeLists.txt create mode 100644 bundles/n2n_ntop_v3/win32/DotNet/n2n.sln create mode 100644 bundles/n2n_ntop_v3/win32/DotNet/n2n.suo create mode 100644 bundles/n2n_ntop_v3/win32/DotNet/n2n.vcproj create mode 100644 bundles/n2n_ntop_v3/win32/DotNet/supernode.vcproj create mode 100644 bundles/n2n_ntop_v3/win32/Makefile create mode 100644 bundles/n2n_ntop_v3/win32/getopt.c create mode 100644 bundles/n2n_ntop_v3/win32/getopt.h create mode 100644 bundles/n2n_ntop_v3/win32/getopt1.c create mode 100644 bundles/n2n_ntop_v3/win32/n2n_win32.h create mode 100644 bundles/n2n_ntop_v3/win32/version-msvc.c create mode 100644 bundles/n2n_ntop_v3/win32/winconfig.h create mode 100644 bundles/n2n_ntop_v3/win32/wintap.c create mode 100644 bundles/n2n_ntop_v3/win32/wintap.h create mode 100644 bundles/n2n_ntop_v3/wireshark/README.md create mode 100644 bundles/n2n_ntop_v3/wireshark/n2n.lua create mode 100644 bundles/slog/slog.c create mode 100644 bundles/slog/slog.h create mode 100644 bundles/tun2tap/tun2tap.c create mode 100644 bundles/tun2tap/tun2tap.h create mode 100644 bundles/tun2tap/tun2tap_appdef.h create mode 100644 bundles/tun2tap/uip-conf.h create mode 100644 bundles/uip/README create mode 100644 bundles/uip/apps/README create mode 100644 bundles/uip/apps/dhcpc/Makefile.dhcpc create mode 100644 bundles/uip/apps/dhcpc/dhcpc.c create mode 100644 bundles/uip/apps/dhcpc/dhcpc.h create mode 100644 bundles/uip/apps/hello-world/Makefile.hello-world create mode 100644 bundles/uip/apps/hello-world/hello-world.c create mode 100644 bundles/uip/apps/hello-world/hello-world.h create mode 100644 bundles/uip/apps/resolv/Makefile.resolv create mode 100644 bundles/uip/apps/resolv/resolv.c create mode 100644 bundles/uip/apps/resolv/resolv.h create mode 100644 bundles/uip/apps/smtp/Makefile.smtp create mode 100644 bundles/uip/apps/smtp/makestrings create mode 100644 bundles/uip/apps/smtp/smtp-strings create mode 100644 bundles/uip/apps/smtp/smtp-strings.c create mode 100644 bundles/uip/apps/smtp/smtp-strings.h create mode 100644 bundles/uip/apps/smtp/smtp.c create mode 100644 bundles/uip/apps/smtp/smtp.h create mode 100644 bundles/uip/apps/telnetd/Makefile.telnetd create mode 100644 bundles/uip/apps/telnetd/shell.c create mode 100644 bundles/uip/apps/telnetd/shell.h create mode 100644 bundles/uip/apps/telnetd/telnetd.c create mode 100644 bundles/uip/apps/telnetd/telnetd.h create mode 100644 bundles/uip/apps/webclient/Makefile.webclient create mode 100644 bundles/uip/apps/webclient/makestrings create mode 100644 bundles/uip/apps/webclient/webclient-strings create mode 100644 bundles/uip/apps/webclient/webclient-strings.c create mode 100644 bundles/uip/apps/webclient/webclient-strings.h create mode 100644 bundles/uip/apps/webclient/webclient.c create mode 100644 bundles/uip/apps/webclient/webclient.h create mode 100644 bundles/uip/apps/webserver/Makefile.webserver create mode 100644 bundles/uip/apps/webserver/http-strings create mode 100644 bundles/uip/apps/webserver/http-strings.c create mode 100644 bundles/uip/apps/webserver/http-strings.h create mode 100644 bundles/uip/apps/webserver/httpd-cgi.c create mode 100644 bundles/uip/apps/webserver/httpd-cgi.h create mode 100644 bundles/uip/apps/webserver/httpd-fs.c create mode 100644 bundles/uip/apps/webserver/httpd-fs.h create mode 100644 bundles/uip/apps/webserver/httpd-fs/404.html create mode 100644 bundles/uip/apps/webserver/httpd-fs/fade.png create mode 100644 bundles/uip/apps/webserver/httpd-fs/files.shtml create mode 100644 bundles/uip/apps/webserver/httpd-fs/footer.html create mode 100644 bundles/uip/apps/webserver/httpd-fs/header.html create mode 100644 bundles/uip/apps/webserver/httpd-fs/index.html create mode 100644 bundles/uip/apps/webserver/httpd-fs/processes.shtml create mode 100644 bundles/uip/apps/webserver/httpd-fs/stats.shtml create mode 100644 bundles/uip/apps/webserver/httpd-fs/style.css create mode 100644 bundles/uip/apps/webserver/httpd-fs/tcp.shtml create mode 100644 bundles/uip/apps/webserver/httpd-fsdata.c create mode 100644 bundles/uip/apps/webserver/httpd-fsdata.h create mode 100644 bundles/uip/apps/webserver/httpd.c create mode 100644 bundles/uip/apps/webserver/httpd.h create mode 100644 bundles/uip/apps/webserver/makefsdata create mode 100644 bundles/uip/apps/webserver/makestrings create mode 100644 bundles/uip/apps/webserver/webserver.h create mode 100644 bundles/uip/lib/memb.c create mode 100644 bundles/uip/lib/memb.h create mode 100644 bundles/uip/uip-1.0-changelog.txt create mode 100644 bundles/uip/uip/Makefile.include create mode 100644 bundles/uip/uip/clock.h create mode 100644 bundles/uip/uip/lc-addrlabels.h create mode 100644 bundles/uip/uip/lc-switch.h create mode 100644 bundles/uip/uip/lc.h create mode 100644 bundles/uip/uip/psock.c create mode 100644 bundles/uip/uip/psock.h create mode 100644 bundles/uip/uip/pt.h create mode 100644 bundles/uip/uip/timer.c create mode 100644 bundles/uip/uip/timer.h create mode 100644 bundles/uip/uip/uip-fw.c create mode 100644 bundles/uip/uip/uip-fw.h create mode 100644 bundles/uip/uip/uip-neighbor.c create mode 100644 bundles/uip/uip/uip-neighbor.h create mode 100644 bundles/uip/uip/uip-split.c create mode 100644 bundles/uip/uip/uip-split.h create mode 100644 bundles/uip/uip/uip.c create mode 100644 bundles/uip/uip/uip.h create mode 100644 bundles/uip/uip/uip_arch.h create mode 100644 bundles/uip/uip/uip_arp.c create mode 100644 bundles/uip/uip/uip_arp.h create mode 100644 bundles/uip/uip/uiplib.c create mode 100644 bundles/uip/uip/uiplib.h create mode 100644 bundles/uip/uip/uipopt.h create mode 100644 bundles/uip/unix/Makefile create mode 100644 bundles/uip/unix/clock-arch.c create mode 100644 bundles/uip/unix/clock-arch.h create mode 100644 bundles/uip/unix/main.c create mode 100644 bundles/uip/unix/tapdev.c create mode 100644 bundles/uip/unix/tapdev.h create mode 100644 bundles/uip/unix/uip-conf.h create mode 100644 link.bat create mode 120000 n2n_v1 create mode 120000 n2n_v2 create mode 120000 n2n_v2s create mode 120000 n2n_v3 create mode 120000 slog create mode 120000 tun2tap create mode 120000 uip diff --git a/Hin2n/CMakeLists.txt b/Hin2n/CMakeLists.txt new file mode 100644 index 00000000..c193ab46 --- /dev/null +++ b/Hin2n/CMakeLists.txt @@ -0,0 +1,153 @@ +project(Hin2n) +cmake_minimum_required(VERSION 3.4.1) + +# N2n information +set(N2N_VERSION 2.9.0) +set(N2N_OSNAME ${CMAKE_SYSTEM}) +set(N2N_MODIFY_VERSION v2s_0.1.0) +set(N2N_MODIFY_AUTHOR "switchwang(https://github.com/switch-st) zhangbz(https://github.com/zhangbz)") +add_definitions(-DCMAKE_BUILD) + +INCLUDE(TestBigEndian) +TEST_BIG_ENDIAN(UIP_CONF_BYTE_ORDER) +if(${UIP_CONF_BYTE_ORDER} EQUAL 1) +set(UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN) +else(${UIP_CONF_BYTE_ORDER} EQUAL 1) +set(UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN) +endif(${UIP_CONF_BYTE_ORDER} EQUAL 1) + +# OpenSSL +SET(OPENSSL_ROOT_DIR src/main/jniLibs/${ANDROID_ABI}) +SET(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}") +SET(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include) +SET(OPENSSL_LIBRARIES "crypto") +LINK_DIRECTORIES(${OPENSSL_LIBRARIES_DIR}) +OPTION(N2N_OPTION_AES "USE AES" ON) +set(N2N_OPTION_AES ON) + +if(CMAKE_BUILD_TYPE) +if(NOT ${CMAKE_BUILD_TYPE} STREQUAL Debug) +set(CMAKE_BUILD_TYPE Release) +endif(NOT ${CMAKE_BUILD_TYPE} STREQUAL Debug) +else(CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE Release) +endif(CMAKE_BUILD_TYPE) +add_definitions(-DCMAKE_BUILD) + +add_definitions(-DN2N_VERSION=\"${N2N_VERSION}\" -DN2N_OSNAME=\"${N2N_OSNAME}\" -DN2N_MODIFY_VERSION=\"${N2N_MODIFY_VERSION}\" -DN2N_MODIFY_AUTHOR=\"${N2N_MODIFY_AUTHOR}\" -DUIP_CONF_BYTE_ORDER=\"${UIP_CONF_BYTE_ORDER}\") +add_definitions(-DGIT_RELEASE="" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${CMAKE_SYSTEM}") +include_directories(src/main/cpp src/main/cpp/edge_jni src/main/cpp/slog src/main/cpp/tun2tap src/main/cpp/uip) + +add_library(edge_jni SHARED src/main/cpp/edge_jni/edge_jni.c) +target_link_libraries(edge_jni edge_v3) +target_link_libraries(edge_jni edge_v2s) +target_link_libraries(edge_jni edge_v2) +target_link_libraries(edge_jni edge_v1) +target_link_libraries(edge_jni slog) +target_link_libraries(edge_jni ${OPENSSL_LIBRARIES}) + +add_library(edge_v2s SHARED src/main/cpp/n2n_v2s/edge.c) +target_link_libraries(edge_v2s n2n_v2s) +target_link_libraries(edge_v2s slog) + +# -- ntop n2n +add_library(edge_v2 SHARED + src/main/cpp/n2n_v2/src/n2n.c + src/main/cpp/n2n_v2/src/edge_utils.c + src/main/cpp/n2n_v2/src/wire.c + src/main/cpp/n2n_v2/src/minilzo.c + src/main/cpp/n2n_v2/src/twofish.c + src/main/cpp/n2n_v2/src/speck.c + src/main/cpp/n2n_v2/src/pearson.c + src/main/cpp/n2n_v2/src/header_encryption.c + src/main/cpp/n2n_v2/src/transform_null.c + src/main/cpp/n2n_v2/src/transform_tf.c + src/main/cpp/n2n_v2/src/transform_aes.c + src/main/cpp/n2n_v2/src/transform_speck.c + src/main/cpp/n2n_v2/src/transform_cc20.c + src/main/cpp/n2n_v2/src/random_numbers.c + + src/main/cpp/edge_jni/tuntap_android_v2.c + src/main/cpp/edge_jni/edge_android_v2.c + ) +target_compile_definitions(edge_v2 PUBLIC N2N_HAVE_AES HAVE_OPENSSL_1_1) +target_include_directories(edge_v2 PUBLIC + src/main/cpp/n2n_v2/include + ${OPENSSL_INCLUDE_DIR} + ) +target_link_libraries(edge_v2 uip) +target_link_libraries(edge_v2 ${OPENSSL_LIBRARIES}) + +add_library(edge_v3 SHARED + src/main/cpp/n2n_v3/src/n2n.c + src/main/cpp/n2n_v3/src/edge_management.c + src/main/cpp/n2n_v3/src/curve25519.c + src/main/cpp/n2n_v3/src/auth.c + src/main/cpp/n2n_v3/src/edge_utils.c + src/main/cpp/n2n_v3/src/wire.c + src/main/cpp/n2n_v3/src/minilzo.c + src/main/cpp/n2n_v3/src/speck.c + src/main/cpp/n2n_v3/src/pearson.c + src/main/cpp/n2n_v3/src/tf.c + src/main/cpp/n2n_v3/src/header_encryption.c + src/main/cpp/n2n_v3/src/transform_null.c + src/main/cpp/n2n_v3/src/transform_tf.c + src/main/cpp/n2n_v3/src/transform_aes.c + src/main/cpp/n2n_v3/src/transform_speck.c + src/main/cpp/n2n_v3/src/transform_cc20.c + src/main/cpp/n2n_v3/src/cc20.c + src/main/cpp/n2n_v3/src/aes.c + src/main/cpp/n2n_v3/src/network_traffic_filter.c + src/main/cpp/n2n_v3/src/sn_selection.c + src/main/cpp/n2n_v3/src/random_numbers.c + src/main/cpp/edge_jni/tuntap_android_v2.c + src/main/cpp/edge_jni/edge_android_v2.c + ) +target_compile_definitions(edge_v3 PUBLIC N2N_HAVE_AES HAVE_OPENSSL_1_1) +target_compile_options(edge_v3 PRIVATE -DN2N_V3) +target_include_directories(edge_v3 PUBLIC + src/main/cpp/n2n_v3/include + ${OPENSSL_INCLUDE_DIR} + ) +target_link_libraries(edge_v3 uip) +target_link_libraries(edge_v3 ${OPENSSL_LIBRARIES}) + +add_library(edge_v1 SHARED + src/main/cpp/n2n_v1/edge.c + ) +target_link_libraries(edge_v1 n2n_v1) +target_link_libraries(edge_v1 slog) + +add_library(n2n_v2s SHARED + src/main/cpp/n2n_v2s/n2n.c + src/main/cpp/n2n_v2s/n2n_keyfile.c + src/main/cpp/n2n_v2s/wire.c + src/main/cpp/n2n_v2s/minilzo.c + src/main/cpp/n2n_v2s/twofish.c + src/main/cpp/n2n_v2s/transform_null.c + src/main/cpp/n2n_v2s/transform_tf.c + src/main/cpp/n2n_v2s/transform_aes.c + src/main/cpp/n2n_v2s/android/tuntap_android.c + src/main/cpp/n2n_v2s/version.c + ) +target_link_libraries(n2n_v2s uip) +target_link_libraries(n2n_v2s slog) + +add_library(n2n_v1 SHARED + src/main/cpp/n2n_v1/n2n.c + src/main/cpp/n2n_v1/minilzo.c + src/main/cpp/n2n_v1/twofish.c + src/main/cpp/n2n_v1/android/tuntap_android.c + src/main/cpp/n2n_v1/version.c + ) +target_link_libraries(n2n_v1 uip) +target_link_libraries(n2n_v1 slog) + +add_library(uip SHARED + src/main/cpp/uip/uip.c + src/main/cpp/uip/uip_arp.c + src/main/cpp/tun2tap/tun2tap.c + ) + +add_library(slog SHARED src/main/cpp/slog/slog.c) +target_link_libraries(slog log) diff --git a/Hin2n/build.gradle b/Hin2n/build.gradle index 78cbc93a..9d72d2fc 100644 --- a/Hin2n/build.gradle +++ b/Hin2n/build.gradle @@ -11,6 +11,12 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" + externalNativeBuild { + cmake { + cppFlags "" + cFlags "-D__ANDROID_NDK__" + } + } } buildTypes { @@ -23,6 +29,11 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } + } } dependencies { diff --git a/Hin2n/src/main/cpp/edge_jni/edge_android_v2.c b/Hin2n/src/main/cpp/edge_jni/edge_android_v2.c new file mode 100644 index 00000000..d052b4a5 --- /dev/null +++ b/Hin2n/src/main/cpp/edge_jni/edge_android_v2.c @@ -0,0 +1,1124 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#include +#include +#include + +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ +#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ +#define N2N_IF_MODE_SIZE 16 /* static | dhcp */ +#define ARP_PERIOD_INTERVAL 10 /* sec */ + +/* Shared status. Must call pthread_mutex_lock before use. */ +n2n_edge_status_t *g_status; + +#ifndef N2N_V3 +static n2n_mac_t broadcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +static n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0}; +#endif + +/* ***************************************************** */ + +/* Private status. Can be accessed without lock. */ +typedef struct { + uint32_t gateway_ip; + n2n_mac_t gateway_mac; + n2n_edge_conf_t *conf; + uint8_t tap_mac[6]; + uint32_t tap_ipaddr; + time_t lastArpPeriod; +} n2n_android_t; + +/* ***************************************************** */ + +static char arp_packet[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* Ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* Hw Size */ + 0x04, /* Protocol Size */ + 0x00, 0x01, /* ARP Request */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x00, 0x00, 0x00, 0x00, /* Src IP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ + 0x00, 0x00, 0x00, 0x00 /* Target IP */ +}; + +/* ************************************** */ + +static int build_unicast_arp(char *buffer, size_t buffer_len, + uint32_t target, n2n_android_t *priv) { + if (buffer_len < sizeof(arp_packet)) return (-1); + + memcpy(buffer, arp_packet, sizeof(arp_packet)); + memcpy(&buffer[6], priv->tap_mac, 6); + memcpy(&buffer[22], priv->tap_mac, 6); + memcpy(&buffer[28], &priv->tap_ipaddr, 4); + memcpy(&buffer[32], broadcast_mac, 6); + memcpy(&buffer[38], &target, 4); + return (sizeof(arp_packet)); +} + +/* ***************************************************** */ + +/** Find the address and IP mode for the tuntap device. + * + * s is one of these forms: + * + * := | A.B.C.D + * + * | static: | dhcp: + * + * If the mode is present (colon required) then fill ip_mode with that value + * otherwise do not change ip_mode. Fill ip_mode with everything after the + * colon if it is present; or s if colon is not present. + * + * ip_add and ip_mode are NULL terminated if modified. + * + * return 0 on success and -1 on error + */ +static int scan_address(char *ip_addr, size_t addr_size, + char *ip_mode, size_t mode_size, + const char *s) { + int retval = -1; + char *p; + + if ((NULL == s) || (NULL == ip_addr)) { + return -1; + } + + memset(ip_addr, 0, addr_size); + + p = strpbrk(s, ":"); + + if (p) { + /* colon is present */ + if (ip_mode) { + size_t end = 0; + + memset(ip_mode, 0, mode_size); + end = MIN(p - s, (ssize_t) (mode_size - 1)); /* ensure NULL term */ + strncpy(ip_mode, s, end); + strncpy(ip_addr, p + 1, addr_size - 1); /* ensure NULL term */ + retval = 0; + } + } else { + /* colon is not present */ + strncpy(ip_addr, s, addr_size); + } + + return retval; +} + +/* *************************************************** */ + +static const char *random_device_mac(void) { + const char key[] = "0123456789abcdef"; + static char mac[18]; + int i; + + srand(getpid()); + for (i = 0; i < sizeof(mac) - 1; ++i) { + if ((i + 1) % 3 == 0) { + mac[i] = ':'; + continue; + } + mac[i] = key[random() % sizeof(key)]; + } + mac[sizeof(mac) - 1] = '\0'; + return mac; +} + +/* *************************************************** */ + +static int protect_socket(int sock) { + JNIEnv *env = NULL; + + if (!sock) + return (-1); + + if (!g_status) + return (-1); + + if ((*g_status->jvm)->GetEnv(g_status->jvm, (void **) &env, JNI_VERSION_1_1) != JNI_OK || + !env) { + traceEvent(TRACE_ERROR, "GetEnv failed"); + return (-1); + } + + jclass vpn_service_cls = (*env)->GetObjectClass(env, g_status->jobj_service); + + if (!vpn_service_cls) { + traceEvent(TRACE_ERROR, "GetObjectClass(VpnService) failed"); + return (-1); + } + + /* Call VpnService protect */ + jmethodID midProtect = (*env)->GetMethodID(env, vpn_service_cls, "protect", "(I)Z"); + if (!midProtect) { + traceEvent(TRACE_ERROR, "Could not resolve VpnService::protect"); + return (-1); + } + + jboolean isProtected = (*env)->CallBooleanMethod(env, g_status->jobj_service, midProtect, sock); + + if (!isProtected) { + traceEvent(TRACE_ERROR, "VpnService::protect failed"); + return (-1); + } + + return (0); +} + +/* *************************************************** */ + +/** Called periodically to update the gateway MAC address. The ARP reply packet + is handled in handle_PACKET . */ +static void update_gateway_mac(n2n_edge_t *eee) { + n2n_android_t *priv = (n2n_android_t *) edge_get_userdata(eee); + + if (priv->gateway_ip != 0) { + size_t len; + char buffer[48]; + + len = build_unicast_arp(buffer, sizeof(buffer), priv->gateway_ip, priv); + traceEvent(TRACE_DEBUG, "Updating gateway mac"); + edge_send_packet2net(eee, (uint8_t *) buffer, len); + } +} + +int getIpAddrPrefixLength(char *ipaddrStr) { + unsigned int a[4] = {0}; + unsigned int total = 0; + int ret = 0; + + sscanf(ipaddrStr, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]); + total = (a[0] << 24) + (a[1] << 16) + (a[2] << 8) + a[3]; + + int i, j; + for (i = 0, j = 0; i < 32; i++) { + unsigned char tmp = total % 2; + if (tmp == 1) { + j = 1; + ret += 1; + } else { // tmp == 0 + if (j == 1) + return -1; + } + total /= 2; + } + + return ret; +} + +int establishVpnService(n2n_edge_cmd_t *cmd, char ipStr[], int netmask) { + JNIEnv *env = NULL; + + if (!g_status) + return (-1); + + if ((*g_status->jvm)->GetEnv(g_status->jvm, (void **) &env, JNI_VERSION_1_1) != JNI_OK || + !env) { + traceEvent(TRACE_ERROR, "GetEnv failed"); + return (-1); + } + + jclass vpn_service_cls = (*env)->GetObjectClass(env, g_status->jobj_service); + if (!vpn_service_cls) { + traceEvent(TRACE_ERROR, "GetObjectClass(VpnService) failed"); + return (-1); + } + + /* Call VpnService protect */ + jmethodID midEstablishVpnService = (*env)->GetMethodID(env, vpn_service_cls, "EstablishVpnService", "(Ljava/lang/String;I)I"); + if (!midEstablishVpnService) { + traceEvent(TRACE_ERROR, "Could not resolve VpnService::EstablishVpnService"); + return (-1); + } + + jstring jIpStr = (*env)->NewStringUTF(env, ipStr); +#if 0 + if(!jIpStr) { + traceEvent(TRACE_ERROR, "Failed to create newStringUTF."); + return -1; + } +#endif + + int vpn_fd = (*env)->CallIntMethod(env, g_status->jobj_service, midEstablishVpnService, jIpStr, netmask); + if (vpn_fd < 0) { + traceEvent(TRACE_ERROR, "VpnService::EstablishVpnService failed"); + return (-1); + } + + return vpn_fd; +} + +/* *************************************************** */ + +static void on_sn_registration_updated(n2n_edge_t *eee, time_t now, const n2n_sock_t *sn) { + int change = 0; + + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1; + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + + if (change) + g_status->report_edge_status(); + + update_gateway_mac(eee); +} + +/* *************************************************** */ + +static n2n_verdict on_packet_from_peer(n2n_edge_t *eee, const n2n_sock_t *peer, + uint8_t *payload, uint16_t *payload_size) { + n2n_android_t *priv = (n2n_android_t *) edge_get_userdata(eee); + + if ((*payload_size >= 36) && + (ntohs(*((uint16_t *) &payload[12])) == 0x0806) && /* ARP */ + (ntohs(*((uint16_t *) &payload[20])) == 0x0002) && /* REPLY */ + (!memcmp(&payload[28], &priv->gateway_ip, 4))) { /* From gateway */ + memcpy(priv->gateway_mac, &payload[22], 6); + + traceEvent(TRACE_INFO, "Gateway MAC: %02X:%02X:%02X:%02X:%02X:%02X", + priv->gateway_mac[0], priv->gateway_mac[1], priv->gateway_mac[2], + priv->gateway_mac[3], priv->gateway_mac[4], priv->gateway_mac[5]); + } + + uip_buf = payload; + uip_len = *payload_size; + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if (uip_len > 0) { + traceEvent(TRACE_DEBUG, "ARP reply packet prepare to send"); + edge_send_packet2net(eee, uip_buf, uip_len); + return N2N_DROP; + } + } + + return (N2N_ACCEPT); +} + +/* *************************************************** */ + +static n2n_verdict on_packet_from_tap(n2n_edge_t *eee, uint8_t *payload, + uint16_t *payload_size) { + n2n_android_t *priv = (n2n_android_t *) edge_get_userdata(eee); + + /* Fill destination mac address first or generate arp request packet instead of + * normal packet. */ + uip_buf = payload; + uip_len = *payload_size; + uip_arp_out(); + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) { + *payload_size = uip_len; + traceEvent(TRACE_DEBUG, "ARP request packets are sent instead of packets"); + } + + /* A NULL MAC as destination means that the packet is directed to the + * default gateway. */ + if ((*payload_size > 6) && (!memcmp(payload, null_mac, 6))) { + traceEvent(TRACE_DEBUG, "Detected packet for the gateway"); + + /* Overwrite the destination MAC with the actual gateway mac address */ + memcpy(payload, priv->gateway_mac, 6); + } + + return (N2N_ACCEPT); +} + +void on_main_loop_period(n2n_edge_t *eee, time_t now) { + n2n_android_t *priv = (n2n_android_t *) edge_get_userdata(eee); + + /* call arp timer periodically */ + if ((now - priv->lastArpPeriod) > ARP_PERIOD_INTERVAL) { + uip_arp_timer(); + priv->lastArpPeriod = now; + } +} + +void on_edge_sock_opened(n2n_edge_t *eee) { + if (!g_status && !g_status->jvm) { + traceEvent(TRACE_ERROR, "Failed to get jvm environment."); + return; + } + + JNIEnv *env; + if ((*g_status->jvm)->AttachCurrentThread(g_status->jvm, &env, NULL) != JNI_OK) { + traceEvent(TRACE_ERROR, "Failed to attach jvm to this thread."); + return; + } + + if (protect_socket(edge_get_n2n_socket(eee)) < 0) { + traceEvent(TRACE_ERROR, "protect(n2n_socket) failed"); + // todo notify deamon to stop + } + + traceEvent(TRACE_DEBUG, "Successfully protected n2n_sock."); + return; +} + +/* *************************************************** */ +#ifndef N2N_V3 +int start_edge_v2(n2n_edge_status_t *status) { + int keep_on_running = 0; + char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0"; + char ip_mode[N2N_IF_MODE_SIZE] = "static"; + char ip_addr[N2N_NETMASK_STR_SIZE] = ""; + char netmask[N2N_NETMASK_STR_SIZE] = "255.255.255.0"; + char device_mac[N2N_MACNAMSIZ] = ""; + char *encrypt_key = NULL; + struct in_addr gateway_ip = {0}; + struct in_addr tap_ip = {0}; + n2n_edge_conf_t conf; + n2n_edge_t *eee = NULL; + n2n_edge_callbacks_t callbacks; + n2n_android_t private_status; + int i; + tuntap_dev dev; + uint8_t hex_mac[6]; + int rv = 0; + + if (!status) { + traceEvent(TRACE_ERROR, "Empty cmd struct"); + return 1; + } + g_status = status; + n2n_edge_cmd_t *cmd = &status->cmd; + + setTraceLevel(cmd->trace_vlevel); + FILE *fp = fopen(cmd->logpath, "a"); + if (fp == NULL) { + traceEvent(TRACE_ERROR, "failed to open log file."); + } else { + setTraceFile(fp); + } + + if (cmd->vpn_fd < 0) { + traceEvent(TRACE_ERROR, "VPN socket is invalid."); + return 1; + } + + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTING; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + memset(&dev, 0, sizeof(dev)); + edge_init_conf_defaults(&conf); + + /* Load the configuration */ + strncpy((char *) conf.community_name, cmd->community, N2N_COMMUNITY_SIZE - 1); + + if (cmd->enc_key && cmd->enc_key[0]) { + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + conf.encrypt_key = strdup(cmd->enc_key); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key); + + if (cmd->encryption_mode[0]) { + if (!strcmp(cmd->encryption_mode, "Twofish")) + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + else if (!strcmp(cmd->encryption_mode, "AES-CBC")) + conf.transop_id = N2N_TRANSFORM_ID_AESCBC; + else if (!strcmp(cmd->encryption_mode, "Speck-CTR")) + conf.transop_id = N2N_TRANSFORM_ID_SPECK; + else if (!strcmp(cmd->encryption_mode, "ChaCha20")) + conf.transop_id = N2N_TRANSFORM_ID_CHACHA20; + else + traceEvent(TRACE_WARNING, "unknown encryption mode:'%s'\n", cmd->encryption_mode); + } + } else + conf.transop_id = N2N_TRANSFORM_ID_NULL; + + scan_address(ip_addr, N2N_NETMASK_STR_SIZE, + ip_mode, N2N_IF_MODE_SIZE, + cmd->ip_addr); + + dev.fd = cmd->vpn_fd; + + conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; + conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + conf.dyn_ip_mode = (strcmp("dhcp", ip_mode) == 0) ? 1 : 0; + conf.header_encryption = cmd->header_encryption == 0 ? 0 : 2; + + for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i) { + if (cmd->supernodes[i][0] != '\0') { + strncpy(conf.sn_ip_array[conf.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE); + traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int) conf.sn_num, + (conf.sn_ip_array[conf.sn_num])); + ++conf.sn_num; + } + } + + if (cmd->ip_netmask[0] != '\0') + strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); + + if (cmd->gateway_ip[0] != '\0') + inet_aton(cmd->gateway_ip, &gateway_ip); + + if (cmd->mac_addr[0] != '\0') + strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); + else { + strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); + traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); + } + + str2mac(hex_mac, device_mac); + + if (edge_verify_conf(&conf) != 0) { + if (conf.encrypt_key) free(conf.encrypt_key); + conf.encrypt_key = NULL; + traceEvent(TRACE_ERROR, "Bad configuration"); + rv = 1; + goto cleanup; + } + + /* Open the TAP device */ + if (tuntap_open(&dev, tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) { + traceEvent(TRACE_ERROR, "Failed in tuntap_open"); + rv = 1; + goto cleanup; + } + + /* Start n2n */ + eee = edge_init(&dev, &conf, &i); + + if (eee == NULL) { + traceEvent(TRACE_ERROR, "Failed in edge_init"); + rv = 1; + goto cleanup; + } + + /* Protect the socket so that the supernode traffic won't go inside the n2n VPN */ + if (protect_socket(edge_get_n2n_socket(eee)) < 0) { + traceEvent(TRACE_ERROR, "protect(n2n_socket) failed"); + rv = 1; + goto cleanup; + } + + if (protect_socket(edge_get_management_socket(eee)) < 0) { + traceEvent(TRACE_ERROR, "protect(management_socket) failed"); + rv = 1; + goto cleanup; + } + + /* Private Status */ + memset(&private_status, 0, sizeof(private_status)); + private_status.gateway_ip = gateway_ip.s_addr; + private_status.conf = &conf; + memcpy(private_status.tap_mac, hex_mac, 6); + inet_aton(ip_addr, &tap_ip); + private_status.tap_ipaddr = tap_ip.s_addr; + edge_set_userdata(eee, &private_status); + + /* set host addr, netmask, mac addr for UIP and init arp*/ + { + int match, i; + int ip[4]; + uip_ipaddr_t ipaddr; + struct uip_eth_addr eaddr; + + match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_sethostaddr(ipaddr); + match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_setnetmask(ipaddr); + for (i = 0; i < 6; ++i) + eaddr.addr[i] = hex_mac[i]; + uip_setethaddr(eaddr); + + uip_arp_init(); + } + + /* Set up the callbacks */ + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.sn_registration_updated = on_sn_registration_updated; + callbacks.packet_from_peer = on_packet_from_peer; + callbacks.packet_from_tap = on_packet_from_tap; + callbacks.main_loop_period = on_main_loop_period; + edge_set_callbacks(eee, &callbacks); + + keep_on_running = 1; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + traceEvent(TRACE_NORMAL, "edge started"); + + run_edge_loop(eee, &keep_on_running); + + traceEvent(TRACE_NORMAL, "edge stopped"); + + cleanup: + if (eee) edge_term(eee); + if (encrypt_key) free(encrypt_key); + tuntap_close(&dev); + edge_term_conf(&conf); + + return rv; +} + +/* *************************************************** */ + +int stop_edge_v2(void) { + // quick stop + int fd = open_socket(0, 0 /* bind LOOPBACK*/ ); + if (fd < 0) { + return 1; + } + + struct sockaddr_in peer_addr; + peer_addr.sin_family = PF_INET; + peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT); + sendto(fd, "stop", 4, 0, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_in)); + close(fd); + + // Do not report the status yet, the edge thread may be still running + /* + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + */ + + return 0; +} +#else + +int g_stop_initial = 0; + +int start_edge_v3(n2n_edge_status_t *status) { + int keep_on_running = 0; + char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0"; + char ip_mode[N2N_IF_MODE_SIZE] = "static"; + char ip_addr[N2N_NETMASK_STR_SIZE] = ""; + char netmask[N2N_NETMASK_STR_SIZE] = "255.255.255.0"; + char device_mac[N2N_MACNAMSIZ] = ""; + char *encrypt_key = NULL; + struct in_addr gateway_ip = {0}; + struct in_addr tap_ip = {0}; + n2n_edge_conf_t conf; + n2n_edge_t *eee = NULL; + n2n_edge_callbacks_t callbacks; + n2n_android_t private_status; + int i; + tuntap_dev dev; + uint8_t hex_mac[6]; + int rv = 0; + + if (!status) { + traceEvent(TRACE_ERROR, "Empty cmd struct"); + return 1; + } + + g_stop_initial = 0; + g_status = status; + n2n_edge_cmd_t *cmd = &status->cmd; + + setTraceLevel(cmd->trace_vlevel); + FILE *fp = fopen(cmd->logpath, "a"); + if (fp == NULL) { + traceEvent(TRACE_ERROR, "failed to open log file."); + } else { + setTraceFile(fp); + } + + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTING; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + memset(&dev, 0, sizeof(dev)); + edge_init_conf_defaults(&conf); + + /* Load the configuration */ + strncpy((char *) conf.community_name, cmd->community, N2N_COMMUNITY_SIZE - 1); + + if (cmd->enc_key && cmd->enc_key[0]) { + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + conf.encrypt_key = strdup(cmd->enc_key); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key); + + if (cmd->encryption_mode[0]) { + if (!strcmp(cmd->encryption_mode, "Twofish")) + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + else if (!strcmp(cmd->encryption_mode, "AES-CBC")) + conf.transop_id = N2N_TRANSFORM_ID_AES; + else if (!strcmp(cmd->encryption_mode, "Speck-CTR")) + conf.transop_id = N2N_TRANSFORM_ID_SPECK; + else if (!strcmp(cmd->encryption_mode, "ChaCha20")) + conf.transop_id = N2N_TRANSFORM_ID_CHACHA20; + else + traceEvent(TRACE_WARNING, "unknown encryption mode:'%s'\n", cmd->encryption_mode); + } + } else + conf.transop_id = N2N_TRANSFORM_ID_NULL; + + if(cmd->ip_mode == 0) + scan_address(ip_addr, N2N_NETMASK_STR_SIZE, + ip_mode, N2N_IF_MODE_SIZE, + cmd->ip_addr); + else if(cmd->ip_mode == 1) + memset(ip_mode, 0, sizeof(ip_mode)); + + dev.fd = cmd->vpn_fd; + + conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; + conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + conf.header_encryption = cmd->header_encryption == 0 ? 0 : 2; + + if(0 == strcmp("static", ip_mode)) + conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC; + else if(0 == strcmp("dhcp", ip_mode)) + conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP; + else + conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; + + for (i = 0; i < EDGE_CMD_SUPERNODES_NUM && cmd->supernodes[i][0] != '\0'; i++) { + if( 0 == edge_conf_add_supernode(&conf, cmd->supernodes[i])) + traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int) conf.sn_num, + cmd->supernodes[i]); + } + + if (cmd->ip_netmask[0] != '\0') + strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); + + if (cmd->gateway_ip[0] != '\0') + inet_aton(cmd->gateway_ip, &gateway_ip); + + if (cmd->mac_addr[0] != '\0') + strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); + else { + strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); + traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); + } + + str2mac(hex_mac, device_mac); + + if(cmd->devDesc && cmd->devDesc[0]) { + memset(conf.dev_desc, 0, sizeof(conf.dev_desc)); + strncpy(conf.dev_desc, cmd->devDesc, sizeof(conf.dev_desc) - 1); + } + + if (edge_verify_conf(&conf) != 0) { + if (conf.encrypt_key) free(conf.encrypt_key); + conf.encrypt_key = NULL; + traceEvent(TRACE_ERROR, "Bad configuration"); + rv = 1; + goto cleanup; + } + + /* Start n2n */ + eee = edge_init(&conf, &i); + + if (eee == NULL) { + traceEvent(TRACE_ERROR, "Failed in edge_init"); + rv = 1; + goto cleanup; + } + + /* Protect the socket so that the supernode traffic won't go inside the n2n VPN */ + if (protect_socket(edge_get_management_socket(eee)) < 0) { + traceEvent(TRACE_ERROR, "protect(management_socket) failed"); + rv = 1; + goto cleanup; + } + + strncpy(eee->tuntap_priv_conf.tuntap_dev_name, tuntap_dev_name, N2N_IFNAMSIZ - 1); + strncpy(eee->tuntap_priv_conf.ip_mode, ip_mode, N2N_IF_MODE_SIZE - 1); + strncpy(eee->tuntap_priv_conf.ip_addr, ip_addr, N2N_NETMASK_STR_SIZE - 1); + strncpy(eee->tuntap_priv_conf.netmask, netmask, N2N_NETMASK_STR_SIZE - 1); + strncpy(eee->tuntap_priv_conf.device_mac, device_mac, N2N_MACNAMSIZ - 1); + eee->tuntap_priv_conf.mtu = cmd->mtu; + + if((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) || + ((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) { + traceEvent(TRACE_NORMAL, "Use manually set IP address."); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC; + } else if(0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) { + traceEvent(TRACE_NORMAL, "Obtain IP from other edge DHCP services."); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP; + } else { + traceEvent(TRACE_NORMAL, "Automatically assign IP address by supernode."); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; + } + + /* Private Status */ + memset(&private_status, 0, sizeof(private_status)); + private_status.gateway_ip = gateway_ip.s_addr; + private_status.conf = &conf; + memcpy(private_status.tap_mac, hex_mac, 6); + inet_aton(ip_addr, &tap_ip); + private_status.tap_ipaddr = tap_ip.s_addr; + edge_set_userdata(eee, &private_status); + + /* set host addr, netmask, mac addr for UIP and init arp*/ + if(cmd->ip_mode == 0) + { + int match, i; + int ip[4]; + uip_ipaddr_t ipaddr; + struct uip_eth_addr eaddr; + + match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_sethostaddr(ipaddr); + match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_setnetmask(ipaddr); + for (i = 0; i < 6; ++i) + eaddr.addr[i] = hex_mac[i]; + uip_setethaddr(eaddr); + + uip_arp_init(); + } + + /* Set up the callbacks */ + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.sn_registration_updated = on_sn_registration_updated; + callbacks.packet_from_peer = on_packet_from_peer; + callbacks.packet_from_tap = on_packet_from_tap; + callbacks.main_loop_period = on_main_loop_period; + callbacks.sock_opened = on_edge_sock_opened; + edge_set_callbacks(eee, &callbacks); + + /* Hin2n : mostly transplant from origin n2n edge init sequence */ + uint8_t runlevel = 0; /* bootstrap: runlevel */ + time_t now, last_action = 0; /* timeout */ + uint8_t seek_answer = 1; /* expecting answer from supernode */ + tuntap_dev tuntap = {0}; /* a tuntap device */ + fd_set socket_mask; /* for supernode answer */ + struct timeval wait_time; /* timeout for sn answer */ + peer_info_t *scan, *scan_tmp; /* supernode iteration */ + uint16_t expected = sizeof(uint16_t); + uint16_t position = 0; + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE + sizeof(uint16_t)]; /* buffer + prepended buffer length in case of tcp */ + macstr_t mac_buf; /* output mac address */ + + tuntap.fd = cmd->vpn_fd; + + // mini main loop for bootstrap, not using main loop code because some of its mechanisms do not fit in here + // for the sake of quickly establishing connection. REVISIT when a more elegant way to re-use main loop code + // is found + + // if more than one supernode given, find at least one who is alive to faster establish connection + if((HASH_COUNT(eee->conf.supernodes) <= 1) || (eee->conf.connect_tcp)) { + // skip the initial supernode ping + traceEvent(TRACE_DEBUG, "Skip PING to supernode."); + runlevel = 2; + } + + eee->last_sup = 0; /* if it wasn't zero yet */ + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + + while(runlevel < 5) { + if(g_stop_initial) { + rv = 1; + goto cleanup; + } + + now = time(NULL); + + // we do not use switch-case because we also check for 'greater than' + + if(runlevel == 0) { /* PING to all known supernodes */ + last_action = now; + eee->sn_pong = 0; + // (re-)initialize the number of max concurrent pings (decreases by calling send_query_peer) + eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL; + send_query_peer(eee, null_mac); + traceEvent(TRACE_NORMAL, "Send PING to supernodes."); + runlevel++; + } + + if(runlevel == 1) { /* PING has been sent to all known supernodes */ + if(eee->sn_pong) { + // first answer + eee->sn_pong = 0; + sn_selection_sort(&(eee->conf.supernodes)); + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + traceEvent(TRACE_NORMAL, "Received first PONG from supernode [%s].", eee->curr_sn->ip_addr); + runlevel++; + } else if(last_action <= (now - BOOTSTRAP_TIMEOUT)) { + // timeout + runlevel--; + // skip waiting for answer to direcly go to send PING again + seek_answer = 0; + traceEvent(TRACE_DEBUG, "PONG timeout."); + } + } + + // by the way, have every later PONG cause the remaining (!) list to be sorted because the entries + // before have already been tried; as opposed to initial PONG, do not change curr_sn + if(runlevel > 1) { + if(eee->sn_pong) { + eee->sn_pong = 0; + if(eee->curr_sn->hh.next) { + sn_selection_sort((peer_info_t**)&(eee->curr_sn->hh.next)); + traceEvent(TRACE_DEBUG, "Received additional PONG from supernode."); + // here, it is hard to detemine from which one, so no details to output + } + } + } + + if(runlevel == 2) { /* send REGISTER_SUPER to get auto ip address from a supernode */ + if(eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_SN_ASSIGN) { + last_action = now; + eee->sn_wait = 1; + send_register_super(eee); + runlevel++; + traceEvent(TRACE_NORMAL, "Send REGISTER_SUPER to supernode [%s] asking for IP address.", + eee->curr_sn->ip_addr); + } else { + runlevel += 2; /* skip waiting for TUNTAP IP address */ + traceEvent(TRACE_DEBUG, "Skip auto IP address asignment."); + } + } + + if(runlevel == 3) { /* REGISTER_SUPER to get auto ip address from a sn has been sent */ + if(!eee->sn_wait) { /* TUNTAP IP address received */ + runlevel++; + traceEvent(TRACE_NORMAL, "Received REGISTER_SUPER_ACK from supernode for IP address asignment."); + // it should be from curr_sn, but we can't determine definitely here, so no details to output + } else if(last_action <= (now - BOOTSTRAP_TIMEOUT)) { + // timeout, so try next supernode + if(eee->curr_sn->hh.next) + eee->curr_sn = eee->curr_sn->hh.next; + else + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + runlevel--; + // skip waiting for answer to direcly go to send REGISTER_SUPER again + seek_answer = 0; + traceEvent(TRACE_DEBUG, "REGISTER_SUPER_ACK timeout."); + } + } + + if(runlevel == 4) { /* configure the TUNTAP device */ + /* call java function to establish vpn service */ + if(tuntap.fd < 0) { + int netmask = getIpAddrPrefixLength(eee->tuntap_priv_conf.netmask); + tuntap.fd = establishVpnService(&g_status->cmd, eee->tuntap_priv_conf.ip_addr, netmask); + + dev.fd = g_status->cmd.vpn_fd = tuntap.fd; + int val = fcntl(g_status->cmd.vpn_fd, F_GETFL); + if (val == -1) { + rv = 1; + goto cleanup; + } + if ((val & O_NONBLOCK) == O_NONBLOCK) { + val &= ~O_NONBLOCK; + val = fcntl(g_status->cmd.vpn_fd, F_SETFL, val); + if (val == -1) { + rv = 1; + goto cleanup; + } + } + + /****************** INIT ARP MODULE ******************/ + { + int match, i; + int ip[4]; + uip_ipaddr_t ipaddr; + struct uip_eth_addr eaddr; + + match = sscanf(eee->tuntap_priv_conf.ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_sethostaddr(ipaddr); + + match = sscanf(eee->tuntap_priv_conf.netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask); + rv = 1; + goto cleanup; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_setnetmask(ipaddr); + + for (i = 0; i < 6; ++i) + eaddr.addr[i] = hex_mac[i]; + uip_setethaddr(eaddr); + + uip_arp_init(); + } + } + + if(tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode, + eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask, + eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) + goto cleanup; + memcpy(&eee->device, &tuntap, sizeof(tuntap)); + traceEvent(TRACE_NORMAL, "Created local tap device IP: %s, Mask: %s, MAC: %s", + eee->tuntap_priv_conf.ip_addr, + eee->tuntap_priv_conf.netmask, + macaddr_str(mac_buf, eee->device.mac_addr)); + runlevel = 5; + // no more answers required + seek_answer = 0; + } + + // we usually wait for some answer, there however are exceptions when going back to a previous runlevel + if(seek_answer) { + FD_ZERO(&socket_mask); + FD_SET(eee->sock, &socket_mask); + wait_time.tv_sec = BOOTSTRAP_TIMEOUT; + wait_time.tv_usec = 0; + + if(select(eee->sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) { + if(FD_ISSET(eee->sock, &socket_mask)) { + fetch_and_eventually_process_data (eee, eee->sock, + pktbuf, &expected, &position, + now); + } + } + } + + seek_answer = 1; + } + // allow a higher number of pings for first regular round of ping + // to quicker get an inital 'supernode selection criterion overview' + eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL; + // shape supernode list; make current one the first on the list + HASH_ITER(hh, eee->conf.supernodes, scan, scan_tmp) { + if(scan == eee->curr_sn) + sn_selection_criterion_good(&(scan->selection_criterion)); + else + sn_selection_criterion_default(&(scan->selection_criterion)); + } + sn_selection_sort(&(eee->conf.supernodes)); + // do not immediately ping again, allow some time + eee->last_sweep = now - SWEEP_TIME + 2 * BOOTSTRAP_TIMEOUT; + eee->sn_wait = 1; + eee->last_register_req = 0; + +#ifdef HAVE_LIBCAP + /* Before dropping the privileges, retain capabilities to regain them in future. */ + caps = cap_get_proc(); + + cap_set_flag(caps, CAP_PERMITTED, num_cap, cap_values, CAP_SET); + cap_set_flag(caps, CAP_EFFECTIVE, num_cap, cap_values, CAP_SET); + + if((cap_set_proc(caps) != 0) || (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0)) + traceEvent(TRACE_WARNING, "Unable to retain permitted capabilities [%s]\n", strerror(errno)); +#else +#ifndef __APPLE__ + traceEvent(TRACE_WARNING, "n2n has not been compiled with libcap-dev. Some commands may fail."); +#endif +#endif /* HAVE_LIBCAP */ + +#if 1 + if((eee->tuntap_priv_conf.userid != 0) || (eee->tuntap_priv_conf.groupid != 0)) { + traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d", + (signed int)eee->tuntap_priv_conf.userid, (signed int)eee->tuntap_priv_conf.groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + if((setgid(eee->tuntap_priv_conf.groupid) != 0) + || (setuid(eee->tuntap_priv_conf.userid) != 0)) { + traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno)); + exit(1); + } + } + + if((getuid() == 0) || (getgid() == 0)) + traceEvent(TRACE_WARNING, "Running as root is discouraged, check out the -u/-g options"); +#endif + + keep_on_running = 1; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + traceEvent(TRACE_NORMAL, "edge started"); + + eee->keep_running = &keep_on_running; + run_edge_loop(eee); + + traceEvent(TRACE_NORMAL, "edge stopped"); + +cleanup: + if (eee) edge_term(eee); + if (encrypt_key) free(encrypt_key); + tuntap_close(&dev); + edge_term_conf(&conf); + + return rv; +} + +int stop_edge_v3(void) { + // quick stop + g_stop_initial = 1; + + int fd = open_socket(0, 0 /* bind LOOPBACK*/,0 ); + if (fd < 0) { + return 1; + } + + struct sockaddr_in peer_addr; + peer_addr.sin_family = PF_INET; + peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT); + sendto(fd, "stop", 4, 0, (struct sockaddr *) &peer_addr, sizeof(struct sockaddr_in)); + close(fd); + + // Do not report the status yet, the edge thread may be still running + /* + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + */ + + return 0; +} + +#endif diff --git a/Hin2n/src/main/cpp/edge_jni/edge_jni.c b/Hin2n/src/main/cpp/edge_jni/edge_jni.c new file mode 100644 index 00000000..3db3439e --- /dev/null +++ b/Hin2n/src/main/cpp/edge_jni/edge_jni.c @@ -0,0 +1,709 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-15. +// + +#include +#include +#include +#include +#include +#include "edge_jni.h" + +static n2n_edge_status_t status; + +static int GetEdgeCmd(JNIEnv *env, jobject jcmd, n2n_edge_cmd_t *cmd); + +static void *EdgeRoutine(void *); + +static void ResetEdgeStatus(JNIEnv *env, uint8_t cleanup); + +static void InitEdgeStatus(void); + +JNIEXPORT jboolean JNICALL Java_wang_switchy_hin2n_service_N2NService_startEdge( + JNIEnv *env, + jobject this, + jobject jcmd) { + +#ifndef NDEBUG + __android_log_write(ANDROID_LOG_DEBUG, "edge_jni", "in start"); +#endif /* #ifndef NDEBUG */ + ResetEdgeStatus(env, 0 /* not cleanup*/); + if (GetEdgeCmd(env, jcmd, &status.cmd) != 0) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + + /* only when java already created the vpn service and pass to C should we reset NON_BLOCK */ + if(status.cmd.vpn_fd > 0) { + int val = fcntl(status.cmd.vpn_fd, F_GETFL); + if (val == -1) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + if ((val & O_NONBLOCK) == O_NONBLOCK) { + val &= ~O_NONBLOCK; + val = fcntl(status.cmd.vpn_fd, F_SETFL, val); + if (val == -1) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + } + } + + if ((*env)->GetJavaVM(env, &status.jvm) != JNI_OK) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + status.jobj_service = (*env)->NewGlobalRef(env, this); + jclass cls = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus"); + if (!cls) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + status.jcls_status = (*env)->NewGlobalRef(env, cls); + jclass cls_rs = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus$RunningStatus"); + if (!cls_rs) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + status.jcls_rs = (*env)->NewGlobalRef(env, cls_rs); + + switch (status.edge_type) { + case EDGE_TYPE_V1: + status.start_edge = start_edge_v1; + status.stop_edge = stop_edge_v1; + break; + case EDGE_TYPE_V2: + status.start_edge = start_edge_v2; + status.stop_edge = stop_edge_v2; + break; + case EDGE_TYPE_V2S: + status.start_edge = start_edge_v2s; + status.stop_edge = stop_edge_v2s; + break; + case EDGE_TYPE_V3: + status.start_edge = start_edge_v3; + status.stop_edge = stop_edge_v3; + break; + default: + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + status.report_edge_status = report_edge_status; + pthread_mutex_init(&status.mutex, NULL); + int ret = pthread_create(&status.tid, NULL, EdgeRoutine, NULL); + if (ret != 0) { + ResetEdgeStatus(env, 1 /* cleanup*/); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +JNIEXPORT void JNICALL Java_wang_switchy_hin2n_service_N2NService_stopEdge( + JNIEnv *env, + jobject this) { + +#ifndef NDEBUG + __android_log_write(ANDROID_LOG_DEBUG, "edge_jni", "in stop"); +#endif /* #ifndef NDEBUG */ + ResetEdgeStatus(env, 0 /* not cleanup*/); +} + +JNIEXPORT jobject JNICALL Java_wang_switchy_hin2n_service_N2NService_getEdgeStatus( + JNIEnv *env, + jobject this) { + const char *running_status = "DISCONNECT"; + if (status.tid != -1) { + if (!pthread_kill(status.tid, 0)) { + pthread_mutex_lock(&status.mutex); + switch (status.running_status) { + case EDGE_STAT_CONNECTING: + running_status = "CONNECTING"; + break; + case EDGE_STAT_CONNECTED: + running_status = "CONNECTED"; + break; + case EDGE_STAT_SUPERNODE_DISCONNECT: + running_status = "SUPERNODE_DISCONNECT"; + break; + case EDGE_STAT_DISCONNECT: + running_status = "DISCONNECT"; + break; + case EDGE_STAT_FAILED: + running_status = "FAILED"; + break; + default: + running_status = "DISCONNECT"; + } + pthread_mutex_unlock(&status.mutex); + } + } + + jclass cls = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus"); + jobject jStatus = (*env)->NewObject(env, cls, (*env)->GetMethodID(env, cls, "", "()V")); + if (!jStatus) { + return NULL; + } + jclass cls_rs = (*env)->FindClass(env, "wang/switchy/hin2n/model/EdgeStatus$RunningStatus"); + jobject jRunningStatus = (*env)->GetStaticObjectField(env, cls_rs, + (*env)->GetStaticFieldID(env, cls_rs, + running_status, + "Lwang/switchy/hin2n/model/EdgeStatus$RunningStatus;")); + (*env)->SetObjectField(env, jStatus, (*env)->GetFieldID(env, cls, "runningStatus", + "Lwang/switchy/hin2n/model/EdgeStatus$RunningStatus;"), + jRunningStatus); + + return jStatus; +} + +///////////////////////////////////////////////////////////////////////// +#ifndef JNI_CHECKNULL +#define JNI_CHECKNULL(p) do { if (!(p)) return 1;}while(0) +#endif /* JNI_CHECKNULL */ + +int GetEdgeCmd(JNIEnv *env, jobject jcmd, n2n_edge_cmd_t *cmd) { + jclass cls; + int i, j; + + cls = (*env)->GetObjectClass(env, jcmd); + JNI_CHECKNULL(cls); + + // edgeType + { + jint jiEdgeType = (*env)->GetIntField(env, jcmd, + (*env)->GetFieldID(env, cls, "edgeType", "I")); + if (jiEdgeType < EDGE_TYPE_V1 || jiEdgeType > EDGE_TYPE_V3) { + return 1; + } + status.edge_type = jiEdgeType; + +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "edgeType = %d", status.edge_type); +#endif /* #ifndef NDEBUG */ + } + + { + jint jiEdgeType = (*env)->GetIntField(env, jcmd, + (*env)->GetFieldID(env, cls, "ipMode", "I")); + if (jiEdgeType < 0 || jiEdgeType > 1) { + return 1; + } + status.cmd.ip_mode = jiEdgeType; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "ipMode = %d", status.cmd.ip_mode); +#endif /* #ifndef NDEBUG */ + } + + // ipAddr + { + jstring jsIpAddr = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "ipAddr", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsIpAddr); + const char *ipAddr = (*env)->GetStringUTFChars(env, jsIpAddr, NULL); + if (!ipAddr || strlen(ipAddr) == 0) { + (*env)->ReleaseStringUTFChars(env, jsIpAddr, ipAddr); + return 1; + } + strncpy(cmd->ip_addr, ipAddr, EDGE_CMD_IPSTR_SIZE); + (*env)->ReleaseStringUTFChars(env, jsIpAddr, ipAddr); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "ipAddr = %s", cmd->ip_addr); +#endif /* #ifndef NDEBUG */ + } + // ipNetmask + { + jstring jsIpNetmask = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "ipNetmask", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsIpNetmask); + const char *ipNetmask = (*env)->GetStringUTFChars(env, jsIpNetmask, NULL); + if (!ipNetmask || strlen(ipNetmask) == 0) { + (*env)->ReleaseStringUTFChars(env, jsIpNetmask, ipNetmask); + return 1; + } + strncpy(cmd->ip_netmask, ipNetmask, EDGE_CMD_IPSTR_SIZE); + (*env)->ReleaseStringUTFChars(env, jsIpNetmask, ipNetmask); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "ipNetmask = %s", cmd->ip_netmask); +#endif /* #ifndef NDEBUG */ + } + // supernodes + { + jarray jaSupernodes = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "supernodes", + "[Ljava/lang/String;")); + JNI_CHECKNULL(jaSupernodes); + int len = (*env)->GetArrayLength(env, jaSupernodes); + if (len <= 0) { + return 1; + } + for (i = 0, j = 0; i < len && i < EDGE_CMD_SUPERNODES_NUM; ++i) { + const jobject jsNode = (*env)->GetObjectArrayElement(env, jaSupernodes, i); + if (!jsNode) { + continue; + } + const char *node = (*env)->GetStringUTFChars(env, jsNode, NULL); + if (!node || strlen(node) == 0) { + (*env)->ReleaseStringUTFChars(env, jsNode, node); + continue; + } + strncpy(cmd->supernodes[j], node, EDGE_CMD_SN_HOST_SIZE); + (*env)->ReleaseStringUTFChars(env, jsNode, node); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "supernodes = %s", + cmd->supernodes[j]); +#endif /* #ifndef NDEBUG */ + j++; + } +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "j = %d", j); +#endif /* #ifndef NDEBUG */ + if (j == 0) { + return 1; + } + } + // community + { + jstring jsCommunity = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "community", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsCommunity); + const char *community = (*env)->GetStringUTFChars(env, jsCommunity, NULL); + if (!community || strlen(community) == 0) { + (*env)->ReleaseStringUTFChars(env, jsCommunity, community); + return 1; + } + strncpy(cmd->community, community, EDGE_CMD_COMMUNITY_SIZE); + (*env)->ReleaseStringUTFChars(env, jsCommunity, community); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "community = %s", cmd->community); +#endif /* #ifndef NDEBUG */ + } + // encKey + { + jstring jsEncKey = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "encKey", + "Ljava/lang/String;")); + if (jsEncKey) { + const char *encKey = (*env)->GetStringUTFChars(env, jsEncKey, NULL); + if (encKey && strlen(encKey) != 0) { + cmd->enc_key = strdup(encKey); + } + (*env)->ReleaseStringUTFChars(env, jsEncKey, encKey); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "encKey = %s", cmd->enc_key); +#endif /* #ifndef NDEBUG */ + } + } + // encKeyFile + if (EDGE_TYPE_V2 <= status.edge_type && status.edge_type <= EDGE_TYPE_V3) { + jstring jsEncKeyFile = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "encKeyFile", + "Ljava/lang/String;")); + if (jsEncKeyFile) { + const char *encKeyFile = (*env)->GetStringUTFChars(env, jsEncKeyFile, NULL); + if (encKeyFile && strlen(encKeyFile) != 0) { + cmd->enc_key_file = strdup(encKeyFile); + } + (*env)->ReleaseStringUTFChars(env, jsEncKeyFile, encKeyFile); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "encKeyFile = %s", + cmd->enc_key_file); +#endif /* #ifndef NDEBUG */ + } + } + // macAddr + { + jstring jsMacAddr = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "macAddr", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsMacAddr); + const char *macAddr = (*env)->GetStringUTFChars(env, jsMacAddr, NULL); + if (macAddr && strlen(macAddr) != 0) { + strncpy(cmd->mac_addr, macAddr, EDGE_CMD_MACNAMSIZ); + } + (*env)->ReleaseStringUTFChars(env, jsMacAddr, macAddr); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "macAddr = %s", cmd->mac_addr); +#endif /* #ifndef NDEBUG */ + } + // mtu + { + jint jiMtu = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "mtu", "I")); + if (jiMtu <= 0) { + return 1; + } + cmd->mtu = jiMtu; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "mtu = %d", cmd->mtu); +#endif /* #ifndef NDEBUG */ + } + // localIP + if (status.edge_type == EDGE_TYPE_V2S) { + jstring jsLocalIP = (*env)->GetObjectField(env, jcmd, + (*env)->GetFieldID(env, cls, "localIP", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsLocalIP); + const char *localIP = (*env)->GetStringUTFChars(env, jsLocalIP, NULL); + if (localIP && strlen(localIP) != 0) { + strncpy(cmd->local_ip, localIP, EDGE_CMD_IPSTR_SIZE); + } + (*env)->ReleaseStringUTFChars(env, jsLocalIP, localIP); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "localIP = %s", cmd->local_ip); +#endif /* #ifndef NDEBUG */ + } + // holePunchInterval + if (status.edge_type == EDGE_TYPE_V2S) { + jint jiHolePunchInterval = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, + "holePunchInterval", + "I")); + if (jiHolePunchInterval <= 0) { + return 1; + } + cmd->holepunch_interval = jiHolePunchInterval; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "holePunchInterval = %d", + cmd->holepunch_interval); +#endif /* #ifndef NDEBUG */ + } + // reResoveSupernodeIP + { + jboolean jbReResoveSupernodeIP = (*env)->GetBooleanField(env, jcmd, + (*env)->GetFieldID(env, cls, + "reResoveSupernodeIP", + "Z")); + cmd->re_resolve_supernode_ip = jbReResoveSupernodeIP ? 1 : 0; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "reResoveSupernodeIP = %d", + cmd->re_resolve_supernode_ip); +#endif /* #ifndef NDEBUG */ + } + // localPort + { + jint jiLocalPort = (*env)->GetIntField(env, jcmd, + (*env)->GetFieldID(env, cls, "localPort", "I")); + if (jiLocalPort < 0) { + return 1; + } + cmd->local_port = jiLocalPort; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "localPort = %d", cmd->local_port); +#endif /* #ifndef NDEBUG */ + } + // allowRouting + { + jboolean jbAllowRouting = (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, + "allowRouting", + "Z")); + cmd->allow_routing = jbAllowRouting ? 1 : 0; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "allowRouting = %d", cmd->allow_routing); +#endif /* #ifndef NDEBUG */ + } + // dropMuticast + if (status.edge_type == EDGE_TYPE_V2 || status.edge_type == EDGE_TYPE_V2S) { + jboolean jbDropMuticast = (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, + "dropMuticast", + "Z")); + cmd->drop_multicast = jbDropMuticast ? 1 : 0; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "dropMuticast = %d", + cmd->drop_multicast); +#endif /* #ifndef NDEBUG */ + } + // gatewayIp + { + jstring jbGatewayIp = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "gatewayIp", + "Ljava/lang/String;")); + JNI_CHECKNULL(jbGatewayIp); + const char *ipAddr = (*env)->GetStringUTFChars(env, jbGatewayIp, NULL); + if (!ipAddr) { + (*env)->ReleaseStringUTFChars(env, jbGatewayIp, ipAddr); + return 1; + } + strncpy(cmd->gateway_ip, ipAddr, EDGE_CMD_IPSTR_SIZE); + (*env)->ReleaseStringUTFChars(env, jbGatewayIp, ipAddr); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "gatewayIp = %s", cmd->gateway_ip); +#endif /* #ifndef NDEBUG */ + } + // encryptionMode + { + jstring jEncryptionMode = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "encryptionMode", + "Ljava/lang/String;")); + JNI_CHECKNULL(jEncryptionMode); + const char *encMode = (*env)->GetStringUTFChars(env, jEncryptionMode, NULL); + if (!encMode) { + (*env)->ReleaseStringUTFChars(env, jEncryptionMode, encMode); + return 1; + } + strncpy(cmd->encryption_mode, encMode, EDGE_CMD_ENCRYPTION_MODE_SIZE); + (*env)->ReleaseStringUTFChars(env, jEncryptionMode, encMode); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "encryptionMode = %s", cmd->encryption_mode); +#endif /* #ifndef NDEBUG */ + } + // httpTunnel + if (status.edge_type == EDGE_TYPE_V1) { + jboolean jbHttpTunnel = (*env)->GetBooleanField(env, jcmd, + (*env)->GetFieldID(env, cls, "httpTunnel", + "Z")); + cmd->http_tunnel = jbHttpTunnel ? 1 : 0; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "httpTunnel = %d", cmd->http_tunnel); +#endif /* #ifndef NDEBUG */ + } + // traceLevel + { + jint jiTraceLevel = (*env)->GetIntField(env, jcmd, + (*env)->GetFieldID(env, cls, "traceLevel", "I")); + cmd->trace_vlevel = jiTraceLevel; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "traceLevel = %d", cmd->trace_vlevel); +#endif /* #ifndef NDEBUG */ + } + // vpnFd + { + jint jiVpnFd = (*env)->GetIntField(env, jcmd, (*env)->GetFieldID(env, cls, "vpnFd", "I")); +#if 0 + if (jiVpnFd < 0) { + return 1; + } +#endif + cmd->vpn_fd = jiVpnFd; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "vpnFd = %d", cmd->vpn_fd); +#endif /* #ifndef NDEBUG */ + } + // logPath + jstring jsLogPath = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "logPath", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsLogPath); + const char *logPath = (*env)->GetStringUTFChars(env, jsLogPath, NULL); + if (logPath && strlen(logPath) != 0) { + cmd->logpath = strdup(logPath); + } + (*env)->ReleaseStringUTFChars(env, jsLogPath, logPath); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "logPath = %s", cmd->logpath); +#endif /* #ifndef NDEBUG */ + // devDesc + { + jstring jsDevDesc = (*env)->GetObjectField(env, jcmd, (*env)->GetFieldID(env, cls, "devDesc", + "Ljava/lang/String;")); + JNI_CHECKNULL(jsDevDesc); + const char *devDesc = (*env)->GetStringUTFChars(env, jsDevDesc, NULL); + if (devDesc && strlen(devDesc) != 0) { + cmd->devDesc = strdup(devDesc); + } + (*env)->ReleaseStringUTFChars(env, jsDevDesc, devDesc); +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "devDesc = %s", cmd->devDesc); +#endif /* #ifndef NDEBUG */ + } + // headerEnc + { + jboolean jbHeaderEnc = (*env)->GetBooleanField(env, jcmd, (*env)->GetFieldID(env, cls, + "headerEnc", + "Z")); + cmd->header_encryption = jbHeaderEnc ? 2 : 0; +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", "headerEnc = %d", cmd->header_encryption); +#endif /* #ifndef NDEBUG */ + } + + return 0; +} + +void InitEdgeStatus(void) { + memset(&status.cmd, 0, sizeof(status.cmd)); + status.cmd.enc_key = NULL; + status.cmd.enc_key_file = NULL; + status.cmd.mtu = 1400; + status.cmd.holepunch_interval = EDGE_CMD_HOLEPUNCH_INTERVAL; + status.cmd.re_resolve_supernode_ip = 0; + status.cmd.local_port = 0; + status.cmd.allow_routing = 0; + status.cmd.drop_multicast = 1; + status.cmd.http_tunnel = 0; + status.cmd.trace_vlevel = 1; + status.cmd.vpn_fd = -1; + status.cmd.logpath = NULL; + status.cmd.header_encryption = 0; + + status.tid = -1; + status.jvm = NULL; + status.jobj_service = NULL; + status.jcls_status = NULL; + status.jcls_rs = NULL; + status.start_edge = NULL; + status.stop_edge = NULL; + status.report_edge_status = NULL; + + status.edge_type = EDGE_TYPE_NONE; + status.running_status = EDGE_STAT_DISCONNECT; +} + +void ResetEdgeStatus(JNIEnv *env, uint8_t cleanup) { + static u_int8_t once = 0; + static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; + + if (!once) { + InitEdgeStatus(); + once = 1; + return; + } + + pthread_mutex_lock(&mut); + if (status.tid != -1 || cleanup) { +#ifndef NDEBUG + __android_log_print(ANDROID_LOG_DEBUG, "edge_jni", + "ResetEdgeStatus tid = %ld, cleanup = %d", status.tid, cleanup); +#endif /* #ifndef NDEBUG */ + if (status.stop_edge) { + status.stop_edge(); + } + if (status.tid != -1) { + pthread_join(status.tid, NULL); + } + pthread_mutex_lock(&status.mutex); + if (env) { + if (status.jcls_rs) { + (*env)->DeleteGlobalRef(env, status.jcls_rs); + } + if (status.jcls_status) { + (*env)->DeleteGlobalRef(env, status.jcls_status); + } + if (status.jobj_service) { + (*env)->DeleteGlobalRef(env, status.jobj_service); + } + } + if (status.cmd.enc_key_file) { + free(status.cmd.enc_key_file); + } + if (status.cmd.enc_key) { + free(status.cmd.enc_key); + } + if (status.cmd.logpath) { + free(status.cmd.logpath); + } + InitEdgeStatus(); + pthread_mutex_unlock(&status.mutex); + pthread_mutex_destroy(&status.mutex); + } + pthread_mutex_unlock(&mut); +} + +void *EdgeRoutine(void *ignore) { + int flag = 0; + JNIEnv *env = NULL; + + if (status.jvm) { + if ((*status.jvm)->AttachCurrentThread(status.jvm, &env, NULL) == JNI_OK) { + flag = 1; + } + } + + if (!status.start_edge) { + return NULL; + } + + int ret = status.start_edge(&status); + if (ret) { + pthread_mutex_lock(&status.mutex); + status.running_status = EDGE_STAT_FAILED; + pthread_mutex_unlock(&status.mutex); + report_edge_status(); + } + + if (flag && status.jvm) { + (*status.jvm)->DetachCurrentThread(status.jvm); + } + + return NULL; +} + +void report_edge_status(void) { + if (!status.jvm || !status.jobj_service || !status.jcls_status || !status.jcls_rs || + status.tid == -1) { + return; + } + + const char *running_status = "DISCONNECT"; + pthread_mutex_lock(&status.mutex); + switch (status.running_status) { + case EDGE_STAT_CONNECTING: + running_status = "CONNECTING"; + break; + case EDGE_STAT_CONNECTED: + running_status = "CONNECTED"; + break; + case EDGE_STAT_SUPERNODE_DISCONNECT: + running_status = "SUPERNODE_DISCONNECT"; + break; + case EDGE_STAT_DISCONNECT: + running_status = "DISCONNECT"; + break; + case EDGE_STAT_FAILED: + running_status = "FAILED"; + break; + default: + running_status = "DISCONNECT"; + } + pthread_mutex_unlock(&status.mutex); + + JNIEnv *env = NULL; + if ((*status.jvm)->GetEnv(status.jvm, (void **)&env, JNI_VERSION_1_1) != JNI_OK || !env) { + return; + } + + jmethodID mid = (*env)->GetMethodID(env, status.jcls_status, "", "()V"); + if (!mid) { + return; + } + jobject jStatus = (*env)->NewObject(env, status.jcls_status, mid); + if (!jStatus) { + return; + } + + jfieldID fid = (*env)->GetStaticFieldID(env, status.jcls_rs, running_status, + "Lwang/switchy/hin2n/model/EdgeStatus$RunningStatus;"); + if (!fid) { + (*env)->DeleteLocalRef(env, jStatus); + return; + } + jobject jRunningStatus = (*env)->GetStaticObjectField(env, status.jcls_rs, fid); + if (!jRunningStatus) { + (*env)->DeleteLocalRef(env, jRunningStatus); + (*env)->DeleteLocalRef(env, jStatus); + return; + } + fid = (*env)->GetFieldID(env, status.jcls_status, "runningStatus", + "Lwang/switchy/hin2n/model/EdgeStatus$RunningStatus;"); + if (!fid) { + (*env)->DeleteLocalRef(env, jRunningStatus); + (*env)->DeleteLocalRef(env, jStatus); + return; + } + (*env)->SetObjectField(env, jStatus, fid, jRunningStatus); + + + jclass cls = (*env)->GetObjectClass(env, status.jobj_service); + if (!cls) { + (*env)->DeleteLocalRef(env, jRunningStatus); + (*env)->DeleteLocalRef(env, jStatus); + return; + } + mid = (*env)->GetMethodID(env, cls, "reportEdgeStatus", + "(Lwang/switchy/hin2n/model/EdgeStatus;)V"); + if (!mid) { + (*env)->DeleteLocalRef(env, jRunningStatus); + (*env)->DeleteLocalRef(env, jStatus); + return; + } + (*env)->CallVoidMethod(env, status.jobj_service, mid, jStatus); + + (*env)->DeleteLocalRef(env, jRunningStatus); + (*env)->DeleteLocalRef(env, jStatus); +} diff --git a/Hin2n/src/main/cpp/edge_jni/edge_jni.h b/Hin2n/src/main/cpp/edge_jni/edge_jni.h new file mode 100644 index 00000000..d905cd34 --- /dev/null +++ b/Hin2n/src/main/cpp/edge_jni/edge_jni.h @@ -0,0 +1,96 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-13. +// + +#ifndef _EDGE_JNI_H_ +#define _EDGE_JNI_H_ + +#ifdef __ANDROID_NDK__ + +#include +#include + +#define EDGE_CMD_IPSTR_SIZE 16 +#define EDGE_CMD_SUPERNODES_NUM 2 +#define EDGE_CMD_SN_HOST_SIZE 48 +#define EDGE_CMD_MACNAMSIZ 18 +#define EDGE_CMD_COMMUNITY_SIZE 16 +#define EDGE_CMD_HOLEPUNCH_INTERVAL 25 +#define EDGE_CMD_ENCRYPTION_MODE_SIZE 16 + +typedef struct n2n_edge_cmd_st +{ + char ip_mode; + char ip_addr[EDGE_CMD_IPSTR_SIZE]; + char ip_netmask[EDGE_CMD_IPSTR_SIZE]; + char supernodes[EDGE_CMD_SUPERNODES_NUM][EDGE_CMD_SN_HOST_SIZE]; + char community[EDGE_CMD_COMMUNITY_SIZE]; + char* enc_key; + char* enc_key_file; + char mac_addr[EDGE_CMD_MACNAMSIZ]; + unsigned int mtu; + char local_ip[EDGE_CMD_IPSTR_SIZE]; + char gateway_ip[EDGE_CMD_IPSTR_SIZE]; + char encryption_mode[EDGE_CMD_ENCRYPTION_MODE_SIZE]; + unsigned int holepunch_interval; + int re_resolve_supernode_ip; + unsigned int local_port; + int allow_routing; + int drop_multicast; + int http_tunnel; + int trace_vlevel; + int vpn_fd; + char* logpath; + char* devDesc; + int header_encryption; +} n2n_edge_cmd_t; + +enum +{ + EDGE_STAT_CONNECTING, + EDGE_STAT_CONNECTED, + EDGE_STAT_SUPERNODE_DISCONNECT, + EDGE_STAT_DISCONNECT, + EDGE_STAT_FAILED +}; + +enum +{ + EDGE_TYPE_NONE = -1, + EDGE_TYPE_V1, + EDGE_TYPE_V2, + EDGE_TYPE_V2S, + EDGE_TYPE_V3 +}; + +typedef struct n2n_edge_status_st { + pthread_mutex_t mutex; + n2n_edge_cmd_t cmd; + pthread_t tid; + JavaVM *jvm; + jobject jobj_service; + jclass jcls_status; + jclass jcls_rs; + int (*start_edge)(struct n2n_edge_status_st* status); + int (*stop_edge)(void); + void (*report_edge_status)(void); + + uint8_t edge_type; + uint8_t running_status; +} n2n_edge_status_t; + +extern n2n_edge_status_t* g_status; + +extern int start_edge_v1(n2n_edge_status_t* status); +extern int stop_edge_v1(void); +extern int start_edge_v2(n2n_edge_status_t* status); +extern int stop_edge_v2(void); +extern int start_edge_v2s(n2n_edge_status_t* status); +extern int stop_edge_v2s(void); +extern int start_edge_v3(n2n_edge_status_t* status); +extern int stop_edge_v3(void); +extern void report_edge_status(void); + +#endif /* __ANDROID_NDK__ */ + +#endif //_EDGE_ANDROID_H_ diff --git a/Hin2n/src/main/cpp/edge_jni/tuntap_android_v2.c b/Hin2n/src/main/cpp/edge_jni/tuntap_android_v2.c new file mode 100644 index 00000000..fb516b89 --- /dev/null +++ b/Hin2n/src/main/cpp/edge_jni/tuntap_android_v2.c @@ -0,0 +1,94 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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, see +*/ + +#include "n2n.h" + +#ifdef __ANDROID_NDK__ +#include + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver then uses ifconfig + * to configure address/mask and MTU. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i, n_matched; + unsigned int mac[6]; + + n_matched = sscanf(device_mac, "%x:%x:%x:%x:%x:%x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + if (n_matched != 6) { + return -1; + } + memset(device->mac_addr, 0, sizeof(device->mac_addr)); + for (i = 0; i < 6; i++) + device->mac_addr[i] = mac[i]; + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->mtu = mtu; + strncpy(device->dev_name, dev, N2N_IFNAMSIZ); + return device->fd; +} + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + memset(buf, 0, UIP_LLH_LEN); + int rlen = read(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + if (rlen < 0) { + return rlen; + } + return rlen + UIP_LLH_LEN; +} + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + uip_buf = buf; + uip_len = len; + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_IP)) { + int rlen = write(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + if (rlen < 0) { + return rlen; + } + return rlen + UIP_LLH_LEN; + } + return 0; +} + +void tuntap_close(struct tuntap_dev *tuntap) { + if(tuntap->fd > 0) + close(tuntap->fd); +} + +void tuntap_get_address(struct tuntap_dev *tuntap) { +} + +#endif /* #ifdef __ANDROID_NDK__ */ diff --git a/Hin2n/src/main/cpp/n2n_v1 b/Hin2n/src/main/cpp/n2n_v1 new file mode 120000 index 00000000..c61c459a --- /dev/null +++ b/Hin2n/src/main/cpp/n2n_v1 @@ -0,0 +1 @@ +../../../../bundles/n2n_meyerd/n2n_v1 \ No newline at end of file diff --git a/Hin2n/src/main/cpp/n2n_v2 b/Hin2n/src/main/cpp/n2n_v2 new file mode 120000 index 00000000..3b70dd20 --- /dev/null +++ b/Hin2n/src/main/cpp/n2n_v2 @@ -0,0 +1 @@ +../../../../bundles/n2n_ntop_v2 \ No newline at end of file diff --git a/Hin2n/src/main/cpp/n2n_v2s b/Hin2n/src/main/cpp/n2n_v2s new file mode 120000 index 00000000..0133d66d --- /dev/null +++ b/Hin2n/src/main/cpp/n2n_v2s @@ -0,0 +1 @@ +../../../../bundles/n2n_meyerd/n2n_v2 \ No newline at end of file diff --git a/Hin2n/src/main/cpp/n2n_v3 b/Hin2n/src/main/cpp/n2n_v3 new file mode 120000 index 00000000..5f1fe9aa --- /dev/null +++ b/Hin2n/src/main/cpp/n2n_v3 @@ -0,0 +1 @@ +../../../../bundles/n2n_ntop_v3 \ No newline at end of file diff --git a/Hin2n/src/main/cpp/slog b/Hin2n/src/main/cpp/slog new file mode 120000 index 00000000..68de9e35 --- /dev/null +++ b/Hin2n/src/main/cpp/slog @@ -0,0 +1 @@ +../../../../bundles/slog \ No newline at end of file diff --git a/Hin2n/src/main/cpp/tun2tap b/Hin2n/src/main/cpp/tun2tap new file mode 120000 index 00000000..887be0df --- /dev/null +++ b/Hin2n/src/main/cpp/tun2tap @@ -0,0 +1 @@ +../../../../bundles/tun2tap \ No newline at end of file diff --git a/Hin2n/src/main/cpp/uip b/Hin2n/src/main/cpp/uip new file mode 120000 index 00000000..4e26bd5b --- /dev/null +++ b/Hin2n/src/main/cpp/uip @@ -0,0 +1 @@ +../../../../bundles/uip/uip \ No newline at end of file diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libBugly.so b/Hin2n/src/main/jniLibs/arm64-v8a/libBugly.so deleted file mode 100644 index f9ab96fa469673cd116c9a6fc5e569cf967a4b8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190656 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 *A6v!S4q6ovTmV^{(wl$)ozuYp_AYFL(j_ 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 Ux0yP&rAxnfp^>`RFPf^gw?=V~`Ma zQ)^2Qw6ywPbkNX!hd#^aCwg?Bzjto1TWY^Hynjvaz{`3~uk4jNARIA9j1w7Rf|w+- zM2?surinZ;L(CF$#5}P;6o^G)i6|1w#0pU&%0z`&CDw>_VuRQuszi;b6I;YKvGa_^ z{)?`z{ZTY*HCE@xJj!hwCakjJtfwmg4?tsh1RiR>qLols-T;8rqDW9Y+Wj` xdJ33!uh4o>Yz>uIZwh*8?+UFC#nzV+>svwJhc5blCUWhf27N#0MtW-1s(-dSY^?wQ diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libedge_jni.so b/Hin2n/src/main/jniLibs/arm64-v8a/libedge_jni.so deleted file mode 100644 index b2a87f1dde42049a80adb03736d67359908f7c90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22352 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 VwKV%yXb*|@zgBQ`Dcec(e*-rt5)}Xd diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v1.so b/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v1.so deleted file mode 100644 index a0aa537a0e810124237f0bc445738ac567818777..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30560 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 KSCL9SiT*z!G=0SY diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2.so b/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2.so deleted file mode 100644 index 0cf303038934ea3d51ba56031b79086398bb4dcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 325632 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

({`L;* zz3|#AS?}R`4-9u>cVqYeMrXYXy&u-QBi3X7 z_Vkgfmt4K%>M<6}d)VJ?RLeVA>-J;)rE}eZzk_=1*f#RE6W^xCEX?&VuXUJSG}dYA z4WZNMA$rq3Hx8l)f2-fG6R;j2rXSw`G5xatK6Kx2@37tmuWgcb9oKa*+=AVL-7Z?X;&ms&mK?xj|btksR~rq(>`PIM>QOMhPYc;MrKj~mu*dUw&g zlQkE;JD0F_;CD#Yt<-9jtgY;^lFLFa3%Sg&HnZOZYa?qWSR0qHHsCii^jT%dU13UIxbl^q8laaB&=h^MDfLliOT*X=*VyHu-*W#4U+YG zuGhnG9d;ddqh!4ny%E-HCF?clHLO=*t0e0%wHnABrdETj6+(xoHP5;pU61ahzs|>b zhH)3qFdpX_#$9|5`*F3b?Jm{O%39mw*vCufx&?m=K5ecQYAKR+l08XsCCHT^SJPd5 z|C;^ryVUYV*5Z$2b&d;vmxN(Lav{SNnpdFHR z3f6XFZ20WN*ku1!wDq@lSg(TDD#>~!*DGPT0=ojcTC!e_UJdKzl657zlJyE~g=B4^ zmYLiZYMEs%6WTQPcEigpUC}2KcBIMT1(amK7^h!)yh%7F%1&dItXtK8^Kk zil4N851C}oWG#QYtSFiawMA3DqFA11f389;A7w39i>)oahh*_*sW*bnkavXmOs%?x zze&#jE$FU7N>mimbF3@!)XSms=v-Rt<{nZpiXKf16Mt`ftoe+n$PzPxFH6h_F}&xi z$e=T6QNiCEEBKvF-0I?IOzh_GjT1MyzBwi)ZeVXt!!D=ljcp@*mi>*ty{S22I?!1ik~#TkoF%kvV;nksm|2Ja@g z#B0@R&J<{USMYbgih-0U8%T>X)35otb6�c?m|MFeJ1_C{*e$Jwi$A<)iC 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 LRAfpz8~y(PuZ=g3 diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2s.so b/Hin2n/src/main/jniLibs/arm64-v8a/libedge_v2s.so deleted file mode 100644 index 5bc29d154f583bab0562830cb1a6e2e8df34c3c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67488 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 TYTIF)zekMygUP}qJr(~G3rNu! diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libn2n_v2s.so b/Hin2n/src/main/jniLibs/arm64-v8a/libn2n_v2s.so deleted file mode 100644 index 947015da0f0683ce225353ec13734a50a39a4de2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88008 zcmeFadwi6|^#}ZHmdI`bLb%@(E=m$qRH%T8ECeJ8Di}~yE=v*u2?+@#0f~qPqBRhz z1Z}ZuO9)z%fTFG1-JiVxu`Srza;bOynFQ3`1g&Vb*%svee&?Clo!#sPY=3>4Pk+xMtpRn{oZ}{za#sct5S%B_G8vd$?`l$21xHjO*#q|cR z_i*v|uz54?!o42XZMZJQ^(?N*xH56Qii^J-Txqzb;G&6Giz^wI`hA3l$7JAL++V=e zgzFw$MY#CeXWooNdFRcEYbdTAxUz7~$Hm`7^XC756`tnc>LVdNlPVK$Nf57<8YPX`U$QIT=(HB#kCmMLR<%NRpW~EON|gw z6#*Uzyao~Zks<+qTE@lTz8lvH8P1dUzsP&&?HLU)Mn1oc`z&0sxEA25#WfHYf9uSf z_`e$e|BCB?273a}dvN_3*DeVkChx=LJsS63@;TCNlNNDAd%jaX{|@&IT!UqJzq~(% zyInrNg8Q4eevRuU2@7}osRYL3-Zunch!(z5K2MVOKWK4$d=A$DT+Kg-MC4D%-JCT&BS45#DHHa8m= zZQHH5sNd>Gdo>T&ZMay6Y?tasJG2NF?dK9)nYglW@t2KjDXwL>mgCCBMVqh!7k~M< zR*NU|UkPrsZ)-FdWzBX^`+YC24Y=;ZrGEG0;Q<+V5clunV%=8a+JdVJ7whO@T>Mqz zqW) zf8E!`HFjL$-;6dq@45P^Uwg7|KYaC#*ydk<`10m!%m2CTiWRp2 z@`TdUJJ2nruc;jEwC-+)5wLNdyH{Nr}-APSXm;RzGWyYJQe9!)2 z$cBwKf4;u(s;qzhy!*cHCF7pCrRe9^Rv)by`Hw56F3-BV;`ie|`{4tF9lNuq-+8p? z?xw37U8!Fc{d9QQ#W!R=I^Z|&%^%!%<;CyhZ~D0ZjN+Y2>9SE%rVgtdCz8`N&y^^@b!|;J4;P~oQ^a& zoyq$8OGthFKmGGyfd=|WNje9s&+0a8rH z5m~M~ye53BEZ3WopQX|OC^{=8{IR(vey*hdf|T=C4ovaeYTk@=34iSo6VN2(vsTLI z0jVcLpnv==fC7-uQ}>!-C5M|OJa>Z$Z!&Mjm$F=^{$&E5mhIyE$cJ_*QQ9RW7rzaX zpHY&|bO}$9@;oxz1b8I;ami=tlO~`>!DYQHly-8dgnK1^(;rQM;y+o+?M#T=K9Kx$ zsWS1E+#XZ%TxY_S{5MJZHBvvv%Y5fZIn;bA@ui%POMOVZ-Gq0Mdib=Y(?=@8(~{0g ziQjXH2~c`sm-hLxJ4|@Htgo}s|DML_b5}|^OESiXlAo8@G2!=)%y+iTcVUBxxe(># zFG0%xUMYX6cE&SE&UzdWQjhlT;qy(F^b4e3fj#pl<)0|!Um(GWQm?kjiIDLoyT(Vd zyoryRi0?@JA4+}_Liiac%bT#@L`;z79Vq!(62i}`vfT~%lZk&)(*IWGyG`nYP4cru z>RY#56H)2IC6Z42uS|HN)c<-}t|m_A;I~BlH;hju{51(5BH^#da`g-;*IS4eb|c3` zY?AoplFsxp6R=;xKLs7)@0ac3aS8ty>X&wYyreJH$Ji$8rHjG|6#@z1O>!=t1;4T5KIf{AQPSBe>ATWRz$pp; zP}2F+Hzq*!j}I$3NIN`7;=d~4ju1T@86n?3kOSMD5mMfPGT#L0zuhG17fE}SdY=hU z{oqv+zd+(ANc<}V{l3P;5PkcVlv_={iFioj4~W2LzNCLfwj(vs9xv%Dy96+_49>ZCSaj#7ki|h-zycf zT%^L>s^s5s(gZA#`v0V)|8%tpmu|FC2C}4ImubS^k#ru!o$yhMOu#k?|4imPXR`@- zN%Gl0Lj5k0{J35;@ja+-{)%L|ruQ=mcqE-+QqB{zO}rWjpCIuslZ+>t(FVmrKA&1) z0xpyAtt*Q!CVsA@(^KY~SYg7IelC*w_R=jTT-l%T68}%E zIQ(*@o-B~<>#~nbc!7k!Civ-N*h1Rx7+GKQLiB&1)aTb`nsgpBZ^ksqe}WwU9+Ggw z>C9f2>0Fjqm|2i_PmT;`mgcO>D@7o)q$H=f^lCii6c-m3;l46wW%jBvXLfGB87Rpq zm4TAd%ve|oSj=NLu*S4R~6?KmM#d?97r0Gv^Fq>sEV}uyMnidiw5q0Dw zeMQ`?HDi?!l9Cwf!jz>N=`&?WL+w5rr7 zSzeHr6|S<$WoMDjyk*Y9qEhNXHlUuXZ4!Qf=)Opbr$BVQ+es?6R3a?XjsYXIN3#o z*_q);2Gxb0B0?qTC>^D*$A$_vC@xf@A(5IW!^DKjFa#xn@L&(6%ys-?*u3HrrHpz^ zNl`HbhBl$fo17b$X_}M&`KvE{?dhn1-GFvvvgsh zIzCG$k!0y)h^3Q{qIB|EmQD+ybXsU4I`M)6(T}mugga4iPmvQUu)NT@Jad%{QwNIk zmgmw}VLaQcb7@f_9T|UkE&UgUR+X}!Duf#W01WQRqP01u8Z#E=X<6QKgmX{_0$+A| z&ZX>ggCJ1Jyu#%Ml3lgVc@>hbTveP?QX&DY%m@HyN#?Q~qQR#r$SFpd`3zpzPSxY8 zGWAFf)iZiW@u<4ud3P7xm{*cJm2QtA1JiS|i_6e`1_v`T?+!q~dQq7Q&L|ARmq88x zMmkQCS{nNn`8+qLboQFkRcrhJr!z~%IZN2J8%~MpoR(LZisl^%gW>!X!Dkp4RNfC2 zNaUsiBpg=Cw3GnijS#Ir)r~o!p(}$U$7#WWH6^*SY<>baXXfY3U6VB{r>rD^Ij30E z^P19}o2SoRnF*E93Yjt238)hig-r^i$;d%91~IyN8pScE2r8`vCPCl>E~BVk7}27; z;m*J`7nT&Qau%*Z+YlX;aI=+Tjk@*Q`85T8?9#i7mO)d@1d4Lw& z|NcV>V7(E4pJVQ#r>xEF?ij#Bwl`qDgg^Cuh85#${(8#sb-COhq~K~Fk=i$;;3}-f z@d}PFPsLKc-Opza<(x)eptI zga%i07mQw|!Ee{_*JfBs*)2Cwo%@vtyZE=;NUe>M${DKG!8rv}H=ng2IHgUcyT5tpFB zclogmBT<9jsll(*;BrYo#7@-Uaw$>39U2@{k^Wz*2A5OJB5sZbmrE=HeuoB!`SSmk zXmDx5L|m>0U*N|^yVl?rYw&d%yoUxa*WfM;MfuK*LYa-~%;yq6QzN!LQWdgEja> z4L(GJJ2d!E4W6pOhiULR8oWV+-=V=vH24w?{!Gc#Q@>tikIv_yG<6f(AdX!Ce~MsloSa@R1t)kOr^S z;72t0Pc-;D8hn%nZ_?md8r-A7vo-h^8vGIs-mbxCXmDe3K>sh*;5H53q``Y?@X;E4 zfCf+0;0YQ$NrNY9@Mkpml^T4t2A` zzDk3?pur!~;4Te5R)g=?;8$w!LmK>Q4Sqy}@73V%Xz+0wyh($P*Wexv{yh!;g$BPy zgSTt&2^!px{vQ3hH#N9TgHP1pJvI0w4L(4FU#r0rH28HIJW+#Rufea>;FC4@L=C<} zgF7_%dJUec!KY|&_4vj5-_~z~n;rMw3}4TKS5zlN#lIDwV0}|vBJO_?*J8$ra0|jw zV+F1Ve}eD`fB1#CR)nW%;m;Ay(!yUNyh#gxgK(`D{wKl*weYtHw`k$089Z$x;67EVWanijqV;Vdnjf$%0Rd^^ImTKF!64{G7X2)AhAEQF)3 z3*^5H;SpMR1;W#`a3R83TDTbDOJ*8V#O#Tw-qZ9NS4>o}@}ao*kzpNQ+ab5JYbo*oW&D&nGX zqy^(`7LyL?2hjrl7|=?$#KyG78}6ofha34<3!bf(qi5G!>(3%wQxV_3%NpNaSK(~$ zjGq-2lOMaa{Fq^}SJhda?H1e*g7+!kp4)-3;p*1&@aUC1dU_bXrXCL8+4U*)=d6~9 zJhcFie5o=9l~0pZXS@ygj=XunSE41PUQn(Wlwa{ukFpboGN=cC0w3wfr(TzozXS3Q zDrX9GpeuC1iaffSX}ngMC+=RrNbg*Vtg8y+s0}i1f-IV$FXS%?`Ao6c+9+>~?M*$A zd}EHM4|K%T3*@8n(D@Q+WZoX&{6p4@Kko{eH}v)F`l$M|2vbj(ztEEibcODAHQcS_ zNtF#c>epYy0Upp_jfYd@L56i+(?JXKkA0S~-7OhWZRt{;f${MR(;OqKF&=&)d;F;C z-Dl73P-$5QsvKw6Ppj`t=aqgby$`KF)fTr%-52p;^#6Y3eH^>v`$;@fK~hM}D=7VW7HZ9WP5>Fsa0 zy@L%mW(WGfCb@0c3eRWiwr4Q(#~R;2+&bv32X@PAjZbD8fj`*c^Yk*fRkn`@&vn*e zCQaCzI_u(g4{V)?gYEGScDS36)@HHiH}w`eGEc<84%#fnX)ns+1zf;-Lq{y)m83o@ zy)D{^^MI}w_|$*!;A^Ek5k6!XFB6Y>(q2+lm{VYRg#79%hJqKQL0RmGOGdeA6YDA# zMdlH<7JA%~N5BP7w8P(l$2!R)W`l>vXSyL?94f+@X1J8bW0WNrn zb+`{%O?goUIMkz>WwYRZ7-em-+LPZpb8g2HOFLil3X+qkC)6wN)HT*&3~`WN$x_IP zI3jQ0K%S)Y4&={tkiW^BCV%!%It}6rUQs{HN2T$|Fm=lZdWql{dgIQ+v%rVm*eteK z$jE(%$d5L6aXaf+={9XJ^r~%_tgo}{Z$!H{`<3x%o9AFdX+O__E^VX7O1%!Y)#+^G zfRQ)aMCh422|7nzr)^=HuaJKe;Gk#rS(Pl`r5 zw0o6S!0fW$LEpQ@D*MCk;92$4h$sKF9eUZ79c3R%ergckjItS)DR0qkinbr(+mHt9 zg0_c!gWlJM(r zWu9X8*OadTe*FEigrAdrTKt>FYR`n7gX&mD;Gz$5x1!y}TFQ^D*bwui%@R`;gM1+a z)|J~vdxo^EYd=k`e(NqO&rp4C6ZHdaJr8Xd@^jm5hXy5Wuno2w_Ixko)==SWhyJ)$EQ&I`;->COAh=K}QxDS z?<0qzommav`~N(*L$nXJW7q}yuczRjY=xbn4c&)wGM;uL$i`@O&bCY30+bE?x3I&0 zn+RIEO{7n4Pcr)(JIXQzw#54^{2|RI(yu2yF$Re<`AtH3V$j~xHrQcb>{S+&hw)J; z5ARl#r;cSo{!MIekV}w`R$Q1({Dsg1%_eH;lpMZAK0$V~A`14_4tpCF@mAyGx9t z58!?rICa^^(K_qUc6${35AaY|F{B;-Vsd@T5SM4P0eLQL_l!h6j)V=2HeO7yn7(0+ zby54Sl!dOA(da)AR|8r#@Q;KKrNwa$fc@m35KkXO`B16Izpi4~I!_5~qkaEfwhcY! z*6l`k0{tFiHRWV)+E?5PUee+=4@v?~ed90}%drbQN0DFnDEB}vwl2n1nNcQR+oilJ zaSxJJ;-#jnV$43kFDvMBnIj#ZFqUB3Li=fB|8+q6TxbjK zv+L8)Z$=5<=q==XrpGY!!DgR(u5tX)Pp6bm{^Yvy$sbQBpL}v$`Q#I0%O|&tDWBXt zx_ole$nwdbK5FaN;_L?>X@4=>c7JM!7v!+!sW-z1FDe zBuiAacZ|j79oeNiX`@l?9c}T|!;kTf1nd_MU(=)eCpYiFH5YQ6T|T)LX?V&99wB@9@84tDgsfk_RLEM$194~{tCe1e_&3dX;;T#4#aCKg{0%(*4Ki!P zz0H(=lhUoPz$;)cBJZYu7(R|IngBb>dPSHtJ^yg{yeK#AV9aUf#PlR%^+u~4zp>t} zmO#Cqqdbt;zi|IoNM6>dzGlFF#Jsv%%)9`5g?S+?^6EO(pBLL@%<1@ve}a9jq~3iz z(`Sc1+M~^Jw1B;9!VX(ZnPDztn{npS>O{2dD66Rpp5=ynD)QKjxFq0vmOI>u7PIZ0 z+~@EKJ2!oFwQUaVC3I(ZO!dbo7wo3cpXRX+AMB>jJI3%mfYWL+L1*|)qpJ@gkEYqQ zt+wQrF%DlU%7uM5eLSzC{QWJ^k@D@H-q53H%mu_pxjnt7qOU?*iJdC!9JYDRW0{-! zLoV^t+%15gYlkcbTYT7e=7%>>UVsVt3{O?7{Y@}eKEW_{W%hFSJ*qpM>?*<+GDDEmpaop_er*3cY}vg6`7dIriaWbPF* z_q9SF&AtWcdPDDf7`|VESJ4*l7+pWostjTe* zz3qV1P1v<+_Iqc#PHX4f>f@jdpZ2I2v%}}24fjI!@RN^Ei8D@ncA#Ik8oonO#stwe zs)tv%SslKZvOO+4e3Ar9{9CLu^c8OGAL~;mpS$6?Qa*D&ELT3W4pQZ_Rl~vjYQVQn zi9UMfNdtXN+#j~MH*9f_^2yDyX#ZVdixi(nPhMYRed78yw5ew* zEJs_cvB}=9hVOppTTNqs*Ph1tE)V)CyWnH7=!4qO2Q@1@A^MsI4xTAL*rQ= zjpmqVGvq{F;QV{b6r-#ab=)?^QFaRXq+7aGwZczog^$z?Z9;`pEyg6&m)irM#2a6p zfx3^uJk%slykk4|Fto=O)Fo$&l& z=b%)Mwf+z2K*t0f=1<=jtLBJ3kWW;X@?$C3o|nCDw13W+ zeyauflec7y6Q^5jG2%JeF=>W+wmT->sGhq!Ce2jOagIsp@_9^O$D~|7!!{(tHu9cm zH{7Y`&h4Nd&wez>zfIvhXcy?br5bJR3)>qreO#}|!*kN%nZ6Zx#va@+^4&9iH{qE+ z`z}Gp)_}Q4AJ$uZtiw|%^TW_V&Q*NYf9IepphwSHE{=IFCEg|Qp+_ySBRB)W{eXt| zIrLHBStTCI&++K`a5(Vko=b7M{&sF>#@`_S%h6Y0PQ&FznEF?T{~i7 z_R;Vq2pa>uNr@tieTlF+2yZsS*avBb51V1^-!#L+lLUTG72aruY0FIdX4s~}naKj5 z{ey^q(F}8~$Uh&W>6@A#p?(AZW;;Xt{J$1bm4{11!?pbMDC5py2!F(mz*uDuWQ}!5 z*a~w^RQ2^-GZEv13S*L}qn}(}&Ay8LBW$bt4dgK$X`ySFe^BcJGJc$VL$!ScJHAlZD*$+x5e42Y=*7Pn*w{7mpf5U%XBP1{2P%! z{fT#_kIFLHXILhwa&kO}{;N&(qviBZ4Ga95!1`>KkdYNKip9Ed$e12=!?i&VY>y3V z4s3hWrx=XKJy!T#s7tId`CfhtfAaTD}Y zj4iY{`fKcqJd_LCAjjw|FKtCL_}Gqgs(kDlAmg?stKmDKd<84#LS|w8*(&^mWR?$l z$N3D*i3%Hn{?NZJk2Wv?_SS6cGM?>;JbcZ$6~y`HGOcXuT_LC7^|vOLm+L=}RWr)g zwA-k@lI4T^WL^1EEpj~#G8A?NxT0LZjRTLw{Ra8b=7kxL2g(PToLxT?`B$TBUWq@rIKK1_qpXD`%lV^-8fRl*0;5i<)nP|-Mpx#Bliv0$# z6X}^FsyB@-&k%k<)8*B%SC(gB%<;w6v@87k4OoBmjYD0nkVy;H;yACzeGjL=&y&cT zYn8u+J*;V5mz}fyg%vpA#tIaGE^_6-e_4R?TAtR}ijHHUA4}A9mFr>Dhh&V8>DORvJBfGY*R!u&OH z@dM#I!IwIWaVzos>3~Pt9H;dTp{;x;MLS*4jxlLdPdFby`p`@4kk8Qjo6!E4W4?Ou zNZC-wlHrdvq{L4Y&lpEE%#EMOxtNCR_=z>+jHC3U#M~&#d_QC=+81c-VVNzlZJ^`! z%MrFh&-+=*u`#fRf^D9*o9%&X;%Yz37PL{uai7D@tZ&4j?Qf^->S@1HhPiCE@?)Iq z<-QBC&X2y0ID!Vo66{wfzg;PdUA6G3IRDTC{L;q6fF@;KFXO}<1?HyN9;xqaTa+#9 z#}0X`8#&{QWTI_|R36p1>E0)&zeT3D`-rh z>6r3WSfA|scA-D3h2ETi-z01>>WTXvI4-4riM45kaBW5S zKG63lWs@QIdi05ew?1p`D-`L_4pQYl60Q|Zr45}owz@XOIQqoj#rneP8fkx__uHvE zlm&H^?E?MMB;GMzsV1LduMVGq$9^lxPT$b*ao-5{<8-iX9qfBRHx43y+IL+qY<7o9 zH(IvIU+x@~4!sb2;E(VT3c24S zrR&i%@6!hwf;ok*+PW6jC&oZuN5hvHiLyfGUaXsldSm^e{A{~9Cxis;p?VUPiL4kSl4Q=75ik=xu`S9(K}k`L0eW& zIp!Dx7~nA&r?tWVPQrcwp(l_%>3DZzJzzvB>pox|rDi~Cs0 zFR;$lGzEQDk;C0G4t_b}E+tua7_$YU1r znu+^NGp{Dqx6ejifW7<`Xw8-L{eZnm+6W8UbCJewoNnwY=ciGp&B$X3`kUECf&Z}8Bc;P%S7Eg*&{?Z?!bE)$iKE2b5>r16o4oQ7+QM`jtD-KFzsS z=v-i~RrHw)>(9K;aZgtnEI>K9W@V?0LgG$BCJU)k zh!ZMHcNtiVA zWtwMI8hdaW)=y|Yu$LmA?O)1#EJm5m+n>Uu!TV~$*AZ<7JbLn_43|TO*(irotJ4Jt zF9*(i!f{9Y^~^P8>950l$TAysxB#-8@9_PLc^1h!42e65v~A#(@v08V2fkBb*5lov ze>d_e!M()H$8T5GBOkzaGX4G1t^oF1=7+GLcfUjUc!^hG?i6hUw$RPCCE5m_1Mt*|o%uua?}0Xm|+(O*(+ss*%8bVZqg&+%S-wCS&7?rp+3@ZFbn2Kwv|lMv7T zK>2liM}Rs8|4jH#@S{W@ZbyEk$1vAKlE4#T$>5)B22GHIe;q)UEln?5yiwK~? zLvPOEhn5dx#7T?~Ej!EFq5SY2zEkVjqtrk-rLS6!=XGa_< zvjC2*BMx|^Toq0SxpxmE_qgvUcdT*ha>u)~L3)>jvM70SKAkd6A8J#wcXuZH^vOL1 zUN?)wy~UJ&Fh0tsXbZZsP9x%@ygEMXA9d@Nb?c_R7Ih051l29d$nchMb*uUG>{rzL zK5Fk8{W7jQrn8M%#GcUYs$JB>ujl$I)==B`!uJ>c{$SYD!REeOu03^E<3;%IYP`7T zv^id6pGRMOmyA<=5A7YxBF2hn&-Brgkw5CcO3Wnz23)Kk1^jKy8)7VG&SBF3Z0-+R zh5q{l?AA&4Rj?(rGc1qruhG_4z}Eb>afl1=pNsba*pG`fR?yD}F6yMJ4fq_taD3c= za_&JnIX33rt2(SFFb(OQLRq_olyx`aSDmM#~QfBh6i?d+uxVj)X12*hS5$TEX95 z8UGw)U5oK?leJsJS>(AF;mT;NUyS5l1$zu>30Rziwi~dRm_6Bx*X3Gl$!46HPc2}i z@v9Kpw_rbFt>xk>#&N!O8{(lWZd1SX^~u28all6mjD1_6ZzrH{Y?IV8j(6yv)nm?w z`mNRnIM)-8JnB=N6Jc}p@o6vUnG0uEVBh3o(I!-y-oO{{!3;O5by{j4$ZsJR#@iu- zq&TCOJ(}-|$Z*o&UiLVnOr%dTs%ycET6^N&LGE8fpUm<$B!Le3hYfMJ;yniLQDZ#z zvbyL;psl(BJ~rp2u%{0FzyUQ5g530ZYYX_+=f#u`(6*>|8<5u|&Ta5rLd;2vcd>-e z0$TCd6U8}?! zMeaZP$=}ZHz?m3*1U=MEBzpZddR#MRKf^gjvwaM8>3dkkywFIrqmjs88_#o1WLL@} zS1s0Wxo`DL(B!-m$1hyJRdK2h8OC}LeaJBEvfZLDg`M@m zrf+XRzqki=z?zo{`PakTa9EJ z-sfPSnF!y2^T50FWcnTtj*h@X;1J;3r4IM_y*%p!K^UeIN5rhHfc) z$3BmJ1Lx{g{no-hV}8KR`9;1beG&8kyqk7R!=vvr0{;8O3*x#gGL>;wPokg9p z4^Ky1pg+KOz=QS(X?E}s)&{7fHP{o<410k!Ss&+~Pof__2U$13PW&f2`X0*Asg9y8 zL{sL_EprZhVY|M!<2_wJMfsth;EVh64=eqoUc*;rfBff8@Y5td_l$DAh4Xf71Js@C zJ4t6(dadPC%DPeQAe65#_*^G@wv#-(u(2GIa37)pTcpe2#}|-}HjL>g7t)DEpWTf8 zje1$FozUUf_A<0Jj1yz_K(9!L`ouL6otIl8l$-izw&#E?*X?+s){fPfsDmBH-kN^o zQRp}P5Y3L$HnIHSZFQp8^=qbm4(abYU9Chq<$cOrOCM11l`csMW{WtX|5B#1_ ze;#9*BIr+2BpE}`4u{c)p^@;ObB@a)`$)c`@&h011c!Ep{$y1M zPN#MFU-lK-!OQvTaAZgwhWd&nklS}@r+biRB>Zr8U}q%!|D$@p|2*}c9a3L@-wOGw zI_=j9PE=n<+1gIxx1gO;FMb$-4~|8mHaaGS#*4Xlz^Cw?60B#ZaehqB>o6`2y2Cz) z<-5>6=g@z-&shjLoKN2#0*-DoLiO$Kw(q7tJxK36^dl*q==0_<{Z41}?Wlv$zUA&t z=*OTwov6=N)Mo?gQ}k0|XnYxoMz}Vi%|Yw)&zL9Z#W@|0$rCY8WWzjB^F?yc0Q@!^ z_ARHVF#1OBGeZBw`760Dg!K-F;a?@;J=7$;tIB$_N1N*)oZo=n`OXF(lB{v1Q;YYm5hqx4VBs}PTTv|(N}Hq3g%JgI|W*H)l| zspJE`0>`Xp*K1>*iopE#A?258a#He9b3S{m!^BxcoL3GfAJsOLZM-53UyM`o8R3^t zeEWXPP3rT=YM(px0d^8;9D%*-SW{Me@TgO)SN1Wlv|^2%_5f+SM%{D~tW9Bp8t;mZ$ z4g7h+u3(-9bz<%Vcx6)tp9Q=(;IKEGcjo(5w0&vNCCocQ*D*evYOKaQm7qa<@<3bK z(74zIyjb$b_j|C9-3&`UVPDUWgMF9hrGx#L=f%PMb?3#wdw1u>8F&FWLoWbl_yyox zasfC=7l3p51>jtD0XW~g0Gvq|fHV30IM6B4w_@GZodo^D-bzy!sc)0xlhpgW{&_fZ19t!;?O}u+X9Z&rBoOnM;&;c&> zoqME`FW#2XYP?Xa_8BIfEjph3?aqv(4KagZBl7D&yAE_u3H)x!Jew#VIC&}_c_m=K z8gbYb5~pIFF~!WkE(Pr(^vns&p&STW9}BE0PJ)fn*KC#j3SF-q47{NATFq9|XYudN zfxV-z6ayId;hci))7R)vp+8f5aycihLJihT>*7ZO9zX1NpDOK6<>n;i|+t!O+)U+ylRk{Y#3|1%IX&{F!_Yct-y= zfv|Y^`JS#j2O%zlYht;v;vJ5TxK`lC1>@RcfQxq7fi7V2!-H|_Y{0Dug9}(F-PEq+ zEetMTp>#db7#CrGLMRV}h2mE7eJiYUbif5H6gQFYV4)5=-~twkdx&E*)Vq!=-p$5b zHT(n-7k_}Z5^@I&<8e3VtvN&9#W6|XH9IG!VqZ#PbNs|)g_mXo z)5W=V;ph(4@M$}QZzlUjzDE>;yhRz|!`duePG_sU89r-09VyM<`ECPn^l~IhTBN5g z`q3CSS93jxeX*XuKW~;BJ~r#9^4oJ_Uog|_xXIXaLVO*j_}5_yN7aS7hKTVCY$0u! zdPnwv>RTZLy${Or(0=j#-)`79Vb$J!;QL=gac;tp_FC(Z_T3eO@gC-2v6rj9!d!!@ zs~8j%rVeu7cb#=XyJrmV3$X_b`Br#CJwTaK##b>t`Ac$a_gWvo`Ap#567#y^y;bnO!q0nypZAzHp4r1I#=~sqH=N)U}Cfa4)5=X+sy9St} z2(mXPU~gdGl0)qc@pOB09qgF0H^iqMgI?2)340^)IroKrvYqXp`yf?&m30zqZ?HZs z>`jC;!rlN!@F(*NwKpD=P1qW=DPe20y#2O@ywTQRt|rvhpiENEnl3Xhv{kGZquyfk zo8|cwqRug<6m=Scb3mSnAaF3I42QEzzM~^>Fs2NLv(evX!4Jli;cznb_BT8{j>Bf^ zBGa?%eqB`Jwa_QN_bc)Ul{aKjsq{dTg=aMA zJZPMT+=LDBpp3A`t8GFy@Essqz0J|LQfWM*E(2{Y250b5_eTH+-;eUw0c9xCT!J$^ z0`=jtL8h#4)6iMTYJ*k8;|Q{NR#PVFRBj?wXL-ML-G9! z>Ucf+Zra`YiUsY+8|~#Tzb)-BcJCVc?)pvG?`NLBk^TwC?(}Ipo?9Pw|2b@)^kwj_ zF8cZ&2xAOq2M_dD*_QdPqwp)hC+%K(8pmw1%>!mfz0v-PxEXA>G0C=j9giwsfqg)( z>`!1%L|>%aZDC6xCqW1KDO*b0W!jTr?aG$k0-2fh5u7jId-Laq^%vEDl~N~3$7;S0 z=1(i^t@(bVh(BvZTY_(c^01AuygVNyl+X0Z2F~<}fq%`j)9J&T`#3}KSnqmy{?m9r z-;WEL)MBzYwYdC`t12-{5AP`?xHscmf2q2&;=5b-t{k9Q9Qk2t#(G7jaD zHu`+=;nE#e_0IBHET>PXegtwBIzrwU7dP#=;1_d9o$}jV#xu>?8ON2LJ)-nwBi@PC z`eO7eIFG>eegDsNX+s2E(#uo^r3^sQHDID8~djGWrY0}I=e{m&o&_6 z>17=VSqRx}*e>LAxmJGrf1zwcBb4nsmWO5CLwTUAnbL-AU>N~tU(a%JPdv-0>%srE z&W6*;QOK8VOI;VD+nwpY*-kre9|DK+6`0R!!?oh7ErVJS&pdF3k2`eSjTeM*d}pK!?Qdh{ zeu7Zhrk|(3wM4;pgS6nfUuK&z{R^cdA|I`vf133TJ*@0v>bhPgrT>@e z<$z7~%Cq7GtuXz6I2wIHVMzA@N$d|{X8Lchjv%#xAOa5h0Ju>qkr`KpnHWp zJGZkJV#~wz34@h?OF6+$$@cpY!Tr;J>Zg#u3z0)vh#c7dG4=}5uUz1~A={4)eouU#y+dKMh z|BfvF1^&Xy;=kxu{hl(>{3_0?(vJKme$|EO=n>=-)K<}dsPWuof8PU+DXdj&&7hmA!vf`j)a!p?^l-@^$!%4JkuistqVTR`Dt?_CvdL z-xF(glA{ehG%ecO=ynTGlEJfv{(TV%Y*D@^(Z8837!Wl_id zA6Q#Gp!klZpBvb7=WeE-YaGpmPsa28uy+mb19BeHhI8w%zKUnA-`cVF3h#Qk<1JXP z#lG7*uHSMmC(c6Wnyolr6=BYq`OkC>JwqS#;8Dy$688P9XweVn5e@Myrh zoBEx|F$j2BqUL}>!-#YEEOzXfk9PR1i2t++`4QgNz_~T1oxr>NejLoBH+V5;_%8Xv zI85*XT*{D_2leHd0DT#U3v$9dsHyuCs3XSe0y)0)j4K!W{!ou`Uf?#MOldra8FFu( zQ0~TBUR7+LO<329O}6JHPxOw%H_FEH-Q?K(T~dcdUP$ZDn|Xj9^FIlHJr!s0+3$4l zOlYzHYCp;%W~i@#$%Z_F!-%3+#Ach*yaRnv_s5m zueMz*=kXEdezIhI&o%v-@ztq$c{s}&vZt-F#=CfrwZs>n0*xQw9JJ@-whsEUJvF_D z#VDQ=Tb>cu3t>xKy3KNNx@{=t5U{?5Vj!5A4mXO0-O$PI8K zMY4xyDE7nmX`{7$1UTy%`vf+FUVX|S>@UPwAJ&1cdg~xpeac{5ce&8cR@XNU6nhiv zQWm(xcpU4kHI4namsi-(I_q67j0IMENADa|4>H_`LNXyYBs0&e_z@?3>gI?4j9?z@mpcg#%koJ^tKi*G_)v0n0ss=i=%X+7) z7WH~9XyZFJt~!LhjmFjRcVg?HZ+;xetiGb3>q_FKn0WOSx4RTxT?+Eetn6LKI6OC0 z-08wzq}V#r#Pc5L4E5*~^eErnt!fMSZ2(`nmY!(u9r108DtoImpNTZxs~WU4Z-}{@ z1t{+TT)0=@Ze57HaZkbBIskGCDLZZK7}+ksOP#epaB)@O!uNFQAP@0fkZ8wt%Gids zRB!FqekjqHmk3*I+c>UzkM;I;{ktG__y$j?t*&Xj!-eyfu@>65y)LD%Yr;o3KPTlj z$jV6P`37l29NPmnEYDRB+3W#7`DO8Q6Ym@YeoUHsD{gDAgzYE2F|Y%CZ@qOs{Euf1 zciV2mJsfmB&%*9Wy59LX$H_jTD%CO_eXmLLv)vB&%Ch)zsdrwE^36v(w!hF7DA2kom{zn&>y)rf!Sb91K65Dpt0`0ZVQuum?uS1M`gl*F*Qxul zhYtnlxa_$k0gc?CZF zJVjrWx5RM&TH%*Sd~1JcZzGf`MV1LZaoaeQ$!WOvDjLo(Wf~{*L^@HX1vu|R;V%eN zCivEZN8pPx%{SbSDg60i%B10oGR-yIl?s2Z#E(!WkxzwLp61!u6Fd^-nPRxtA-!ix zKu4+j+_NO`8-YLD;l_EQ?n2^S7mRlyZR8Ya{Qx>r$GS%T{&s@>L7(*p52MjmuwVFg z(jOg6KZpo8>+?Nv%J_qv_ZBOKV0c{VoRNnb2Z}^M&R+D=GX~G91O}4?! zp?Slv!F~bv#l-6xz~lHh*&eyAvOn?nDYEZ*7VA68?@{Xz2mF4|?e%B&;JvCw^E+g{ zke|N)+lKQY?0nY%|p5-s7iY-2D)~ErxFisP~s~4h!%whQof=DIfCuHS9xx zjL_d!kw-C~$7j%O0F89eXaIfjZE(`$SRORt2l{E&0x8Lec<9QH#?tZJ= zi*c2B9=u7sx660`E#Tn^;CFbZvjV>BZu+i$@y(N9-?eEB#{Z*nZq7`cyO(0PpSBKa z=NLN)d~Q_ZoD|rUE^6<_UG3xrKA0GjdB!*}Zo`nQ``lg zQk1o~;rk29p~|%jek;GFu!Uulbqu>K&aw`zYw8R1J^x@xeY37P9-$As0`m*3W3IoR zuMD(lqQ22LaIc-pKT^I?k@7|P^5plVq`%!kpFWrJ67kU4I<JqQ)EAziL^}ZgwP6S1nowuWs2`?z6yZYXfk=9MA5t4rqtJ-`-&D4;y+1p8MgtoogfhwhTW4`}gN# z|NeaJ-@m=RKgw5Q9cZ2fsKtr=VasEge=PGKXyzZLjy$3D4;hL22Y<6rSGn+C!_^Dd zj&!>~nTmYTPrAXEYL87_9lj6Wk6dTT#Fh0$eYzB3(cV#itP?x>TZSX|-?!DD*^T}i za}<0>c?8mn?@vJfI15+2+lKEy!I!|?75o|T&ea6@j+GT~&MAXO_Ayh?H+j37-x`4} zbEDtoyxatS*NydBQe%NX27NH>66ZN%;9tOgRK@U}M)U`##yZ?=EA@DHqoHDO zdmH+(&(M!?Kc^QytrvbC`~JXryf~K)`qnZUx{A21r~~z$KHuX|aY|RqAvd9`6?jh{ z`NJNIepWoA&*e8(TE;lseCG)BgFXlGY1_b`Iy;!>39#SiJUh<}rthTo$c4VgAK;Vc z)S72W@QlPP!DoECT6a)!O1ExjzK|(>4Fm1|?E3WjbB*R%lo8*x0#CcZ6Te@!8+_46 zv2!m0;9S>hXdH_1Q!s2#<099J;W5b(>=VduQx%bKDK6545v% zev3}P`p$8;LUx2hr|Lvv?Pq)Wbmc`Vd~)72-7e-$gXq;G9qBQhU&eOWMacYV z*hNuakWq*FiVm(XfoBg>|J{M7)&Ex5XhpMwu8^jNt7vw}n>00DvEw|B3)Pj!^*TUa zbqwpeqSdXYD{(=(qSdX3`axZxeo$|yE7YMdx~J(%Fg>Ibb&7OKR|<7L5r1DNd}_K9 zL|3m{p&#H==m+(Nd{T$P@Tuua5Irx_Dcy^xE3g3_>Wel&t1nTnumK(FpEf|Ne~|~| z8~Q$mkU7?tJHTi2Y?8n`D~asqcglCo(2wvP9{~d|9q<6-dUXf5IPWBc<|7?xQof;S z%{JMQX5EQJ>pI|mwP<1}jO{xdEG(b%!<2nrM?M2~`fl*LBmAFZ zHP-lcerpKtLBqFz{{#P#d+q%581lQE@H38aE`@U&uk(Fy;mgVS35MYl=r|3Svk*8K z*K@uB^&`ID$L~4fJOcVL$jjmT<{kJ&jqxt}@H`75G`>N`MqwWg8fVbI6z7X@3<14le}C96=Qp53980LV3mf*6!QV$c zoA4y8Lj=V^F2d#@O=VX}gZc{Jlix`Y-$dwc^zuI^8LR)O)=5*G6K#tuSVN1S7|rrC ze1L0e@#feZVahuhJhUPo+98$^`!6ODN8oShGS~l%eEiS`}=ACa26K6jSl;Vxt|jl1B&q<##Na6W8da;VoWE#f7uK6jPr_`9ZWZ2 z7}J_I?ob?XICj%;k_kgPn?-|Tj2i=c$aBV@ZHyw-h^>kwli?syuVXxW>{$k_s z%`CudICG8PRms2Pz#!~v@I8n4=kV>LJ<(=-KF%%-g4-2*fFHgW_*LDFNvDv0Gt$GC zsDcdeK9xBZwPA0L?ZNTl{X6CtX-pb)rVadho^Qx8>8~Ld&Xq?RlfH;Dd!WO#85r|s zaD9byiQ@nlV|mCR0b_a2>kdaf;OukMGh_job3Fz6I-YsH6Mamj1FGKmos)*fAuh9D zQ{U7H?9n?{!80VfWBxq&3<>}I`AF#N6zD7TR>_z8LYaF|4(`Q*U*|jAPws0Qjc?|u zXYg(7C)+-By{>Nnhcr+o@jem1Th=@U`UxDCYc$IbI@C{LgYZoJ%HA?Pa48SQH6d^6 zb_?c^PBR_z++dlj_K5Mji+@z`spgp`6CgL*d@t-(y?m$1gY;bgd`Q|c&egJS6ZCmq0OAIL=Nioah`vyZQ*(Y7Qy1Y+)B#7Ak>a}*<>8!xh@-zg z)L31q=99rQeR0)y*%JbLZR*g+cf;H~zAcxp&W7Ok%l&jX=LNcLobw{x;l}Drbw(-Z z+Rx5`J_wxy+|J!WnAx+qr(icO%hWa84=Sowp9fdfO1p zk1oPo4(^!G3YHnaBeV$ZcOlyE!uB^%FG1f-k#TBH=>YYhD`jTBYm4E#Y9ILF`DaaNBh4tc$OmJz zbJQEiLY%>bIm$YDo{|mUn!~<=NuK+07A$-VFYcHZ%-EBJH8{(_;=H&m*dvE|5PYW% z_ZVRth`Yhk+uOs0G0h+GZB)#02JnR~v8VIBD70C(4c}oC{WrezCg>qP3Ey%P&+OL` zFP=#o`T6HDSoh%lDC-{W!3$by+}UZFW}{5AWtnjAv`p}!1+HEur0Gzm9w-NSi`B{$ z3*J?k5brM&;i^pJBSM*Am))o@^IMKqtSvsuwZ-1`XB)e44p)39lD3v>+}OwZ#a8T% z?4D45><5h!uxl^u#&Z>e+MkEb*jF*I{RQj5_7|~sFq3-y)llp& zSnS%Bve1>n@Cg~VE_6*{__z!=E^uAPaO2R4d(pR5S};dZF%-1%9F6A``E19tRX%se zbK?;B;5_pWd%2)nHuxGmBXBGH>YaEe)3amepuJeTu#Mw4*3r)%;9jIVg7+d}3@X-^ zV6QL_hyK}tzMpy-8&gxU2=hbG`(Ue?*OkcYMdZ~p zDo*6Zy)12y8165s(EsasR7J?cs^#&B%%idMJh=a*?IGk*VYvUG=TQ+M53CC*S$+PH znFnmA>oUAURHy0%dxZRBlN%s^(ma zs28M{Sx<>$RQhN`ss4WmNaxZ=sYZ!asUk>2lORv z3k>(2q=7y|$YFt`5lIdj4Izj5m|ND<&krL9y)Lx$LJo5c_ar_2+%R&G>4Vy7$|4uO zEsOm_-T3YS*Gb){W*Y8Gb$QG(X{q)aq!Y8HEYRM$-seeyET-W5F-)H#WdZ+9Z;PtE zKX1LO{jjN9?&nUhuDko&;N{S_FF^Y_ws-J&mEbWhxfOnC+gQW>*%-rpdbHs_^H(jO zF~Rvn?Tas>IzxP};beDs?8dVb?s~d)tS2syz2GsC@$aTh>`2?jBlfC|$L=-Okv&W~%OdLz{3`ySBftAxms$(3=F#77%B6gKJM!6k{>L1g z_R%v$=kd|ic^%<{y;kN{wPuy`cjD7-TXO|_sH_*%9_r<1x31wGe9rnn*WbQgU5vkb z3;yoSXJw6W5%s(GdNoe_yIrMzs{^d8M4;MK6wi3Pxi@?fwbA($0Dchq@9AkC-Pg5uZ6#K z_9XpwihhgkGwH8Sh+$l);=t^GyZYl$oztR3arf7duo$;I6zkbIW&)LmWJ+^O|*uP%RWZ!tEyDa?TCT!O!bZ&K2S(>+)Wulw9OuqTtu!J(*@9A*A|Edz*75$a9 z%WVEWi@XJf2*zqgRS@{NvoQIaVNuPOMCjAG0YJR}(sri9#Ig1U1Zo{nC(j%!CVdM4v zfQ(3LU)Ozv`^#MSFAa{QUg^5e9TrI)AZvKnd1~TYVmsxWH@vu>CvH!d{jF%6@HUh` zk%{=nLNEDJ*hA<^tQkI6UC7+@L08`2417BUp90t;*I3oIKb9zSo&61Wc)0ih%AuVH zW<6UFc@Tevn8JbeFI^Lf^}Ruf-N-wjF7Ww@+5I&RH z`;@iCeu!J!!%eK$@{gNZ9i;3t_EE*&4Q(sxCPrQ# zqsGGNvb9F!6~@CQruLDLTLY||f9^)~S>{0T4YC-Eat_sf<|UQ5Ki}F_ z=LxiaKY*;aCUQnq>43eT)Iq=LTUnzR^xYick>4_ol&(oSeJA_t*EzT*=1!%5($AtV zy&OHH-s9+@)YTsyRCOX-=Cc+#AM*|9)iXa*HfbUQ_nDQ}URUv)QUdEXBVxVL{aw8; zE_*9S$6=FL!=m5CO&;mnx`$=0ePSGSBM0^n)H*x4EBANv9f3=o{h`s^`xzsHzz-td zbfZPlPG#-Edj*>A5&K5^)!?rtFZ*Zg5vskVqtn?3ya(Gv`iJQG(b-0e>|5#dUpi@O zA7?gYI5sHxVrNg0vDQSL*pQQI{qOK1_NDom#7MJ;v*0G*Az|KazJ>a4f~WbwTPSNT zaIVddsrm81&rQS%=ED!T!BT&jA>*bGF~K&R=$wq{%cZ{Yzmogu#CEpi~ONqFF1l^=rk3TTI*AM^t{ z#`E^#J9o#bu$S1;^=)^F^`=^`(Q2ls}IOPfON-o`vmIbb|JMs9W z(IWZf?A6I`M$1fB-jm&2d_3LWPR(0V?qtPVS9n7nI|pEMly9;mAtF9Y>EOEJ$ECfF ze6q-w(v^8t_Ephok)ilF9cX)Wf$#o9??aYffi`BI6Ly|~nRUftk0lTK;M!Mo-t9pQ z?wIaR;%|(xh@8c0?Kb7CJpXWi9TSiIK_V)APGJ4?#XP=P=JV^X(cnFKRm|`s2*=>U*Ay)eO<0 zM4lI<4s9Y|xfp6gOTgIixFWM#~ zW4FY%H&UL+rz`!?VT=yHK#lMFF03nlTJ+~?^1aa|BIi!ze3IDWCw`91NtZq!2tDtT zYEZrb_BmbpijNdIiS6WB9yLdN#i9?edrfm0SF`co zrW-9ybHPmoPQ^~S&VfX~%jq%7KFVC9=8gH-_1VlR(uE#cqvVI@0d`ppyi-A)-P30ePjH{ym%Q{-C!4n80%g-)zo@SG2I`VJ zI_1d|dyU<@xURS;UY>e8&%jISil;hxq~7-P6pq~^#?fZ?h*wyNgF4u~EwtgBI*8sK zL+_3cLkEYT2ZN9?yfsavZ|D=HgQ7oT6Z*qn77RT`%=!nqWY0MoY9D_-`KH6c>RbnWNmdpw2m)MRysZ~jXhbZ4<2~; zR-_qUbxL2(5JHpqI6R;eMc{d-Swr(g`x|P{Io||fyf!dK?>GUj2|aEm?<~>liFFN4 z=&$(UqQA|I`IA@MdfYS)$oTD`&*&;=yIPcA2CngE)W;Z5`s~8#`Tnr*EBZ{Hn7Vc( zS?OBoRdvNLkyr9aS&hho-|h3bH$~-}LcIGs?tJu5hkQw?c0RMN_(^v@WXIQc|If3Nr_@b=8)Y_eK+|-I}fFgTYqZ5yB zu^6+m22wt?*gW)I^i}fc^_#5SkD~kdqr?gDN5S7r8^ljn{QypEg5Z>$BgQ1Q+k=928q9II){DSITc$TPP^^q|c(gsj`Mt?JzcEv1Ux^ zYvZsh8?sn4rd(#<^Gy8dEY_IVQ$?%rtRYjbbltOtOc{V27!#t`dL5sMc=s`*FJs zYObd}5+|_G3AOfB^7_ZuzDLl%bNX+IMoTy0G12zl4EjrtgX0B`U&7k=pp4^j9nZV5 zj(=C;qS8J&r`i_xe1mk_BYWT$dL=s5M1N#;ZTI(5S@$X(5_)iL{YKsn{RSRir9tZG zf!(`@bBZT9=lq~N!ytA8{p^PP<+qX}^~rntv@Iv**wS{!%eD8|HV#FKwh`m*7D{Of5INXe0$hio;hrCktN4w56IXL$? ze1<&I9*Hd(_;6nq**p5{9*4~mr$LWo-caLD^xGMSx9f2SPK~343+!>H?!0jc)5Lsm*ZRr)`!pLt3i9rq2Q*B2gt4IbJfYq{qwOARxAyp@9q&3$pU9d25B7H+^MY&BF~(G?OQ!Dc49fXc#?HlJ_m5H6 zad?sEo#go~X-nH!`mFg9+hf>Ur}BPI=REB;}D|qh~{V4BWi;jn5Pukzn5ETo*U&**V7Jh66V|<(~;}gj0yWnk| zZGT4tbG7&^^36fBK$z?)5-3f)4#}2v82kLM$7FfMoVQ^qwQT8 zmFRk9Pq8_dpRMc)bYkTq1HQeaVl`rujEnG-Qi$;|hMpl_UL)<4^uEN)96KDHXA3d) z+k{6apK8}IcubhoAn`(V?{WK9_Oph_G3u;!d))P#l;_^Bmp)Z<4*GihQslrm7%Jss z6W_*$^3K->WiL>KafiHf;d%Crw@;P5=Bv&=$Nuv35+C7A1kY8dwWhWWv#<@q zquP%qej@fs;#-U0LB_enO^G##Z{C3YZGWe++`rjh-LI4RihIrmHKd80;44e~pXaA5 z+uaN#TbhcFfZroE>Ly{g3;~5X!Bf|z+uS{{|87-$~_Kp@(rs$o> zLY4W`r!Id}&fhy}LuKE&WqQj@+9&&_RkU#?dF5G&5#XLbHofI};`npA)*XBvJ&|)Y z+tHKl=)rd4X!1=^_J<#qy;ymkD@Di9&?C_kdCuq=co02FflrCMcX;ff@z+a*Lmhln=@rvvFWc4g?%O7fp&Su4b>&3RX#Hu zFw26zlCaMV1GcXVk(8@%}UB z%%ARAuxQ>iPw}+rGv_auR@|OaIIVNqyvb8%Pg~HQN9XX69wT-B4fEV3w&hmo=c4gk zKiO5@b<^Nw@`9OjuQw)6oTyra0DM(tfn`dZG}T<5jSR{WTt+B$O0B;tYzC_3_tZem zs-VB3GHi~@$r(2yXS_MWtPF>1CX5`pV#SK=>TsYYI}of$ofGi-%U7ApeZi35rgTzD zS4lC>jk~nme2U8OI^~5Zu)-g%tS!xkt&yP>{%~342!FuQ;M7zjCwJ87yfI_P<&Q5Z zE%W-yjd``f3V(Hl8L0A_L0^SG6b_bzsXSy9`<4Zk`^=0^h=p7eGAe6PjBNdHLWb9{ z)Rkb|W*Elk(flVuT4{W)5#(9wTUG9_@-dQ%(O%(jNJeN#s$q^8aV=_Ad#hO<3@n4Y zTJ*j;?60za!hLm!9$0n_3=TKFCE=25kerY${2XN0mB52nMvK>17V!GaDn^=_QJZSC zV*)k4YRz0qYENTScFt(~zsWU0b99dMdA?Dz-LlMW*q$AhRrs7`<-KEBn|S$dArB!H z9I&kU)q!AmMoDPYb^cK0wCb|psv7Br;y`VfDnkQ|1uFuAGPYHG??lpHpIQEmhwD~0 z{`TGco(HDArSh8pRgg=IcXLSF;^$#qafBUXakNxh4(~h6{xAOguCf;}`?W*_x^2S$R zZhGg{?>Da)|KjL3OYgXMRm$_}KWjPs(T^ME6ei#Q`=_tm{_zDh-#s|_uFV(azCL7w z`KKk;zb=01xo>VNzQXfJ>VHJOH1m@YbH8@=^e->F?w8m4y+eQg_Q=++cfE7RJ-@ho z_J!ZMIkV5itaSxNUFv_m^U@pof939*e)>@OmAy{||E2H1ix+l#Jg<7*zgPNp|K{wz zt-~fA`P-;1Z}lE<`n_9w8G$FqPMLMvYe#GU@RKvYx$7_cX1({jrPJ;{G5eRJ4*zxB z9iJY{>2>ysFaOsC6L0(e3%7j5*!|?P*Iv4??$(39*u1t|pO-fbf9AWPq6H6!$9^$? z=MQggT~hk5Ra5@ldv)fJ^_M)l>8I(}U0w6mhhKX8q63fAe|wE-J+R+*&b)Ws zCj<6ge)3m89{>2yp3i+Sq2Hk2_P>5a%Z$1I>HF%+#S1Tc=%dGOs<@}C_r>tEYdEH|F+tjtqQr&l3+E`uMqvztyw&2VF*Pd%xtW zUGtLu^!gVv?!WPdlpjU@{^8U%COp-(RaJ~AU$yA6x|2~8eUG{a%u;`avSc+SYI-QG zEid;44SN){Q%2pNgYq9?J6sOaj{eWA_J_@KH7s3Yu%xOgP$sikP0+tw@f}_fD3{@) z8Xu_flz6?N8ef^mNjF0!9>4dRj9P6XvQy(`onV%hcufqF%8RL8<`0FGMe+~n6Slu>saajS%oD;a)wb0LrmQj$P=$t9+DJ2Vc}W#MgqlvOYR!1M!M6)KuWLbmQ#3jK-dqNB|-d!+F%f8qKauo%Fi}u`+PN0g05JrgO-#O z$wX3V&YvvhW=G@ECdXJg{n9B1HVpky$`M*dS9QwZuhw``JFKl!X0}$ixV$(DsPWuJ z^AeSVMj(IjpQK&lPL&60tG%6Ss;v&y*3@8=#r)g4)IKjGgs5We7OV&cq$~V)`pnFX z+NvyRio;U&=a>iE2X2Wk#1Lqob2{rgIof($>pE%XXo6eclQmYMHTe zLdSofgG22Mhna#)7-Y6@46Boi=iyG=QR@qZP1}Un+80uOtnHGD2kYRR{55E$V{mGM zz8X zGR4t~?HGl^S>~OUi-N2k&%Q^zA1hxX# z1JhV+Z5Rzba9uw1z<%T5L*NAX0EVxI4`A;C%i0g@agAl20yYAZSO9LimNgZyU=ltJ zaLHuL@&YGKv8=Vgb-+zPb1HlQYk)_9nT7BHTnJ2K!y%6~Spm?v4nBaxfvbTFft!Fy z)1e3M2Oa?y&43;#Yqm5wG%^c%;L+L81D6!h4&d6kv;(-g*s^v3PXqS@SIrUP3mpa<4hLNDol=z*C_p$8@} zgC1yBLl0aJOyUKg-T?H#^)=7~Gw*;NSO{DV+ydML+zH$TtOxD~?gcgi4**+%M}U2L z8^#IXaA4AM%PIoq1FL|Cf$M=QSD+ujw3Uk> z#yxP}`|trg^K1A39{CM?0GE6KAHYM$-~+g@k^cAsm;G@!W;pTmdD>I(l<&%QI9Kof3wSz#Jbca_yznexyrIm zNJI;d-_N>k%!G5GWx zVvv&Hl6#o+O{8-kD<<7W@T+sNV}f^$yB(zO8HGKR@?!MYe((jOv5PVAq6eqI_sg@a z!-98>uO#?COnN*yr-QE%qrsS1b7R3633#QNH+tdEk%4DZc>xY4Gvv z(qizN@UMo)ppAe7!0!UTBM$v;@RRV{_Qk;;0e=E~T^xKX_!-wQFU09L@ngmR zI~|9<0DRR%J6la?Q~Osq>G<@igcwP&N!3wKH@*mV84LhdYnl5aMJT; z!k4tyH7*ND&&NNF*AHIsN5RWH6HAZRg5Qf@n-4k`ehc^`;0xp6_kuU@hmXd=H-g^- zo^yOL%TK~&9iBt^aq#KjTd%jQt#R;$;MdN>KZ{ep7rgmJ{IfXpYrz-bx3i}klfNxe z{(SIp?C@Uj`|;~lzr+~Fjo|m)h`$r3{3O;Xix)b26N5e-{66r>ap()d?_6|__Jc3F z`5f&BUwI4uTAcE?fM3nJ<7gcGUhoC1L;A(RH-gXe#Gj{=SZCFNKOCq3(!u91v8>EE z(Oj(X7G!+z{!9K5WXhgZ>GBKWBO zQtby{6~=E-_Neo^pbGrfyYP#Vdo;cD-+J&h_qX}sy`>pauB^v*lAal3J`lXD)9W8# zA0`gpvVO0B5Wh(Hj`GulK8f}D#*Ojinhw6-qw(!?A^05djg%GLE-Bv&{tS47`6jx4 zY4=+2hn{f8k87UXMEb%_jvp99-n+qXWIZkOL#%p_fbaJ#d)}a9;akD)1HU*9K8?6T z(zoN|3&2kTUlfC0+O-&b6?jwdF262JdYJUhk{+X78^NCeUlpf6cS*h5n2+M%4}stJ z9C|AH5>>wNbq0L$i_H6C&s_6(58@(QcQOx%JY(p|aPWQV@dxAB!6NVyf8d>Fo$3`m zr~-fF`>ZG9;Map6zB@jC2l&-LjPI}Qm->Gc+h3D*p8~)6)z0h6Bu1K~3y->=B!3#| zTS%YbN|!u&q#q*PjMI(*rnI&7WZB;@E>j;Mcwx z-;SLDfB0?aMSo)Sb06YU1;l~&#KGr*KXQQiGKT(%+!lb}_+Do@OI%FSA0v-j@79vu z=MeoCN1hTtYy3t0c!R{%`VnuMC*?-zyU0`GZ8N}ch=CV=lZd0$gU=Ma%MVT?eP2|% z>VMJ?lfF1c`vt!Me4k&%_cz1fhyR-Xjnm$Z;LrTV;U}s+!tXBdt>Ed#HhmS-F7uug z>Fg$O#LqB-qjJ4~&wY&@Gb%qfZ`|jmKTmjG0_P=gUIOPOa9#rEC2(E>=Ou7n0_P=g zUIPEy66ihMslkEk7Rk!UULOhk5iv2j>{QlyQTOjf-TyY~{-db-Pn>%~E9%N2wj|f( zHZWE?^~?HDF12<8CaF8l1ISvE>yLl40s{BRf{u$VD*GB_0|}wYb;2oMLWy!sb?ymq zs;i#^B}5?C=3DHRI@K8a970)7$|WHmxi}J`uA_N2)ajX{?0bhTLq1p|7ol}^>H4m6 z?sdMuSay4~od4$BCp+a?QTWr&ePNDWP>as*l>2`Lc22ZwIuFmwK_qZq5B`7X!3M{U z+T8sA|6k0c*gjJo4l#_u4$N`jGzZRgpcA_@GsotQ$s0FrG-vcf9Muj~o59gz$BZ4F zTQ(}oEUV&hZ`-kL4iIPOn{6k3OPs^X6@frSl`j;i4VLk^5syvr_(N4$r99SGRkeKC zh?-zP4%wUI^ULzbjLFL%KPG=%{J2Tg&N7VbP$dsog-c3}Y>uA$vMZ`|^`fD8JnN`%1qRZ|rv;?;IAi z82nz2W*gb%{%XIcBp57NMeR^a@f4(3DOu((qxt~Z?1D=}AwxtaPbdD9R7~b&nM?Kj z+xEjrNRO&V`vp3AAV0(x(Dd40&~UTk7-%{@|LS|0m;c0Es_C_Vp`qzG8altG*Y#)e zL)xI}wf~`EKM6K-NipJcXnO4z$aF60n%;2y84b1nLKbyte?i~p^Fw?EO|Sg}4PSQ% zH2*rEhSQ)I-$UPP|3gF5sYv*jqBQ?bvO3c#Wovrv4{50VAziXr6Y|$Rn5bFEy+r%}sAiSJ?~=z3)2r4$$q;snz@t zdfk4nI&8t-t^@NO|5xXare7XKzsa$88YVgV7mt2z6#eEb;Re6ff&17KabH^gI_<0c zaF4%Abr^?pCk}i}XLMjR|KB2=?L(!*l12OTD|rxIE-hzu!+*Md4PPKla>^KxORq=P zIrKW8jcupb_dno=^u4Cn^WX+uztb^VjJiC{*IsDd_3QP(=Giv?OQIUA={0;air!da z(;4$@m;>H@X*!+u4nHJK^Pl6;=Q#BFno)-!n*I>!Qd4w2n*L>nP6LNKMI&i)uj|%% R1b*by|66w=zcsy1{%lo0gXs4MO)*Ha$N2%>$2U;`Q_PyD#~2 z&2=0*)9D}CoBh6hpMCG`?%UnB-ye71`i(bOG)-{Q#S4PCO|uQep(?tTr~-&XR0%7t zmx@cI?99oke=E(;Ga#m7uEA3q7a%(p8@yxL`E<}?@Jv~cVA5+;dW}kt=~*=trdGp@ zm;p*zD7%^T3MI!>$|@ZyN9P#=ne-8*$CULpeGu_b*>SNUkV)4mJ*KSpP3Y11zHCzN z6q~udFX>O^Cg~HJA|3h0TfQaUcWoKE?^mwU9bG&8e}3f$Zx)Xn>88G1gltEq;aq~8 zgIt76eJw!dL~DV@Lj9VLOnR3hlly2cE=0~u`I&&?)zXpN99(H=g~++c3y~>(%^ zYRO7u7Opl`M`V#IFHn@mOZI6wknF(*ZL1K)U2n{YuC=ap$U5qm)O)r(QMdk`zrHlO zfA{NG|9Ift9gU0jRTme|`2FZ7ufBJCLBRcJxbbff?`prT=Ap;E<9~$Oe@wcVJ+Z&c zf;zmlNv&tbX`a*)Vo1{cS@5zfcw-jamj!Rjf?t~jr@5J`pR_Ng!f(!kAIO3~odtg& z3x0PN{JUB3pJ%~o9Z%JN8zyG1_1>aV4LZMgB9?Pc^P*m7N;elt^9Bm&xgL z-{W#N`vNY%?_RGkSXab*k1qno74U?DK9AEM+~#a=3;6;BdPAW=5HuWdxwkvrE!&;V zE}vflA$LoN5aDvWz2UHM`-5R`7}}y)7DaQje`mNwGzZ(f0nr@tdWA3Gi%5x9m){?B zi`MNPUr2-_WQvGqXPanmmTfl+qYqO2?vO8HnD+ac&_ZcAC{Suu)ZQiOq88Y#d!lBSymK;Oj2`XWaCYB^~!6AN9G^Jr_7&*Gk2<=VS#G?f+DS3 zO706OB3r~YYF_x9)zyKsRn32ciaU(+`Oooa0#|ZdmrL`)0z2mT-D1Ki#&T*i;i_p_ zb&m-*-$z7ExcNNnGT{`rIqfsyeCAW#BPQH@9(0>Wp;zz(+)=aklA^6Ko{AuuYCjMja zO(y;y;P;sLPr)BD@t=V|YVdICap9>**{?F2U_h9I}Jy^uzJlA{C$QNZEyWC_YQ160=M; zW*u1g7Hm-c?;y+iSW|goM)YJq>Fb8hnC?iS52-%%DS>j1O$;QUCvh8OfE6tO21MXJPX6%;@I6`ojL6&MnEF z&c(=gCE?fo?AOz<*R4B~2kW==A3|L-{LqatAx7mfewV^}Fisi+`C?*j(5I^~Uvc;v zq4)5Te_CTc@+FNI^Frgmy=9)#*^K*%YLY!z8{K?0$t_jBML(%-Y^h_QL=)x3sKc|@ zK+$@v3Cw>N`boYddsti2p4kVlVqI~4yugtf@3^5ieT?TrU_LCE4}tj*hpi{9F&g7R zti2J;#VF>T=I|iqdjx$ug?SytTK)Ws^uyyFb+99hdDUm0IQO7{?Ri+cGh#iX;>1Un zM{7SUiq?Km5Uo9xAFUmo7p)!1jn)p&j@HI!MQcC0U8Fv|Rir-nhDe>dS)^_{e%(7) zUE)afVQ#uR7og1r@caDalluJRncV2bzrb9b(LwdX{?qj$wn4MR`Y>;&>n*Vj-xIMu zeQ~l6cwgrt=-&bTJD}eP{l=uw25YsMgS7|sM{BzEpVd6oshyy;_6f#8ZS_EY4CABr ze~I<5L7Q_Xfw2z@aU13?FOG4Kcih^0?mm&14Su$P5+p6n&`qQ1mZky=mXHI9KX)L&(D3|O_C?R~0E(jl1| zY9BJgn7a|I=fpfmYH~bJU_6i4Jb6rPSZOyiHD z%({5?l)4<_1Z=Do(akqPCW_cgI@DJ@R~l`=)s<6jb9Tsl1ndJZ%W zy7!B88sifY9FBHSO8l&^-Md+6y9>2~ImX=-J%3X^l{9q4#yN}UK4E#B?;)wK2Kgzp zy^m~7QGX}kJoKdjbgKH@fNM}MpS?CI`;Q?aB9Z;akn_;@t}OOnM*Z&bbowmlRQCTw zFvc96qMlmWi%h218V^PC{Yt28rH917YFb@UR<*Lc@~f&(>rH!L+5^)bnD)T52c|tR z?SW|zWbwdO^^!32eW|*w6|X5h=HJfXhcbA2cT0)i4K7iN3k_KC`&+s%rG)osGV%Rz zF@4ZN!n19VXj1X~ZnaUpOyzf~jp`+B4hbWzRPFJ*&-n%{_+4%TzeiN~8%mz<-}#*^ zzZ0%9ZleX`XH`MLqCwf=ceC6cednXZa=1O0<6%GIc3Sesl|4L4oL7HV@%O8GJRZn; z9*1H5e{f~T{-06)Uap=w?8U3gE6OV?SJ|6fVXwy?4A?`fR#&WEwbETyVt4ypfo=A7 zZz$|TMRnR>@ln7B8ZowCvh^tAI27(c9>9)Ym(x#n0zh{}xBP7@2!q=cu&#pjt zSF1rIA)`hO<2=TRx{%lJA_Y}y^G8G}K3Cxy3d)Z>rQQ~2bI8@|b+&jQ&z$N4yTRx2 z;$v1RK79F{u29Ie3$5c55t)Y}*%eo-&yD7T5QCpuN&df1v|nkdtL;8nP{0)#EpWVG z_%akIMzB7|5vG4of~?2;l6l&%pJI=(KF1xVcV^L7uqZ}>#=!aMeOOeT&a%vYg6F@*IwZZLHyK^`y5F~z$)K{1JWj!R7KN}u{qZFBz> zEN(-AY_mScNu~`-klSZ{9{(1lU#H|a?lR>#P5S&_3=(C1H_Fs6J{RO4JV-#rtxXvY z<8y~;ONRc$d8iJOQxk^CsQNFCQIyvJuGB=C!phahE2exNscI=pW$sqHDzpC_N}uUE zR#cSz$nf3_{Vt`?G|7UBvi}+W2@2-@7gZnGm_EXSie|Qd2zV|spHFIKv*`0m|D+j2ne`a{7d5SZ^#A|> diff --git a/Hin2n/src/main/jniLibs/arm64-v8a/libuip.so b/Hin2n/src/main/jniLibs/arm64-v8a/libuip.so deleted file mode 100644 index 9bda23d2d0633c26dd7f93c94bd2f1f7a94d8fe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30544 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 UL3ZBlsL$#4KeGchz8&;`0JNSREC2ui diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/aes.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/aes.h new file mode 100644 index 00000000..245c552a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/aes.h @@ -0,0 +1,92 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_AES_H +# define HEADER_AES_H + +# include + +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1.h new file mode 100644 index 00000000..9522eec1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1.h @@ -0,0 +1,886 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include +# include +# include +# include +# include +# include + +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG /*compat*/ V_ASN1_PRIMITIVE_TAG + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_UNDEF -1 +/* ASN.1 tag values */ +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 + +/* + * NB the constants below are used internally by ASN1_INTEGER + * and ASN1_ENUMERATED to indicate the sign. They are *not* on + * the wire tag values. + */ + +# define V_ASN1_NEG 0x100 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) + +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DEFINE_STACK_OF(X509_ALGOR) + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* String is embedded and only content should be freed */ +# define ASN1_STRING_FLAG_EMBED 0x080 +/* String should be parsed in RFC 5280's time format */ +# define ASN1_STRING_FLAG_X509_TIME 0x100 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +/* + * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted + * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting + * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias + * STABLE_FLAGS_CLEAR to reflect this. + */ +# define STABLE_FLAGS_CLEAR STABLE_FLAGS_MALLOC +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DEFINE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * This flag specifies that RC2254 escaping shall be performed. + */ +#define ASN1_STRFLGS_ESC_2254 0x400 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DEFINE_STACK_OF(ASN1_INTEGER) + +DEFINE_STACK_OF(ASN1_GENERALSTRING) + +DEFINE_STACK_OF(ASN1_UTF8STRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DEFINE_STACK_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(const ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t); +void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DEFINE_STACK_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(const ASN1_STRING *x); +DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)) +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, + const unsigned char *flags, int flags_len); + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, + BIT_STRING_BITNAME *tbl); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(const ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); +int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str); +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_normalize(ASN1_TIME *s); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t); +int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b); + +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r); +int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r); + + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_STDIO +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags); +int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +const char *ASN1_tag2str(int tag); + +/* Used to load and write Netscape format cert */ + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); +void ASN1_add_stable_module(void); + +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +int ASN1_str2mask(const char *str, unsigned long *pmask); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)); +void ASN1_SCTX_free(ASN1_SCTX *p); +const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p); +const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p); +unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p); +void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data); +void *ASN1_SCTX_get_app_data(ASN1_SCTX *p); + +const BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +const ASN1_ITEM *ASN1_ITEM_lookup(const char *name); +const ASN1_ITEM *ASN1_ITEM_get(size_t i); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1_mac.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1_mac.h new file mode 100644 index 00000000..7ac1782a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1_mac.h @@ -0,0 +1,10 @@ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#error "This file is obsolete; please update your software." diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1err.h new file mode 100644 index 00000000..faed5a55 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1err.h @@ -0,0 +1,256 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1ERR_H +# define HEADER_ASN1ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASN1_strings(void); + +/* + * ASN1 function codes. + */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIO_INIT 113 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DO_LOCK 233 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENC_SAVE 115 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_INT64 224 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_GET_UINT64 225 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EMBED_D2I 120 +# define ASN1_F_ASN1_ITEM_EMBED_NEW 121 +# define ASN1_F_ASN1_ITEM_FLAGS_I2D 118 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PRIMITIVE_NEW 119 +# define ASN1_F_ASN1_SCTX_NEW 221 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_GET_INT64 227 +# define ASN1_F_ASN1_STRING_GET_UINT64 230 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TO_BN 228 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_STRING 229 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_C2I_IBUF 226 +# define ASN1_F_C2I_UINT64_INT 101 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_DO_BUF 142 +# define ASN1_F_DO_CREATE 124 +# define ASN1_F_DO_DUMP 125 +# define ASN1_F_DO_TCREATE 222 +# define ASN1_F_I2A_ASN1_OBJECT 126 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_OBJECT 143 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_NDEF_PREFIX 127 +# define ASN1_F_NDEF_SUFFIX 136 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE2_SET_SCRYPT 231 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_PKCS5_SCRYPT_SET 232 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_STABLE_GET 138 +# define ASN1_F_STBL_MODULE_INIT 223 +# define ASN1_F_UINT32_C2I 105 +# define ASN1_F_UINT32_NEW 139 +# define ASN1_F_UINT64_C2I 112 +# define ASN1_F_UINT64_NEW 141 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_PKEY_NEW 173 + +/* + * ASN1 reason codes. + */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NEGATIVE_VALUE 226 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_PADDING 221 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_ILLEGAL_ZERO_CONTENT 222 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SCRYPT_PARAMETERS 227 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_STRING_TABLE_VALUE 218 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_INVALID_VALUE 219 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NESTED_TOO_DEEP 201 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LARGE 223 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TOO_SMALL 224 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 195 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 228 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_INTEGER_TYPE 225 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1t.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1t.h new file mode 100644 index 00000000..a450ba0d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asn1t.h @@ -0,0 +1,945 @@ +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +# define static_ASN1_ITEM_start(itname) \ + static const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define static_ASN1_ITEM_start(itname) \ + static ASN1_ITEM_start(itname) + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) +# define static_ASN1_BROKEN_SEQUENCE_END(stname) \ + static_ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) +# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) +/* Embedded simple type */ +# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) +# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) +# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ + const char *field_name; /* Field name */ + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + int (*adb_cb)(long *psel); /* Application callback */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT (ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT) + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT (ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT) + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* Field is embedded and not a pointer */ +# define ASN1_TFLG_EMBED (0x1 << 12) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ + const char *sname; /* Structure name */ +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \ + static stname *d2i_##stname(stname **a, \ + const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \ + ASN1_ITEM_rptr(stname)); \ + } \ + static int i2d_##stname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, \ + ASN1_ITEM_rptr(stname)); \ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(INT32) +DECLARE_ASN1_ITEM(ZINT32) +DECLARE_ASN1_ITEM(UINT32) +DECLARE_ASN1_ITEM(ZUINT32) +DECLARE_ASN1_ITEM(INT64) +DECLARE_ASN1_ITEM(ZINT64) +DECLARE_ASN1_ITEM(UINT64) +DECLARE_ASN1_ITEM(ZUINT64) + +# if OPENSSL_API_COMPAT < 0x10200000L +/* + * LONG and ZLONG are strongly discouraged for use as stored data, as the + * underlying C type (long) differs in size depending on the architecture. + * They are designed with 32-bit longs in mind. + */ +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) +# endif + +DEFINE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/async.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/async.h new file mode 100644 index 00000000..7052b890 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/async.h @@ -0,0 +1,76 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifndef HEADER_ASYNC_H +# define HEADER_ASYNC_H + +#if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include to use this */ +#define OSSL_ASYNC_FD HANDLE +#define OSSL_BAD_ASYNC_FD INVALID_HANDLE_VALUE +# endif +#else +#define OSSL_ASYNC_FD int +#define OSSL_BAD_ASYNC_FD -1 +#endif +# include + + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct async_job_st ASYNC_JOB; +typedef struct async_wait_ctx_st ASYNC_WAIT_CTX; + +#define ASYNC_ERR 0 +#define ASYNC_NO_JOBS 1 +#define ASYNC_PAUSE 2 +#define ASYNC_FINISH 3 + +int ASYNC_init_thread(size_t max_size, size_t init_size); +void ASYNC_cleanup_thread(void); + +#ifdef OSSL_ASYNC_FD +ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); +void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); +int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD fd, + void *custom_data, + void (*cleanup)(ASYNC_WAIT_CTX *, const void *, + OSSL_ASYNC_FD, void *)); +int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD *fd, void **custom_data); +int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, + size_t *numfds); +int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); +#endif + +int ASYNC_is_capable(void); + +int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret, + int (*func)(void *), void *args, size_t size); +int ASYNC_pause_job(void); + +ASYNC_JOB *ASYNC_get_current_job(void); +ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job); +void ASYNC_block_pause(void); +void ASYNC_unblock_pause(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asyncerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asyncerr.h new file mode 100644 index 00000000..91afbbb2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/asyncerr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASYNCERR_H +# define HEADER_ASYNCERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASYNC_strings(void); + +/* + * ASYNC function codes. + */ +# define ASYNC_F_ASYNC_CTX_NEW 100 +# define ASYNC_F_ASYNC_INIT_THREAD 101 +# define ASYNC_F_ASYNC_JOB_NEW 102 +# define ASYNC_F_ASYNC_PAUSE_JOB 103 +# define ASYNC_F_ASYNC_START_FUNC 104 +# define ASYNC_F_ASYNC_START_JOB 105 +# define ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD 106 + +/* + * ASYNC reason codes. + */ +# define ASYNC_R_FAILED_TO_SET_POOL 101 +# define ASYNC_R_FAILED_TO_SWAP_CONTEXT 102 +# define ASYNC_R_INIT_FAILED 105 +# define ASYNC_R_INVALID_POOL_SIZE 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bio.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bio.h new file mode 100644 index 00000000..ae559a51 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bio.h @@ -0,0 +1,801 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* There are the classes of BIOs */ +# define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM ( 1|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_FILE ( 2|BIO_TYPE_SOURCE_SINK) + +# define BIO_TYPE_FD ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_SOCKET ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_NULL ( 6|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_SSL ( 7|BIO_TYPE_FILTER) +# define BIO_TYPE_MD ( 8|BIO_TYPE_FILTER) +# define BIO_TYPE_BUFFER ( 9|BIO_TYPE_FILTER) +# define BIO_TYPE_CIPHER (10|BIO_TYPE_FILTER) +# define BIO_TYPE_BASE64 (11|BIO_TYPE_FILTER) +# define BIO_TYPE_CONNECT (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ACCEPT (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) + +# define BIO_TYPE_NBIO_TEST (16|BIO_TYPE_FILTER)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|BIO_TYPE_FILTER) +# define BIO_TYPE_BIO (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|BIO_TYPE_FILTER) +# define BIO_TYPE_DGRAM (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ASN1 (22|BIO_TYPE_FILTER) +# define BIO_TYPE_COMP (23|BIO_TYPE_FILTER) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# endif + +#define BIO_TYPE_START 128 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_PEEK 29/* BIO_f_buffer special */ +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +/* Deliberately outside of OPENSSL_NO_SCTP - used in bss_dgram.c */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: + * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way; + * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 +# define BIO_FLAGS_NONCLEAR_RST 0x400 +# define BIO_FLAGS_IN_EOF 0x800 + +typedef union bio_addr_st BIO_ADDR; +typedef struct bio_addrinfo_st BIO_ADDRINFO; + +int BIO_get_new_index(void); +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi, + long argl, long ret); +typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp, + size_t len, int argi, + long argl, int ret, size_t *processed); +BIO_callback_fn BIO_get_callback(const BIO *b); +void BIO_set_callback(BIO *b, BIO_callback_fn callback); + +BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b); +void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback); + +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +typedef struct bio_method_st BIO_METHOD; + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef int BIO_info_cb(BIO *, int, int); +typedef BIO_info_cb bio_info_cb; /* backward compatibility */ + +DEFINE_STACK_OF(BIO) + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +/* # define BIO_C_SET_PROXY_PARAM 103 */ +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +/* # define BIO_C_GET_PROXY_PARAM 121 */ +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_C_SET_CONNECT_MODE 155 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +# ifndef OPENSSL_NO_SOCK +/* IP families we support, for BIO_s_connect() and BIO_s_accept() */ +/* Note: the underlying operating system may not support some of them */ +# define BIO_FAMILY_IPV4 4 +# define BIO_FAMILY_IPV6 6 +# define BIO_FAMILY_IPANY 256 + +/* BIO_s_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0, \ + (char *)(name)) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1, \ + (char *)(port)) +# define BIO_set_conn_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2, \ + (char *)(addr)) +# define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f) +# define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)) +# define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) +# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) +# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ + (char *)(name)) +# define BIO_set_accept_port(b,port) BIO_ctrl(b,BIO_C_SET_ACCEPT,1, \ + (char *)(port)) +# define BIO_get_accept_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)) +# define BIO_get_accept_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1)) +# define BIO_get_peer_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2)) +# define BIO_get_peer_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3)) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,3, \ + (char *)(bio)) +# define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) +# define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) + +/* Aliases kept for backward compatibility */ +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR +# define BIO_BIND_REUSEADDR_IF_UNUSED BIO_SOCK_REUSEADDR +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# endif /* OPENSSL_NO_SOCK */ + +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)(c)) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)(fp)) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)(fpp)) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)(name)) +# endif +# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)(ssl)) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)(sslp)) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)(md)) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)(pp)) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)(bm)) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0, \ + (char *)(pp)) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) +# define BIO_buffer_peek(b,s,l) BIO_ctrl(b,BIO_CTRL_PEEK,(l),(s)) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)(peer)) +# define BIO_ctrl_set_connected(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)(peer)) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef) +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +uint64_t BIO_number_read(BIO *bio); +uint64_t BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +const BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +# ifndef OPENSSL_NO_STDIO +BIO *BIO_new_fp(FILE *stream, int close_flag); +# endif +BIO *BIO_new(const BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_set_data(BIO *a, void *ptr); +void *BIO_get_data(BIO *a); +void BIO_set_init(BIO *a, int init); +int BIO_get_init(BIO *a); +void BIO_set_shutdown(BIO *a, int shut); +int BIO_get_shutdown(BIO *a); +void BIO_vfree(BIO *a); +int BIO_up_ref(BIO *a); +int BIO_read(BIO *b, void *data, int dlen); +int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int dlen); +int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); +void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +void BIO_set_next(BIO *b, BIO *next); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +void BIO_set_retry_reason(BIO *bio, int reason); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +const BIO_METHOD *BIO_s_mem(void); +const BIO_METHOD *BIO_s_secmem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +# ifndef OPENSSL_NO_SOCK +const BIO_METHOD *BIO_s_socket(void); +const BIO_METHOD *BIO_s_connect(void); +const BIO_METHOD *BIO_s_accept(void); +# endif +const BIO_METHOD *BIO_s_fd(void); +const BIO_METHOD *BIO_s_log(void); +const BIO_METHOD *BIO_s_bio(void); +const BIO_METHOD *BIO_s_null(void); +const BIO_METHOD *BIO_f_null(void); +const BIO_METHOD *BIO_f_buffer(void); +const BIO_METHOD *BIO_f_linebuffer(void); +const BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_datagram(void); +int BIO_dgram_non_fatal_error(int error); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +const BIO_METHOD *BIO_s_datagram_sctp(void); +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +# endif + +# ifndef OPENSSL_NO_SOCK +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +# endif + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_STDIO +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen); + +# ifndef OPENSSL_NO_SOCK +BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, + const void *where, size_t wherelen, unsigned short port); +void BIO_ADDR_free(BIO_ADDR *); +void BIO_ADDR_clear(BIO_ADDR *ap); +int BIO_ADDR_family(const BIO_ADDR *ap); +int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l); +unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap); +char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_path_string(const BIO_ADDR *ap); + +const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai); +const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai); +void BIO_ADDRINFO_free(BIO_ADDRINFO *bai); + +enum BIO_hostserv_priorities { + BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV +}; +int BIO_parse_hostserv(const char *hostserv, char **host, char **service, + enum BIO_hostserv_priorities hostserv_prio); +enum BIO_lookup_type { + BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER +}; +int BIO_lookup(const char *host, const char *service, + enum BIO_lookup_type lookup_type, + int family, int socktype, BIO_ADDRINFO **res); +int BIO_lookup_ex(const char *host, const char *service, + int lookup_type, int family, int socktype, int protocol, + BIO_ADDRINFO **res); +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_sock_init(void); +# if OPENSSL_API_COMPAT < 0x10100000L +# define BIO_sock_cleanup() while(0) continue +# endif +int BIO_set_tcp_ndelay(int sock, int turn_on); + +DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name)) +DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr)) +DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip)) +DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode)) +DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port)) + +union BIO_sock_info_u { + BIO_ADDR *addr; +}; +enum BIO_sock_info_type { + BIO_SOCK_INFO_ADDRESS +}; +int BIO_sock_info(int sock, + enum BIO_sock_info_type type, union BIO_sock_info_u *info); + +# define BIO_SOCK_REUSEADDR 0x01 +# define BIO_SOCK_V6_ONLY 0x02 +# define BIO_SOCK_KEEPALIVE 0x04 +# define BIO_SOCK_NONBLOCK 0x08 +# define BIO_SOCK_NODELAY 0x10 + +int BIO_socket(int domain, int socktype, int protocol, int options); +int BIO_connect(int sock, const BIO_ADDR *addr, int options); +int BIO_bind(int sock, const BIO_ADDR *addr, int options); +int BIO_listen(int sock, const BIO_ADDR *addr, int options); +int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options); +int BIO_closesocket(int sock); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); +# endif /* OPENSSL_NO_SOCK*/ + +BIO *BIO_new_fd(int fd, int close_flag); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# define ossl_bio__attr__(x) +# if defined(__GNUC__) && defined(__STDC_VERSION__) \ + && !defined(__APPLE__) + /* + * Because we support the 'z' modifier, which made its appearance in C99, + * we can't use __attribute__ with pre C99 dialects. + */ +# if __STDC_VERSION__ >= 199901L +# undef ossl_bio__attr__ +# define ossl_bio__attr__ __attribute__ +# if __GNUC__*10 + __GNUC_MINOR__ >= 44 +# define ossl_bio__printf__ __gnu_printf__ +# else +# define ossl_bio__printf__ __printf__ +# endif +# endif +# endif +int BIO_printf(BIO *bio, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 0))); +# undef ossl_bio__attr__ +# undef ossl_bio__printf__ + + +BIO_METHOD *BIO_meth_new(int type, const char *name); +void BIO_meth_free(BIO_METHOD *biom); +int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int); +int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t, + size_t *); +int BIO_meth_set_write(BIO_METHOD *biom, + int (*write) (BIO *, const char *, int)); +int BIO_meth_set_write_ex(BIO_METHOD *biom, + int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); +int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); +int BIO_meth_set_read(BIO_METHOD *biom, + int (*read) (BIO *, char *, int)); +int BIO_meth_set_read_ex(BIO_METHOD *biom, + int (*bread) (BIO *, char *, size_t, size_t *)); +int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); +int BIO_meth_set_puts(BIO_METHOD *biom, + int (*puts) (BIO *, const char *)); +int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); +int BIO_meth_set_gets(BIO_METHOD *biom, + int (*gets) (BIO *, char *, int)); +long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); +int BIO_meth_set_ctrl(BIO_METHOD *biom, + long (*ctrl) (BIO *, int, long, void *)); +int (*BIO_meth_get_create(const BIO_METHOD *bion)) (BIO *); +int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); +int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *); +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); +long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) + (BIO *, int, BIO_info_cb *); +int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl) (BIO *, int, + BIO_info_cb *)); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bioerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bioerr.h new file mode 100644 index 00000000..46e2c96e --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bioerr.h @@ -0,0 +1,124 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIOERR_H +# define HEADER_BIOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BIO_strings(void); + +/* + * BIO function codes. + */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_ADDRINFO_WRAP 148 +# define BIO_F_ADDR_STRINGS 134 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_ACCEPT_EX 137 +# define BIO_F_BIO_ACCEPT_NEW 152 +# define BIO_F_BIO_ADDR_NEW 144 +# define BIO_F_BIO_BIND 147 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CONNECT 138 +# define BIO_F_BIO_CONNECT_NEW 153 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_NEW_INDEX 102 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_LISTEN 139 +# define BIO_F_BIO_LOOKUP 135 +# define BIO_F_BIO_LOOKUP_EX 143 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_METH_NEW 146 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_DGRAM_SCTP 145 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PARSE_HOSTSERV 136 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_READ_EX 105 +# define BIO_F_BIO_READ_INTERN 120 +# define BIO_F_BIO_SOCKET 140 +# define BIO_F_BIO_SOCKET_NBIO 142 +# define BIO_F_BIO_SOCK_INFO 141 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BIO_WRITE_EX 119 +# define BIO_F_BIO_WRITE_INTERN 128 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_NEW 149 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_DOAPR_OUTCH 150 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_LINEBUFFER_NEW 151 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_NBIOF_NEW 154 +# define BIO_F_SLG_WRITE 155 +# define BIO_F_SSL_NEW 118 + +/* + * BIO reason codes. + */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET 141 +# define BIO_R_AMBIGUOUS_HOST_OR_SERVICE 129 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_GETSOCKNAME_ERROR 132 +# define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 +# define BIO_R_GETTING_SOCKTYPE 134 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_SOCKET 135 +# define BIO_R_IN_USE 123 +# define BIO_R_LENGTH_TOO_LONG 102 +# define BIO_R_LISTEN_V6_ONLY 136 +# define BIO_R_LOOKUP_RETURNED_NOTHING 142 +# define BIO_R_MALFORMED_HOST_OR_SERVICE 130 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 +# define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_KEEPALIVE 137 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNABLE_TO_NODELAY 138 +# define BIO_R_UNABLE_TO_REUSEADDR 139 +# define BIO_R_UNAVAILABLE_IP_FAMILY 145 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNKNOWN_INFO_TYPE 140 +# define BIO_R_UNSUPPORTED_IP_FAMILY 146 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/blowfish.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/blowfish.h new file mode 100644 index 00000000..cd3e460e --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/blowfish.h @@ -0,0 +1,61 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include + +# ifndef OPENSSL_NO_BF +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define BF_LONG unsigned int + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bn.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bn.h new file mode 100644 index 00000000..8af05d00 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bn.h @@ -0,0 +1,539 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 64-bit processor with LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULONG unsigned long +# define BN_BYTES 8 +# endif + +/* + * 64-bit processor other than LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT +# define BN_ULONG unsigned long long +# define BN_BYTES 8 +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_ULONG unsigned int +# define BN_BYTES 4 +# endif + +# define BN_BITS2 (BN_BYTES * 8) +# define BN_BITS (BN_BITS2 * 2) +# define BN_TBIT ((BN_ULONG)1 << (BN_BITS2 - 1)) + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 +# define BN_FLG_SECURE 0x08 + +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +# define BN_FLG_FREE 0x8000 /* used for debugging */ +# endif + +void BN_set_flags(BIGNUM *b, int n); +int BN_get_flags(const BIGNUM *b, int n); + +/* Values for |top| in BN_rand() */ +#define BN_RAND_TOP_ANY -1 +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +/* Values for |bottom| in BN_rand() */ +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot be used in parallel!). Also only for *read only* use. The + * value |dest| should be a newly allocated BIGNUM obtained via BN_new() that + * has not been otherwise initialised or used. + */ +void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags); + +/* Wrapper function to make using BN_GENCB easier */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); + +BN_GENCB *BN_GENCB_new(void); +void BN_GENCB_free(BN_GENCB *cb); + +/* Populate a BN_GENCB structure with an "old"-style callback */ +void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *), + void *cb_arg); + +/* Populate a BN_GENCB structure with a "new"-style callback */ +void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *), + void *cb_arg); + +void *BN_GENCB_get_arg(BN_GENCB *cb); + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations + * that will be done for checking that a random number is probably prime. The + * error rate for accepting a composite number as prime depends on the size of + * the prime |b|. The error rates used are for calculating an RSA key with 2 primes, + * and so the level is what you would expect for a key of double the size of the + * prime. + * + * This table is generated using the algorithm of FIPS PUB 186-4 + * Digital Signature Standard (DSS), section F.1, page 117. + * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) + * + * The following magma script was used to generate the output: + * securitybits:=125; + * k:=1024; + * for t:=1 to 65 do + * for M:=3 to Floor(2*Sqrt(k-1)-1) do + * S:=0; + * // Sum over m + * for m:=3 to M do + * s:=0; + * // Sum over j + * for j:=2 to m do + * s+:=(RealField(32)!2)^-(j+(k-1)/j); + * end for; + * S+:=2^(m-(m-1)*t)*s; + * end for; + * A:=2^(k-2-M*t); + * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; + * pkt:=2.00743*Log(2)*k*2^-k*(A+B); + * seclevel:=Floor(-Log(2,pkt)); + * if seclevel ge securitybits then + * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; + * break; + * end if; + * end for; + * if seclevel ge securitybits then break; end if; + * end for; + * + * It can be run online at: + * http://magma.maths.usyd.edu.au/calc + * + * And will output: + * k: 1024, security: 129 bits (t: 6, M: 23) + * + * k is the number of bits of the prime, securitybits is the level we want to + * reach. + * + * prime length | RSA key size | # MR tests | security level + * -------------+--------------|------------+--------------- + * (b) >= 6394 | >= 12788 | 3 | 256 bit + * (b) >= 3747 | >= 7494 | 3 | 192 bit + * (b) >= 1345 | >= 2690 | 4 | 128 bit + * (b) >= 1080 | >= 2160 | 5 | 128 bit + * (b) >= 852 | >= 1704 | 5 | 112 bit + * (b) >= 476 | >= 952 | 5 | 80 bit + * (b) >= 400 | >= 800 | 6 | 80 bit + * (b) >= 347 | >= 694 | 7 | 80 bit + * (b) >= 308 | >= 616 | 8 | 80 bit + * (b) >= 55 | >= 110 | 27 | 64 bit + * (b) >= 6 | >= 12 | 34 | 64 bit + */ + +# define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ + (b) >= 1345 ? 4 : \ + (b) >= 476 ? 5 : \ + (b) >= 400 ? 6 : \ + (b) >= 347 ? 7 : \ + (b) >= 308 ? 8 : \ + (b) >= 55 ? 27 : \ + /* b >= 6 */ 34) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_zero(const BIGNUM *a); +int BN_is_one(const BIGNUM *a); +int BN_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_odd(const BIGNUM *a); + +# define BN_one(a) (BN_set_word((a),1)) + +void BN_zero_ex(BIGNUM *a); + +# if OPENSSL_API_COMPAT >= 0x00908000L +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +BN_CTX *BN_CTX_secure_new(void); +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG l); +int BN_security_bits(int L, int N); +BIGNUM *BN_new(void); +BIGNUM *BN_secure_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param b pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +int BN_is_negative(const BIGNUM *b); + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_STDIO +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +int BN_print(BIO *bio, const BIGNUM *a); +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +DEPRECATEDIN_0_9_8(BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, + const BIGNUM *rem, + void (*callback) (int, int, + void *), + void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg, + int do_trial_division)) + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); + +int BN_BLINDING_is_current_thread(BN_BLINDING *b); +void BN_BLINDING_set_current_thread(BN_BLINDING *b); +int BN_BLINDING_lock(BN_BLINDING *b); +int BN_BLINDING_unlock(BN_BLINDING *b); + +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +DEPRECATEDIN_0_9_8(void BN_set_params(int mul, int high, int low, int mont)) +DEPRECATEDIN_0_9_8(int BN_get_params(int which)) /* 0, mul, 1 high, 2 low, 3 + * mont */ + +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a, + const BIGNUM *field, BN_CTX *ctx); + +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, const unsigned char *message, + size_t message_len, BN_CTX *ctx); + +/* Primes from RFC 2409 */ +BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define get_rfc2409_prime_768 BN_get_rfc2409_prime_768 +# define get_rfc2409_prime_1024 BN_get_rfc2409_prime_1024 +# define get_rfc3526_prime_1536 BN_get_rfc3526_prime_1536 +# define get_rfc3526_prime_2048 BN_get_rfc3526_prime_2048 +# define get_rfc3526_prime_3072 BN_get_rfc3526_prime_3072 +# define get_rfc3526_prime_4096 BN_get_rfc3526_prime_4096 +# define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144 +# define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192 +# endif + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bnerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bnerr.h new file mode 100644 index 00000000..9f3c7cfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/bnerr.h @@ -0,0 +1,100 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BNERR_H +# define HEADER_BNERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BN_strings(void); + +/* + * BN function codes. + */ +# define BN_F_BNRAND 127 +# define BN_F_BNRAND_RANGE 138 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_COMPUTE_WNAF 142 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GENCB_NEW 143 +# define BN_F_BN_GENERATE_DSA_NONCE 140 +# define BN_F_BN_GENERATE_PRIME_EX 141 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MONT_CTX_NEW 149 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_POOL_GET 147 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RECP_CTX_NEW 150 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_SET_WORDS 144 +# define BN_F_BN_STACK_PUSH 148 +# define BN_F_BN_USUB 115 + +/* + * BN reason codes. + */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_PRIVATE_KEY_TOO_LARGE 117 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffer.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffer.h new file mode 100644 index 00000000..d2765766 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffer.h @@ -0,0 +1,58 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include +# ifndef HEADER_CRYPTO_H +# include +# endif +# include + + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include + +/* + * These names are outdated as of OpenSSL 1.1; a future release + * will move them to be deprecated. + */ +# define BUF_strdup(s) OPENSSL_strdup(s) +# define BUF_strndup(s, size) OPENSSL_strndup(s, size) +# define BUF_memdup(data, size) OPENSSL_memdup(data, size) +# define BUF_strlcpy(dst, src, size) OPENSSL_strlcpy(dst, src, size) +# define BUF_strlcat(dst, src, size) OPENSSL_strlcat(dst, src, size) +# define BUF_strnlen(str, maxlen) OPENSSL_strnlen(str, maxlen) + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ + unsigned long flags; +}; + +# define BUF_MEM_FLAG_SECURE 0x01 + +BUF_MEM *BUF_MEM_new(void); +BUF_MEM *BUF_MEM_new_ex(unsigned long flags); +void BUF_MEM_free(BUF_MEM *a); +size_t BUF_MEM_grow(BUF_MEM *str, size_t len); +size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffererr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffererr.h new file mode 100644 index 00000000..04f6ff7a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/buffererr.h @@ -0,0 +1,34 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFERR_H +# define HEADER_BUFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BUF_strings(void); + +/* + * BUF function codes. + */ +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 + +/* + * BUF reason codes. + */ + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/camellia.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/camellia.h new file mode 100644 index 00000000..151f3c13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/camellia.h @@ -0,0 +1,83 @@ +/* + * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include + +# ifndef OPENSSL_NO_CAMELLIA +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cast.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cast.h new file mode 100644 index 00000000..2cc89ae0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cast.h @@ -0,0 +1,53 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +# include + +# ifndef OPENSSL_NO_CAST +# ifdef __cplusplus +extern "C" { +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmac.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmac.h new file mode 100644 index 00000000..3535a9ab --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmac.h @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +# ifndef OPENSSL_NO_CMAC + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cms.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cms.h new file mode 100644 index 00000000..c7627968 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cms.h @@ -0,0 +1,339 @@ +/* + * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include + +# ifndef OPENSSL_NO_CMS +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DEFINE_STACK_OF(CMS_SignerInfo) +DEFINE_STACK_OF(CMS_RecipientEncryptedKey) +DEFINE_STACK_OF(CMS_RecipientInfo) +DEFINE_STACK_OF(CMS_RevocationInfoChoice) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 +# define CMS_ASCIICRLF 0x80000 + +const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + const unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* Backward compatibility for spelling errors. */ +# define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \ + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmserr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmserr.h new file mode 100644 index 00000000..7dbc13dc --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cmserr.h @@ -0,0 +1,202 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMSERR_H +# define HEADER_CMSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CMS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CMS_strings(void); + +/* + * CMS function codes. + */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT 179 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_ENV_ASN1_CTRL 171 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SD_ASN1_CTRL 170 +# define CMS_F_CMS_SET1_IAS 176 +# define CMS_F_CMS_SET1_KEYID 177 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_SI_CHECK_ATTRIBUTES 183 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 +# define CMS_F_KEK_UNWRAP_KEY 180 + +/* + * CMS reason codes. + */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_ATTRIBUTE_ERROR 161 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_AGREEMENT 181 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comp.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comp.h new file mode 100644 index 00000000..d814d3cf --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comp.h @@ -0,0 +1,53 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include + +# ifndef OPENSSL_NO_COMP +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx); +int COMP_CTX_get_type(const COMP_CTX* comp); +int COMP_get_type(const COMP_METHOD *meth); +const char *COMP_get_name(const COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); + +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); + +COMP_METHOD *COMP_zlib(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +#define COMP_zlib_cleanup() while(0) continue +#endif + +# ifdef HEADER_BIO_H +# ifdef ZLIB +const BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comperr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comperr.h new file mode 100644 index 00000000..90231e9a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/comperr.h @@ -0,0 +1,44 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMPERR_H +# define HEADER_COMPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_COMP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_COMP_strings(void); + +/* + * COMP function codes. + */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 +# define COMP_F_COMP_CTX_NEW 103 + +/* + * COMP reason codes. + */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf.h new file mode 100644 index 00000000..7336cd2f --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf.h @@ -0,0 +1,168 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DEFINE_STACK_OF(CONF_VALUE) +DEFINE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DEFINE_STACK_OF(CONF_MODULE) +DEFINE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_STDIO +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +#ifndef OPENSSL_NO_STDIO +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +#endif +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name)) + +#if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_no_config() \ + OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL) +#endif + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_STDIO +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +#ifndef OPENSSL_NO_STDIO +int NCONF_dump_fp(const CONF *conf, FILE *out); +#endif +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +#if OPENSSL_API_COMPAT < 0x10100000L +# define CONF_modules_free() while(0) continue +#endif +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf_api.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf_api.h new file mode 100644 index 00000000..a0275ad7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conf_api.h @@ -0,0 +1,40 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conferr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conferr.h new file mode 100644 index 00000000..32b92291 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/conferr.h @@ -0,0 +1,76 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONFERR_H +# define HEADER_CONFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CONF_strings(void); + +/* + * CONF function codes. + */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_GET_NEXT_FILE 107 +# define CONF_F_MODULE_ADD 122 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_PROCESS_INCLUDE 116 +# define CONF_F_SSL_MODULE_INIT 123 +# define CONF_F_STR_COPY 101 + +/* + * CONF reason codes. + */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_NUMBER_TOO_LARGE 121 +# define CONF_R_RECURSIVE_DIRECTORY_INCLUDE 111 +# define CONF_R_SSL_COMMAND_SECTION_EMPTY 117 +# define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND 118 +# define CONF_R_SSL_SECTION_EMPTY 119 +# define CONF_R_SSL_SECTION_NOT_FOUND 120 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/crypto.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/crypto.h new file mode 100644 index 00000000..7d0b5262 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/crypto.h @@ -0,0 +1,445 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include +# include + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif + +# include +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSLeay OpenSSL_version_num +# define SSLeay_version OpenSSL_version +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION OPENSSL_VERSION +# define SSLEAY_CFLAGS OPENSSL_CFLAGS +# define SSLEAY_BUILT_ON OPENSSL_BUILT_ON +# define SSLEAY_PLATFORM OPENSSL_PLATFORM +# define SSLEAY_DIR OPENSSL_DIR + +/* + * Old type for allocating dynamic locks. No longer used. Use the new thread + * API instead. + */ +typedef struct { + int dummy; +} CRYPTO_dynlock; + +# endif /* OPENSSL_API_COMPAT */ + +typedef void CRYPTO_RWLOCK; + +CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); +int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); +void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); + +int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); + +/* + * The following can be used to detect memory leaks in the library. If + * used, it turns on malloc checking + */ +# define CRYPTO_MEM_CHECK_OFF 0x0 /* Control only */ +# define CRYPTO_MEM_CHECK_ON 0x1 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3 /* Control only */ + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; +DEFINE_STACK_OF(void) + +/* + * Per class, we have a STACK of function pointers. + */ +# define CRYPTO_EX_INDEX_SSL 0 +# define CRYPTO_EX_INDEX_SSL_CTX 1 +# define CRYPTO_EX_INDEX_SSL_SESSION 2 +# define CRYPTO_EX_INDEX_X509 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_DH 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_EC_KEY 8 +# define CRYPTO_EX_INDEX_RSA 9 +# define CRYPTO_EX_INDEX_ENGINE 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_BIO 12 +# define CRYPTO_EX_INDEX_APP 13 +# define CRYPTO_EX_INDEX_UI_METHOD 14 +# define CRYPTO_EX_INDEX_DRBG 15 +# define CRYPTO_EX_INDEX__COUNT 16 + +/* No longer needed, so this is a no-op */ +#define OPENSSL_malloc_init() while(0) continue + +int CRYPTO_mem_ctrl(int mode); + +# define OPENSSL_malloc(num) \ + CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_zalloc(num) \ + CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_realloc(addr, num) \ + CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_realloc(addr, old_num, num) \ + CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_free(addr, num) \ + CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_free(addr) \ + CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_memdup(str, s) \ + CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strdup(str) \ + CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strndup(str, n) \ + CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_malloc(num) \ + CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_zalloc(num) \ + CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_free(addr) \ + CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_clear_free(addr, num) \ + CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_actual_size(ptr) \ + CRYPTO_secure_actual_size(ptr) + +size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz); +size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz); +size_t OPENSSL_strnlen(const char *str, size_t maxlen); +char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); +unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); +int OPENSSL_hexchar2int(unsigned char c); + +# define OPENSSL_MALLOC_MAX_NELEMS(type) (((1U<<(sizeof(int)*8-1))-1)/sizeof(type)) + +unsigned long OpenSSL_version_num(void); +const char *OpenSSL_version(int type); +# define OPENSSL_VERSION 0 +# define OPENSSL_CFLAGS 1 +# define OPENSSL_BUILT_ON 2 +# define OPENSSL_PLATFORM 3 +# define OPENSSL_DIR 4 +# define OPENSSL_ENGINES_DIR 5 + +int OPENSSL_issetugid(void); + +typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* No longer use an index. */ +int CRYPTO_free_ex_index(int class_index, int idx); + +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + const CRYPTO_EX_DATA *from); + +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); + +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +# define CRYPTO_cleanup_all_ex_data() while(0) continue + +/* + * The old locking functions have been removed completely without compatibility + * macros. This is because the old functions either could not properly report + * errors, or the returned error values were not clearly documented. + * Replacing the locking functions with no-ops would cause race condition + * issues in the affected applications. It is far better for them to fail at + * compile time. + * On the other hand, the locking callbacks are no longer used. Consequently, + * the callback management functions can be safely replaced with no-op macros. + */ +# define CRYPTO_num_locks() (1) +# define CRYPTO_set_locking_callback(func) +# define CRYPTO_get_locking_callback() (NULL) +# define CRYPTO_set_add_lock_callback(func) +# define CRYPTO_get_add_lock_callback() (NULL) + +/* + * These defines where used in combination with the old locking callbacks, + * they are not called anymore, but old code that's not called might still + * use them. + */ +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +/* This structure is no longer used */ +typedef struct crypto_threadid_st { + int dummy; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +# define CRYPTO_THREADID_set_numeric(id, val) +# define CRYPTO_THREADID_set_pointer(id, ptr) +# define CRYPTO_THREADID_set_callback(threadid_func) (0) +# define CRYPTO_THREADID_get_callback() (NULL) +# define CRYPTO_THREADID_current(id) +# define CRYPTO_THREADID_cmp(a, b) (-1) +# define CRYPTO_THREADID_cpy(dest, src) +# define CRYPTO_THREADID_hash(id) (0UL) + +# if OPENSSL_API_COMPAT < 0x10000000L +# define CRYPTO_set_id_callback(func) +# define CRYPTO_get_id_callback() (NULL) +# define CRYPTO_thread_id() (0UL) +# endif /* OPENSSL_API_COMPAT < 0x10000000L */ + +# define CRYPTO_set_dynlock_create_callback(dyn_create_function) +# define CRYPTO_set_dynlock_lock_callback(dyn_lock_function) +# define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function) +# define CRYPTO_get_dynlock_create_callback() (NULL) +# define CRYPTO_get_dynlock_lock_callback() (NULL) +# define CRYPTO_get_dynlock_destroy_callback() (NULL) +# endif /* OPENSSL_API_COMPAT < 0x10100000L */ + +int CRYPTO_set_mem_functions( + void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, int), + void (*f) (void *, const char *, int)); +int CRYPTO_set_mem_debug(int flag); +void CRYPTO_get_mem_functions( + void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, int), + void (**f) (void *, const char *, int)); + +void *CRYPTO_malloc(size_t num, const char *file, int line); +void *CRYPTO_zalloc(size_t num, const char *file, int line); +void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line); +void CRYPTO_free(void *ptr, const char *file, int line); +void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line); +void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line); +void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, + const char *file, int line); + +int CRYPTO_secure_malloc_init(size_t sz, int minsize); +int CRYPTO_secure_malloc_done(void); +void *CRYPTO_secure_malloc(size_t num, const char *file, int line); +void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); +void CRYPTO_secure_free(void *ptr, const char *file, int line); +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); +int CRYPTO_secure_allocated(const void *ptr); +int CRYPTO_secure_malloc_initialized(void); +size_t CRYPTO_secure_actual_size(void *ptr); +size_t CRYPTO_secure_used(void); + +void OPENSSL_cleanse(void *ptr, size_t len); + +# ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_mem_debug_push(info) \ + CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_mem_debug_pop() \ + CRYPTO_mem_debug_pop() +int CRYPTO_mem_debug_push(const char *info, const char *file, int line); +int CRYPTO_mem_debug_pop(void); +void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount); + +/*- + * Debugging functions (enabled by CRYPTO_set_mem_debug(1)) + * The flag argument has the following significance: + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line); + +int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +int CRYPTO_mem_leaks_fp(FILE *); +# endif +int CRYPTO_mem_leaks(BIO *bio); +# endif + +/* die if we have to */ +ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line); +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l)) +# endif +# define OPENSSL_assert(e) \ + (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1)) + +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); +# ifdef OPENSSL_SYS_UNIX +void OPENSSL_fork_prepare(void); +void OPENSSL_fork_parent(void); +void OPENSSL_fork_child(void); +# endif + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to); + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len); + +/* Standard initialisation options */ +# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L +# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L +# define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L +# define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L +# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0x00000010L +# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0x00000020L +# define OPENSSL_INIT_LOAD_CONFIG 0x00000040L +# define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000080L +# define OPENSSL_INIT_ASYNC 0x00000100L +# define OPENSSL_INIT_ENGINE_RDRAND 0x00000200L +# define OPENSSL_INIT_ENGINE_DYNAMIC 0x00000400L +# define OPENSSL_INIT_ENGINE_OPENSSL 0x00000800L +# define OPENSSL_INIT_ENGINE_CRYPTODEV 0x00001000L +# define OPENSSL_INIT_ENGINE_CAPI 0x00002000L +# define OPENSSL_INIT_ENGINE_PADLOCK 0x00004000L +# define OPENSSL_INIT_ENGINE_AFALG 0x00008000L +/* OPENSSL_INIT_ZLIB 0x00010000L */ +# define OPENSSL_INIT_ATFORK 0x00020000L +/* OPENSSL_INIT_BASE_ONLY 0x00040000L */ +# define OPENSSL_INIT_NO_ATEXIT 0x00080000L +/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */ +/* Max OPENSSL_INIT flag value is 0x80000000 */ + +/* openssl and dasync not counted as builtin */ +# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \ + (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \ + | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \ + OPENSSL_INIT_ENGINE_PADLOCK) + + +/* Library initialisation functions */ +void OPENSSL_cleanup(void); +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_atexit(void (*handler)(void)); +void OPENSSL_thread_stop(void); + +/* Low-level control of initialization */ +OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); +# ifndef OPENSSL_NO_STDIO +int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, + const char *config_filename); +void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, + unsigned long flags); +int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, + const char *config_appname); +# endif +void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); + +# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +# if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include in order to use this */ +typedef DWORD CRYPTO_THREAD_LOCAL; +typedef DWORD CRYPTO_THREAD_ID; + +typedef LONG CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif +# else +# include +typedef pthread_once_t CRYPTO_ONCE; +typedef pthread_key_t CRYPTO_THREAD_LOCAL; +typedef pthread_t CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif +# endif + +# if !defined(CRYPTO_ONCE_STATIC_INIT) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif + +int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + +int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); +void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); +int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); +int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); + +CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); +int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cryptoerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cryptoerr.h new file mode 100644 index 00000000..3db5a4ee --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cryptoerr.h @@ -0,0 +1,57 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTOERR_H +# define HEADER_CRYPTOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CRYPTO_strings(void); + +/* + * CRYPTO function codes. + */ +# define CRYPTO_F_CMAC_CTX_NEW 120 +# define CRYPTO_F_CRYPTO_DUP_EX_DATA 110 +# define CRYPTO_F_CRYPTO_FREE_EX_DATA 111 +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_MEMDUP 115 +# define CRYPTO_F_CRYPTO_NEW_EX_DATA 112 +# define CRYPTO_F_CRYPTO_OCB128_COPY_CTX 121 +# define CRYPTO_F_CRYPTO_OCB128_INIT 122 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_GET_AND_LOCK 113 +# define CRYPTO_F_OPENSSL_ATEXIT 114 +# define CRYPTO_F_OPENSSL_BUF2HEXSTR 117 +# define CRYPTO_F_OPENSSL_FOPEN 119 +# define CRYPTO_F_OPENSSL_HEXSTR2BUF 118 +# define CRYPTO_F_OPENSSL_INIT_CRYPTO 116 +# define CRYPTO_F_OPENSSL_LH_NEW 126 +# define CRYPTO_F_OPENSSL_SK_DEEP_COPY 127 +# define CRYPTO_F_OPENSSL_SK_DUP 128 +# define CRYPTO_F_PKEY_HMAC_INIT 123 +# define CRYPTO_F_PKEY_POLY1305_INIT 124 +# define CRYPTO_F_PKEY_SIPHASH_INIT 125 +# define CRYPTO_F_SK_RESERVE 129 + +/* + * CRYPTO reason codes. + */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 +# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ct.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ct.h new file mode 100644 index 00000000..ebdba34d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ct.h @@ -0,0 +1,474 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CT_H +# define HEADER_CT_H + +# include + +# ifndef OPENSSL_NO_CT +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + +/* Minimum RSA key size, from RFC6962 */ +# define SCT_MIN_RSA_BITS 2048 + +/* All hashes are SHA256 in v1 of Certificate Transparency */ +# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH + +typedef enum { + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1 +} ct_log_entry_type_t; + +typedef enum { + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0 +} sct_version_t; + +typedef enum { + SCT_SOURCE_UNKNOWN, + SCT_SOURCE_TLS_EXTENSION, + SCT_SOURCE_X509V3_EXTENSION, + SCT_SOURCE_OCSP_STAPLED_RESPONSE +} sct_source_t; + +typedef enum { + SCT_VALIDATION_STATUS_NOT_SET, + SCT_VALIDATION_STATUS_UNKNOWN_LOG, + SCT_VALIDATION_STATUS_VALID, + SCT_VALIDATION_STATUS_INVALID, + SCT_VALIDATION_STATUS_UNVERIFIED, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION +} sct_validation_status_t; + +DEFINE_STACK_OF(SCT) +DEFINE_STACK_OF(CTLOG) + +/****************************************** + * CT policy evaluation context functions * + ******************************************/ + +/* + * Creates a new, empty policy evaluation context. + * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished + * with the CT_POLICY_EVAL_CTX. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); + +/* Deletes a policy evaluation context and anything it owns. */ +void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); + +/* Gets the peer certificate that the SCTs are for */ +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the certificate associated with the received SCTs. + * Increments the reference count of cert. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); + +/* Gets the issuer of the aforementioned certificate */ +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the issuer of the certificate associated with the received SCTs. + * Increments the reference count of issuer. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); + +/* Gets the CT logs that are trusted sources of SCTs */ +const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); + +/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */ +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store); + +/* + * Gets the time, in milliseconds since the Unix epoch, that will be used as the + * current time when checking whether an SCT was issued in the future. + * Such SCTs will fail validation, as required by RFC6962. + */ +uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch. + * If an SCT's timestamp is after this time, it will be interpreted as having + * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs + * whose timestamp is in the future", so an SCT will not validate in this case. + */ +void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); + +/***************** + * SCT functions * + *****************/ + +/* + * Creates a new, blank SCT. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new(void); + +/* + * Creates a new SCT from some base64-encoded strings. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new_from_base64(unsigned char version, + const char *logid_base64, + ct_log_entry_type_t entry_type, + uint64_t timestamp, + const char *extensions_base64, + const char *signature_base64); + +/* + * Frees the SCT and the underlying data structures. + */ +void SCT_free(SCT *sct); + +/* + * Free a stack of SCTs, and the underlying SCTs themselves. + * Intended to be compatible with X509V3_EXT_FREE. + */ +void SCT_LIST_free(STACK_OF(SCT) *a); + +/* + * Returns the version of the SCT. + */ +sct_version_t SCT_get_version(const SCT *sct); + +/* + * Set the version of an SCT. + * Returns 1 on success, 0 if the version is unrecognized. + */ +__owur int SCT_set_version(SCT *sct, sct_version_t version); + +/* + * Returns the log entry type of the SCT. + */ +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct); + +/* + * Set the log entry type of an SCT. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type); + +/* + * Gets the ID of the log that an SCT came from. + * Ownership of the log ID remains with the SCT. + * Returns the length of the log ID. + */ +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id); + +/* + * Set the log ID of an SCT to point directly to the *log_id specified. + * The SCT takes ownership of the specified pointer. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len); + +/* + * Set the log ID of an SCT. + * This makes a copy of the log_id. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, + size_t log_id_len); + +/* + * Returns the timestamp for the SCT (epoch time in milliseconds). + */ +uint64_t SCT_get_timestamp(const SCT *sct); + +/* + * Set the timestamp of an SCT (epoch time in milliseconds). + */ +void SCT_set_timestamp(SCT *sct, uint64_t timestamp); + +/* + * Return the NID for the signature used by the SCT. + * For CT v1, this will be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset). + */ +int SCT_get_signature_nid(const SCT *sct); + +/* + * Set the signature type of an SCT + * For CT v1, this should be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_signature_nid(SCT *sct, int nid); + +/* + * Set *ext to point to the extension data for the SCT. ext must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext); + +/* + * Set the extensions of an SCT to point directly to the *ext specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len); + +/* + * Set the extensions of an SCT. + * This takes a copy of the ext. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext, + size_t ext_len); + +/* + * Set *sig to point to the signature for the SCT. sig must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig); + +/* + * Set the signature of an SCT to point directly to the *sig specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len); + +/* + * Set the signature of an SCT to be a copy of the *sig specified. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig, + size_t sig_len); + +/* + * The origin of this SCT, e.g. TLS extension, OCSP response, etc. + */ +sct_source_t SCT_get_source(const SCT *sct); + +/* + * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_source(SCT *sct, sct_source_t source); + +/* + * Returns a text string describing the validation status of |sct|. + */ +const char *SCT_validation_status_string(const SCT *sct); + +/* + * Pretty-prints an |sct| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came + * from, so that the log name can be printed. + */ +void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs); + +/* + * Pretty-prints an |sct_list| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * SCTs will be delimited by |separator|. + * If |logs| is not NULL, it will be used to lookup the CT log that each SCT + * came from, so that the log names can be printed. + */ +void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *logs); + +/* + * Gets the last result of validating this SCT. + * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET. + */ +sct_validation_status_t SCT_get_validation_status(const SCT *sct); + +/* + * Validates the given SCT with the provided context. + * Sets the "validation_status" field of the SCT. + * Returns 1 if the SCT is valid and the signature verifies. + * Returns 0 if the SCT is invalid or could not be verified. + * Returns -1 if an error occurs. + */ +__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); + +/* + * Validates the given list of SCTs with the provided context. + * Sets the "validation_status" field of each SCT. + * Returns 1 if there are no invalid SCTs and all signatures verify. + * Returns 0 if at least one SCT is invalid or could not be verified. + * Returns a negative integer if an error occurs. + */ +__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts, + CT_POLICY_EVAL_CTX *ctx); + + +/********************************* + * SCT parsing and serialisation * + *********************************/ + +/* + * Serialize (to TLS format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just return the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Convert TLS format SCT list to a stack of SCTs. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + size_t len); + +/* + * Serialize (to DER format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just returns the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Parses an SCT list in DER format and returns it. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + long len); + +/* + * Serialize (to TLS format) an |sct| and write it to |out|. + * If |out| is null, no SCT will be output but the length will still be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format SCT. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the TLS-format SCT will be written + * to it. + * The length of the SCT in TLS format will be returned. + */ +__owur int i2o_SCT(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT in TLS format and returns it. + * If |psct| is not null, it will end up pointing to the parsed SCT. If it + * already points to a non-null pointer, the pointer will be free'd. + * |in| should be a pointer to a string containing the TLS-format SCT. + * |in| will be advanced to the end of the SCT if parsing succeeds. + * |len| should be the length of the SCT in |in|. + * Returns NULL if an error occurs. + * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len' + * fields will be populated (with |in| and |len| respectively). + */ +SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); + +/******************** + * CT log functions * + ********************/ + +/* + * Creates a new CT log instance with the given |public_key| and |name|. + * Takes ownership of |public_key| but copies |name|. + * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); + +/* + * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER + * in |pkey_base64|. The |name| is a string to help users identify this log. + * Returns 1 on success, 0 on failure. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +int CTLOG_new_from_base64(CTLOG ** ct_log, + const char *pkey_base64, const char *name); + +/* + * Deletes a CT log instance and its fields. + */ +void CTLOG_free(CTLOG *log); + +/* Gets the name of the CT log */ +const char *CTLOG_get0_name(const CTLOG *log); +/* Gets the ID of the CT log */ +void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, + size_t *log_id_len); +/* Gets the public key of the CT log */ +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); + +/************************** + * CT log store functions * + **************************/ + +/* + * Creates a new CT log store. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new(void); + +/* + * Deletes a CT log store and all of the CT log instances held within. + */ +void CTLOG_STORE_free(CTLOG_STORE *store); + +/* + * Finds a CT log in the store based on its log ID. + * Returns the CT log, or NULL if no match is found. + */ +const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, + const uint8_t *log_id, + size_t log_id_len); + +/* + * Loads a CT log list into a |store| from a |file|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file); + +/* + * Loads the default CT log list into a |store|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cterr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cterr.h new file mode 100644 index 00000000..feb7bc56 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/cterr.h @@ -0,0 +1,80 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CTERR_H +# define HEADER_CTERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CT + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CT_strings(void); + +/* + * CT function codes. + */ +# define CT_F_CTLOG_NEW 117 +# define CT_F_CTLOG_NEW_FROM_BASE64 118 +# define CT_F_CTLOG_NEW_FROM_CONF 119 +# define CT_F_CTLOG_STORE_LOAD_CTX_NEW 122 +# define CT_F_CTLOG_STORE_LOAD_FILE 123 +# define CT_F_CTLOG_STORE_LOAD_LOG 130 +# define CT_F_CTLOG_STORE_NEW 131 +# define CT_F_CT_BASE64_DECODE 124 +# define CT_F_CT_POLICY_EVAL_CTX_NEW 133 +# define CT_F_CT_V1_LOG_ID_FROM_PKEY 125 +# define CT_F_I2O_SCT 107 +# define CT_F_I2O_SCT_LIST 108 +# define CT_F_I2O_SCT_SIGNATURE 109 +# define CT_F_O2I_SCT 110 +# define CT_F_O2I_SCT_LIST 111 +# define CT_F_O2I_SCT_SIGNATURE 112 +# define CT_F_SCT_CTX_NEW 126 +# define CT_F_SCT_CTX_VERIFY 128 +# define CT_F_SCT_NEW 100 +# define CT_F_SCT_NEW_FROM_BASE64 127 +# define CT_F_SCT_SET0_LOG_ID 101 +# define CT_F_SCT_SET1_EXTENSIONS 114 +# define CT_F_SCT_SET1_LOG_ID 115 +# define CT_F_SCT_SET1_SIGNATURE 116 +# define CT_F_SCT_SET_LOG_ENTRY_TYPE 102 +# define CT_F_SCT_SET_SIGNATURE_NID 103 +# define CT_F_SCT_SET_VERSION 104 + +/* + * CT reason codes. + */ +# define CT_R_BASE64_DECODE_ERROR 108 +# define CT_R_INVALID_LOG_ID_LENGTH 100 +# define CT_R_LOG_CONF_INVALID 109 +# define CT_R_LOG_CONF_INVALID_KEY 110 +# define CT_R_LOG_CONF_MISSING_DESCRIPTION 111 +# define CT_R_LOG_CONF_MISSING_KEY 112 +# define CT_R_LOG_KEY_INVALID 113 +# define CT_R_SCT_FUTURE_TIMESTAMP 116 +# define CT_R_SCT_INVALID 104 +# define CT_R_SCT_INVALID_SIGNATURE 107 +# define CT_R_SCT_LIST_INVALID 105 +# define CT_R_SCT_LOG_ID_MISMATCH 114 +# define CT_R_SCT_NOT_SET 106 +# define CT_R_SCT_UNSUPPORTED_VERSION 115 +# define CT_R_UNRECOGNIZED_SIGNATURE_NID 101 +# define CT_R_UNSUPPORTED_ENTRY_TYPE 102 +# define CT_R_UNSUPPORTED_VERSION 103 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/des.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/des.h new file mode 100644 index 00000000..be4abbdf --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/des.h @@ -0,0 +1,174 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include + +# ifndef OPENSSL_NO_DES +# ifdef __cplusplus +extern "C" { +# endif +# include + +typedef unsigned int DES_LONG; + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +# define DES_fixup_key_parity DES_set_odd_parity + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dh.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dh.h new file mode 100644 index 00000000..3527540c --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dh.h @@ -0,0 +1,340 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include + +# ifndef OPENSSL_NO_DH +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + +# define DH_FLAG_CACHE_MONT_P 0x01 + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +DECLARE_ASN1_ITEM(DHparams) + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 +# define DH_CHECK_Q_NOT_PRIME 0x10 +# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_PUBKEY_INVALID 0x04 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_bits(const DH *dh); +int DH_size(const DH *dh); +int DH_security_bits(const DH *dh); +#define DH_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, l, p, newf, dupf, freef) +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check_params_ex(const DH *dh); +int DH_check_ex(const DH *dh); +int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key); +int DH_check_params(const DH *dh, int *ret); +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); +int i2d_DHxparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_STDIO +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +int DHparams_print(BIO *bp, const DH *x); + +/* RFC 5114 parameters */ +DH *DH_get_1024_160(void); +DH *DH_get_2048_224(void); +DH *DH_get_2048_256(void); + +/* Named parameters, currently RFC7919 */ +DH *DH_new_by_nid(int nid); +int DH_get_nid(const DH *dh); + +# ifndef OPENSSL_NO_CMS +/* RFC2631 KDF */ +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif + +void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DH_get0_p(const DH *dh); +const BIGNUM *DH_get0_q(const DH *dh); +const BIGNUM *DH_get0_g(const DH *dh); +const BIGNUM *DH_get0_priv_key(const DH *dh); +const BIGNUM *DH_get0_pub_key(const DH *dh); +void DH_clear_flags(DH *dh, int flags); +int DH_test_flags(const DH *dh, int flags); +void DH_set_flags(DH *dh, int flags); +ENGINE *DH_get0_engine(DH *d); +long DH_get_length(const DH *dh); +int DH_set_length(DH *dh, long length); + +DH_METHOD *DH_meth_new(const char *name, int flags); +void DH_meth_free(DH_METHOD *dhm); +DH_METHOD *DH_meth_dup(const DH_METHOD *dhm); +const char *DH_meth_get0_name(const DH_METHOD *dhm); +int DH_meth_set1_name(DH_METHOD *dhm, const char *name); +int DH_meth_get_flags(const DH_METHOD *dhm); +int DH_meth_set_flags(DH_METHOD *dhm, int flags); +void *DH_meth_get0_app_data(const DH_METHOD *dhm); +int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data); +int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *)); +int (*DH_meth_get_compute_key(const DH_METHOD *dhm)) + (unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_meth_set_compute_key(DH_METHOD *dhm, + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh)); +int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm)) + (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DH_meth_set_bn_mod_exp(DH_METHOD *dhm, + int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *); +int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *)); +int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *)); +int (*DH_meth_get_generate_params(const DH_METHOD *dhm)) + (DH *, int, int, BN_GENCB *); +int DH_meth_set_generate_params(DH_METHOD *dhm, + int (*generate_params) (DH *, int, int, BN_GENCB *)); + + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, \ + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_DH_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_dh_pad(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_PAD, pad, NULL) + +# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)) + +# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(poid)) + +# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)(plen)) + +# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(p)) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) +# define EVP_PKEY_CTRL_DH_NID (EVP_PKEY_ALG_CTRL + 15) +# define EVP_PKEY_CTRL_DH_PAD (EVP_PKEY_ALG_CTRL + 16) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# ifndef OPENSSL_NO_CMS +# define EVP_PKEY_DH_KDF_X9_42 2 +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dherr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dherr.h new file mode 100644 index 00000000..916b3bed --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dherr.h @@ -0,0 +1,88 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DHERR_H +# define HEADER_DHERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DH + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DH_strings(void); + +/* + * DH function codes. + */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_CHECK_EX 121 +# define DH_F_DH_CHECK_PARAMS_EX 122 +# define DH_F_DH_CHECK_PUB_KEY_EX 123 +# define DH_F_DH_CMS_DECRYPT 114 +# define DH_F_DH_CMS_SET_PEERKEY 115 +# define DH_F_DH_CMS_SET_SHARED_INFO 116 +# define DH_F_DH_METH_DUP 117 +# define DH_F_DH_METH_NEW 118 +# define DH_F_DH_METH_SET1_NAME 119 +# define DH_F_DH_NEW_BY_NID 104 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PKEY_PUBLIC_CHECK 124 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_PKEY_DH_CTRL_STR 120 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_INIT 125 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* + * DH reason codes. + */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_CHECK_INVALID_J_VALUE 115 +# define DH_R_CHECK_INVALID_Q_VALUE 116 +# define DH_R_CHECK_PUBKEY_INVALID 122 +# define DH_R_CHECK_PUBKEY_TOO_LARGE 123 +# define DH_R_CHECK_PUBKEY_TOO_SMALL 124 +# define DH_R_CHECK_P_NOT_PRIME 117 +# define DH_R_CHECK_P_NOT_SAFE_PRIME 118 +# define DH_R_CHECK_Q_NOT_PRIME 119 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PARAMETER_NAME 110 +# define DH_R_INVALID_PARAMETER_NID 114 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KDF_PARAMETER_ERROR 112 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_MISSING_PUBKEY 125 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NOT_SUITABLE_GENERATOR 120 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 +# define DH_R_PEER_KEY_ERROR 111 +# define DH_R_SHARED_INFO_ERROR 113 +# define DH_R_UNABLE_TO_CHECK_GENERATOR 121 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsa.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsa.h new file mode 100644 index 00000000..6d8a18a4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsa.h @@ -0,0 +1,244 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include + +# ifndef OPENSSL_NO_DSA +# ifdef __cplusplus +extern "C" { +# endif +# include +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + +# define DSA_FLAG_CACHE_MONT_P 0x01 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 +# define DSA_FLAG_FIPS_CHECKED 0x0800 + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st DSA_SIG; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); +const DSA_METHOD *DSA_get_method(DSA *d); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); +int DSA_bits(const DSA *d); +int DSA_security_bits(const DSA *d); + /* next 4 return -1 on error */ +DEPRECATEDIN_1_2_0(int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)) +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +#define DSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, l, p, newf, dupf, freef) +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DSA *DSA_generate_parameters(int bits, + unsigned char *seed, + int seed_len, + int *counter_ret, + unsigned long *h_ret, void + (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# ifndef OPENSSL_NO_STDIO +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 64 +/* + * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only + * have one value here we set the number of checks to 64 which is the 128 bit + * security level that is the highest level and valid for creating a 3072 bit + * DSA key. + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DSA_get0_p(const DSA *d); +const BIGNUM *DSA_get0_q(const DSA *d); +const BIGNUM *DSA_get0_g(const DSA *d); +const BIGNUM *DSA_get0_pub_key(const DSA *d); +const BIGNUM *DSA_get0_priv_key(const DSA *d); +void DSA_clear_flags(DSA *d, int flags); +int DSA_test_flags(const DSA *d, int flags); +void DSA_set_flags(DSA *d, int flags); +ENGINE *DSA_get0_engine(DSA *d); + +DSA_METHOD *DSA_meth_new(const char *name, int flags); +void DSA_meth_free(DSA_METHOD *dsam); +DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam); +const char *DSA_meth_get0_name(const DSA_METHOD *dsam); +int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name); +int DSA_meth_get_flags(const DSA_METHOD *dsam); +int DSA_meth_set_flags(DSA_METHOD *dsam, int flags); +void *DSA_meth_get0_app_data(const DSA_METHOD *dsam); +int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data); +DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA *); +int DSA_meth_set_sign(DSA_METHOD *dsam, + DSA_SIG *(*sign) (const unsigned char *, int, DSA *)); +int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam)) + (DSA *, BN_CTX *, BIGNUM **, BIGNUM **); +int DSA_meth_set_sign_setup(DSA_METHOD *dsam, + int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **)); +int (*DSA_meth_get_verify(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA_SIG *, DSA *); +int DSA_meth_set_verify(DSA_METHOD *dsam, + int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *)); +int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_mod_exp(DSA_METHOD *dsam, + int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, + BN_MONT_CTX *)); +int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam, + int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *); +int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *)); +int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *)); +int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam)) + (DSA *, int, const unsigned char *, int, int *, unsigned long *, + BN_GENCB *); +int DSA_meth_set_paramgen(DSA_METHOD *dsam, + int (*paramgen) (DSA *, int, const unsigned char *, int, int *, + unsigned long *, BN_GENCB *)); +int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *)); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsaerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsaerr.h new file mode 100644 index 00000000..495a1ac8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dsaerr.h @@ -0,0 +1,72 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSAERR_H +# define HEADER_DSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DSA + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DSA_strings(void); + +/* + * DSA function codes. + */ +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_BUILTIN_PARAMGEN 125 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_METH_DUP 127 +# define DSA_F_DSA_METH_NEW 128 +# define DSA_F_DSA_METH_SET1_NAME 129 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 102 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_CTRL_STR 104 +# define DSA_F_PKEY_DSA_KEYGEN 121 + +/* + * DSA reason codes. + */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MISSING_PRIVATE_KEY 111 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 +# define DSA_R_Q_NOT_PRIME 113 +# define DSA_R_SEED_LEN_SMALL 110 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dtls1.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dtls1.h new file mode 100644 index 00000000..d55ca9c3 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/dtls1.h @@ -0,0 +1,55 @@ +/* + * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS1_2_VERSION 0xFEFD +# define DTLS_MIN_VERSION DTLS1_VERSION +# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +/* Special value for method supporting multiple versions */ +# define DTLS_ANY_VERSION 0x1FFFF + +/* lengths of messages */ +/* + * Actually the max cookie length in DTLS is 255. But we can't change this now + * due to compatibility concerns. + */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# define DTLS1_AL_HEADER_LENGTH 2 + +/* Timeout multipliers */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/e_os2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/e_os2.h new file mode 100644 index 00000000..97a776cd --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/e_os2.h @@ -0,0 +1,300 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYS_MSDOS) +# undef OPENSSL_SYS_UNIX +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +/* + * UEFI lives here because it might be built with a Microsoft toolchain and + * we need to avoid the false positive match on Windows. + */ +# if defined(OPENSSL_SYS_UEFI) +# undef OPENSSL_SYS_UNIX +# elif defined(OPENSSL_SYS_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN__) || defined(OPENSSL_SYS_CYGWIN) +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYS_WIN32) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN32) +# define OPENSSL_SYS_WIN32 +# endif +# endif +# if defined(_WIN64) || defined(OPENSSL_SYS_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYS_WINNT) +# undef OPENSSL_SYS_UNIX +# endif +# if defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYS_VMS) +# if !defined(OPENSSL_SYS_VMS) +# undef OPENSSL_SYS_UNIX +# endif +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) && !defined(OPENSSL_SYS_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# if defined(_AIX) && !defined(OPENSSL_SYS_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) && !defined(OPENSSL_SYS_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * OPENSSL_EXTERN is normally used to declare a symbol with possible extra + * attributes to handle its presence in a shared library. + * OPENSSL_EXPORT is used to define a symbol with extra possible attributes + * to make it visible in a shared library. + * Care needs to be taken when a header file is used both to declare and + * define symbols. Basically, for any library that exports some global + * variables, the following code must be present in the header file that + * declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT and OPENSSL_EXTERN + * have some generally sensible values. + */ + +# if defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_EXTERN extern __declspec(dllimport) +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_EXTERN extern +# endif + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# ifdef _WIN32 +# ifdef _WIN64 +# define ossl_ssize_t __int64 +# define OSSL_SSIZE_MAX _I64_MAX +# else +# define ossl_ssize_t int +# define OSSL_SSIZE_MAX INT_MAX +# endif +# endif + +# if defined(OPENSSL_SYS_UEFI) && !defined(ossl_ssize_t) +# define ossl_ssize_t INTN +# define OSSL_SSIZE_MAX MAX_INTN +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# if defined(SSIZE_MAX) +# define OSSL_SSIZE_MAX SSIZE_MAX +# elif defined(_POSIX_SSIZE_MAX) +# define OSSL_SSIZE_MAX _POSIX_SSIZE_MAX +# else +# define OSSL_SSIZE_MAX ((ssize_t)(SIZE_MAX>>1)) +# endif +# endif + +# ifdef DEBUG_UNUSED +# define __owur __attribute__((__warn_unused_result__)) +# else +# define __owur +# endif + +/* Standard integer types */ +# if defined(OPENSSL_SYS_UEFI) +typedef INT8 int8_t; +typedef UINT8 uint8_t; +typedef INT16 int16_t; +typedef UINT16 uint16_t; +typedef INT32 int32_t; +typedef UINT32 uint32_t; +typedef INT64 int64_t; +typedef UINT64 uint64_t; +# elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + defined(__osf__) || defined(__sgi) || defined(__hpux) || \ + defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__) +# include +# elif defined(_MSC_VER) && _MSC_VER<=1500 +/* + * minimally required typdefs for systems not supporting inttypes.h or + * stdint.h: currently just older VC++ + */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +# else +# include +# endif + +/* ossl_inline: portable inline definition usable in public headers */ +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* just use inline */ +# define ossl_inline inline +# elif defined(__GNUC__) && __GNUC__>=2 +# define ossl_inline __inline__ +# elif defined(_MSC_VER) + /* + * Visual Studio: inline is available in C++ only, however + * __inline is available for C, see + * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + */ +# define ossl_inline __inline +# else +# define ossl_inline +# endif +# else +# define ossl_inline inline +# endif + +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define ossl_noreturn _Noreturn +# elif defined(__GNUC__) && __GNUC__ >= 2 +# define ossl_noreturn __attribute__((noreturn)) +# else +# define ossl_noreturn +# endif + +/* ossl_unused: portable unused attribute for use in public headers */ +# if defined(__GNUC__) +# define ossl_unused __attribute__((unused)) +# else +# define ossl_unused +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ebcdic.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ebcdic.h new file mode 100644 index 00000000..aa012855 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ebcdic.h @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ec.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ec.h new file mode 100644 index 00000000..5af9ebdc --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ec.h @@ -0,0 +1,1479 @@ +/* + * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include + +# ifndef OPENSSL_NO_EC +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_point_st EC_POINT; +typedef struct ecpk_parameters_st ECPKPARAMETERS; +typedef struct ec_parameters_st ECPARAMETERS; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and its order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used montgomery data (possibly NULL). +*/ +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the order of an EC_GROUP + * \param group EC_GROUP object + * \return the group order + */ +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +/** Gets the number of bits of the order of an EC_GROUP + * \param group EC_GROUP object + * \return number of bits of group order. + */ +int EC_GROUP_order_bits(const EC_GROUP *group); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Gets the cofactor of an EC_GROUP + * \param group EC_GROUP object + * \return the group cofactor + */ +const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameters of a ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameters of the ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx); + +/** Sets the parameters of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if the groups are equal, 1 if not, or -1 on error + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif + +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/** Creates a new EC_GROUP object from an ECPARAMETERS object + * \param params pointer to the ECPARAMETERS object + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params); + +/** Creates an ECPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPARAMETERS object or NULL + * \return pointer to the new ECPARAMETERS object or NULL + * if an error occurred. + */ +ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, + ECPARAMETERS *params); + +/** Creates a new EC_GROUP object from an ECPKPARAMETERS object + * \param params pointer to an existing ECPKPARAMETERS object, or NULL + * \return newly created EC_GROUP object with specified curve, or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params); + +/** Creates an ECPKPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPKPARAMETERS object or NULL + * \return pointer to the new ECPKPARAMETERS object or NULL + * if an error occurred. + */ +ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, + ECPKPARAMETERS *params); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r is not zero, + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of an EC_POINT. + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, + BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Encodes an EC_POINT object to an allocated octet string + * \param group underlying EC_GROUP object + * \param point EC_POINT object + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if the point is on the curve, 0 if not, or -1 on error + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 if the points are not equal, 0 if they are, or -1 on error + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number further summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +DECLARE_ASN1_ITEM(ECPKPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPKPARAMETERS) +DECLARE_ASN1_ITEM(ECPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_EXPLICIT_CURVE 0x000 +# define OPENSSL_EC_NAMED_CURVE 0x001 + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# ifndef OPENSSL_NO_STDIO +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 +# define EC_FLAG_COFACTOR_ECDH 0x1000 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the ENGINE object of a EC_KEY object + * \param eckey EC_KEY object + * \return the ENGINE object (possibly NULL). + */ +ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); + +#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef) +int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg); +void *EC_KEY_get_ex_data(const EC_KEY *key, int idx); + +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Indicates if an EC_KEY can be used for signing. + * \param eckey the EC_KEY object + * \return 1 if can can sign and 0 otherwise. + */ +int EC_KEY_can_sign(const EC_KEY *eckey); + +/** Sets a public key from affine coordinates performing + * necessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/** Encodes an EC_KEY public key to an allocated octet string + * \param key key to encode + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/** Decodes a EC_KEY public key from a octet string + * \param key key to decode + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, + BN_CTX *ctx); + +/** Decodes an EC_KEY private key from an octet string + * \param key key to decode + * \param buf memory buffer with the encoded private key + * \param len length of the encoded key + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2priv(EC_KEY *key, const unsigned char *buf, size_t len); + +/** Encodes a EC_KEY private key to an octet string + * \param key key to encode + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len); + +/** Encodes an EC_KEY private key to an allocated octet string + * \param eckey key to encode + * \param pbuf returns pointer to allocated buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec parameters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out); + +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# ifndef OPENSSL_NO_STDIO +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +const EC_KEY_METHOD *EC_KEY_OpenSSL(void); +const EC_KEY_METHOD *EC_KEY_get_default_method(void); +void EC_KEY_set_default_method(const EC_KEY_METHOD *meth); +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key); +int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); +EC_KEY *EC_KEY_new_method(ENGINE *engine); + +/** The old name for ecdh_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + const EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +typedef struct ECDSA_SIG_st ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or a negative value + * on error + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Accessor for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param pr pointer to BIGNUM pointer for r (may be NULL) + * \param ps pointer to BIGNUM pointer for s (may be NULL) + */ +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); + +/** Accessor for r field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); + +/** Accessor for s field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); + +/** Setter for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param r pointer to BIGNUM for r (may be NULL) + * \param s pointer to BIGNUM for s (may be NULL) + */ +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/********************************************************************/ +/* EC_KEY_METHOD constructors, destructors, writers and accessors */ +/********************************************************************/ + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth); +void EC_KEY_METHOD_free(EC_KEY_METHOD *meth); +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, + int (*keygen)(EC_KEY *key)); + +void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, + int (**pinit)(EC_KEY *key), + void (**pfinish)(EC_KEY *key), + int (**pcopy)(EC_KEY *dest, const EC_KEY *src), + int (**pset_group)(EC_KEY *key, + const EC_GROUP *grp), + int (**pset_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (**pset_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)); + +void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, + int (**pck)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, + int (**psign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \ + (void *)(plen)) + +# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p)) + +/* SM2 will skip the operation check so no need to pass operation here */ +# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id(ctx, id) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) +/* KDF types */ +# define EVP_PKEY_ECDH_KDF_NONE 1 +# define EVP_PKEY_ECDH_KDF_X9_63 2 +/** The old name for EVP_PKEY_ECDH_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +# define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63 + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdh.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdh.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdh.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdsa.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdsa.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecdsa.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecerr.h new file mode 100644 index 00000000..f7b91834 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ecerr.h @@ -0,0 +1,275 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ECERR_H +# define HEADER_ECERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_EC + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EC_strings(void); + +/* + * EC function codes. + */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECDH_CMS_DECRYPT 238 +# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 +# define EC_F_ECDH_COMPUTE_KEY 246 +# define EC_F_ECDH_SIMPLE_COMPUTE_KEY 257 +# define EC_F_ECDSA_DO_SIGN_EX 251 +# define EC_F_ECDSA_DO_VERIFY 252 +# define EC_F_ECDSA_SIGN_EX 254 +# define EC_F_ECDSA_SIGN_SETUP 248 +# define EC_F_ECDSA_SIG_NEW 265 +# define EC_F_ECDSA_VERIFY 253 +# define EC_F_ECD_ITEM_VERIFY 270 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NISTZ256_GET_AFFINE 240 +# define EC_F_ECP_NISTZ256_INV_MOD_ORD 275 +# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +# define EC_F_ECP_NISTZ256_POINTS_MUL 241 +# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +# define EC_F_ECX_KEY_OP 266 +# define EC_F_ECX_PRIV_ENCODE 267 +# define EC_F_ECX_PUB_ENCODE 268 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_FIELD_INV 296 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_LADDER_POST 285 +# define EC_F_EC_GF2M_SIMPLE_LADDER_PRE 288 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINTS_MUL 289 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_INV 297 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES 287 +# define EC_F_EC_GFP_SIMPLE_FIELD_INV 298 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET_CURVE 291 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ECPARAMETERS 261 +# define EC_F_EC_GROUP_GET_ECPKPARAMETERS 262 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS 263 +# define EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS 264 +# define EC_F_EC_GROUP_SET_CURVE 292 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_GROUP_SET_SEED 286 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_NEW_METHOD 245 +# define EC_F_EC_KEY_OCT2PRIV 255 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_PRIV2BUF 279 +# define EC_F_EC_KEY_PRIV2OCT 256 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_KEY_SIMPLE_CHECK_KEY 258 +# define EC_F_EC_KEY_SIMPLE_OCT2PRIV 259 +# define EC_F_EC_KEY_SIMPLE_PRIV2OCT 260 +# define EC_F_EC_PKEY_CHECK 273 +# define EC_F_EC_PKEY_PARAM_CHECK 274 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINTS_MUL 290 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_BN2POINT 280 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES 293 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2BUF 281 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES 294 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES 295 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_SCALAR_MUL_LADDER 284 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_OSSL_ECDH_COMPUTE_KEY 247 +# define EC_F_OSSL_ECDSA_SIGN_SIG 249 +# define EC_F_OSSL_ECDSA_VERIFY_SIG 250 +# define EC_F_PKEY_ECD_CTRL 271 +# define EC_F_PKEY_ECD_DIGESTSIGN 272 +# define EC_F_PKEY_ECD_DIGESTSIGN25519 276 +# define EC_F_PKEY_ECD_DIGESTSIGN448 277 +# define EC_F_PKEY_ECX_DERIVE 269 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_INIT 282 +# define EC_F_PKEY_EC_KDF_DERIVE 283 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 +# define EC_F_VALIDATE_ECX_DERIVE 278 + +/* + * EC reason codes. + */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_BAD_SIGNATURE 156 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_CANNOT_INVERT 165 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 +# define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST 151 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_KEY 116 +# define EC_R_INVALID_OUTPUT_LENGTH 161 +# define EC_R_INVALID_PEER_KEY 133 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KDF_PARAMETER_ERROR 148 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_LADDER_POST_FAILURE 136 +# define EC_R_LADDER_PRE_FAILURE 153 +# define EC_R_LADDER_STEP_FAILURE 162 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NEED_NEW_SETUP_VALUES 157 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_NO_PRIVATE_VALUE 154 +# define EC_R_OPERATION_NOT_SUPPORTED 152 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PEER_KEY_ERROR 149 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_ARITHMETIC_FAILURE 155 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_COORDINATES_BLIND_FAILURE 163 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_RANDOM_NUMBER_GENERATION_FAILED 158 +# define EC_R_SHARED_INFO_ERROR 150 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_COFACTOR 164 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engine.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engine.h new file mode 100644 index 00000000..0780f0fb --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engine.h @@ -0,0 +1,751 @@ +/* + * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include + +# ifndef OPENSSL_NO_ENGINE +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# include +# include +# include +# include +# include +# endif +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +# define ENGINE_METHOD_EC (unsigned int)0x0800 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ENGINE_load_openssl() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_OPENSSL, NULL) +# define ENGINE_load_dynamic() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_DYNAMIC, NULL) +# ifndef OPENSSL_NO_STATIC_ENGINE +# define ENGINE_load_padlock() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_PADLOCK, NULL) +# define ENGINE_load_capi() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CAPI, NULL) +# define ENGINE_load_afalg() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_AFALG, NULL) +# endif +# define ENGINE_load_cryptodev() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL) +# define ENGINE_load_rdrand() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL) +#endif +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_EC(ENGINE *e); +void ENGINE_unregister_EC(ENGINE *e); +void ENGINE_register_all_EC(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parameterised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +#define ENGINE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, l, p, newf, dupf, freef) +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function previously cleaned up anything that needs it. Auto-deinit will + * now take care of it so it is no longer required to call this function. + */ +# define ENGINE_cleanup() while(0) continue +#endif + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_EC(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_EC(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00030000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00030000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_fn) (size_t, const char *, int); +typedef void *(*dyn_MEM_realloc_fn) (void *, size_t, const char *, int); +typedef void (*dyn_MEM_free_fn) (void *, const char *, int); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_fn malloc_fn; + dyn_MEM_realloc_fn realloc_fn; + dyn_MEM_free_fn free_fn; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependent code) can simplify a bit?? + */ +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + dynamic_MEM_fns mem_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if (v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if (ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \ + fns->mem_fns.realloc_fn, \ + fns->mem_fns.free_fn); \ + skip_cbs: \ + if (!fn(e, id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) +DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void)) +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engineerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engineerr.h new file mode 100644 index 00000000..05e84bd2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/engineerr.h @@ -0,0 +1,111 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINEERR_H +# define HEADER_ENGINEERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_ENGINE + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ENGINE_strings(void); + +/* + * ENGINE function codes. + */ +# define ENGINE_F_DIGEST_UPDATE 198 +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_FIRST 195 +# define ENGINE_F_ENGINE_GET_LAST 196 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR 197 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CLEANUP_ITEM 199 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_OSSL_HMAC_INIT 200 + +/* + * ENGINE reason codes. + */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/err.h new file mode 100644 index 00000000..b49f8812 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/err.h @@ -0,0 +1,274 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# include +# endif + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 +# define ERR_FLAG_CLEAR 0x02 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_OSSL_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +/* # define ERR_LIB_JPAKE 49 */ +# define ERR_LIB_CT 50 +# define ERR_LIB_ASYNC 51 +# define ERR_LIB_KDF 52 +# define ERR_LIB_SM2 53 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) + +# define ERR_PACK(l,f,r) ( \ + (((unsigned int)(l) & 0x0FF) << 24L) | \ + (((unsigned int)(f) & 0xFFF) << 12L) | \ + (((unsigned int)(r) & 0xFFF) ) ) +# define ERR_GET_LIB(l) (int)(((l) >> 24L) & 0x0FFL) +# define ERR_GET_FUNC(l) (int)(((l) >> 12L) & 0xFFFL) +# define ERR_GET_REASON(l) (int)( (l) & 0xFFFL) +# define ERR_FATAL_ERROR(l) (int)( (l) & ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 +# define SYS_F_GETADDRINFO 12 +# define SYS_F_GETNAMEINFO 13 +# define SYS_F_SETSOCKOPT 14 +# define SYS_F_GETSOCKOPT 15 +# define SYS_F_GETSOCKNAME 16 +# define SYS_F_GETHOSTBYNAME 17 +# define SYS_F_FFLUSH 18 +# define SYS_F_OPEN 19 +# define SYS_F_CLOSE 20 +# define SYS_F_IOCTL 21 +# define SYS_F_STAT 22 +# define SYS_F_FCNTL 23 +# define SYS_F_FSTAT 24 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_OSSL_STORE_LIB ERR_LIB_OSSL_STORE/* 44 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) +# define ERR_R_INIT_FAIL (6|ERR_R_FATAL) +# define ERR_R_PASSED_INVALID_ARGUMENT (7) +# define ERR_R_OPERATION_FAIL (8|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +DEFINE_LHASH_OF(ERR_STRING_DATA); + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +void ERR_print_errors_fp(FILE *fp); +# endif +void ERR_print_errors(BIO *bp); +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +int ERR_load_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_strings_const(const ERR_STRING_DATA *str); +int ERR_unload_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_ERR_strings(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ERR_load_crypto_strings() \ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# define ERR_free_strings() while(0) continue +#endif + +DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *)) +DEPRECATEDIN_1_0_0(void ERR_remove_state(unsigned long pid)) +ERR_STATE *ERR_get_state(void); + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); +int ERR_clear_last_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evp.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evp.h new file mode 100644 index 00000000..a411f3f2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evp.h @@ -0,0 +1,1666 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# include +# include +# include +# include +# include + +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_RSA_PSS NID_rsassaPss +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_DHX NID_dhpublicnumber +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_SM2 NID_sm2 +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac +# define EVP_PKEY_SCRYPT NID_id_scrypt +# define EVP_PKEY_TLS1_PRF NID_tls1_prf +# define EVP_PKEY_HKDF NID_hkdf +# define EVP_PKEY_POLY1305 NID_poly1305 +# define EVP_PKEY_SIPHASH NID_siphash +# define EVP_PKEY_X25519 NID_X25519 +# define EVP_PKEY_ED25519 NID_ED25519 +# define EVP_PKEY_X448 NID_X448 +# define EVP_PKEY_ED448 NID_ED448 + +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type); +EVP_MD *EVP_MD_meth_dup(const EVP_MD *md); +void EVP_MD_meth_free(EVP_MD *md); + +int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize); +int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize); +int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize); +int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags); +int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx, + const void *data, + size_t count)); +int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx, + unsigned char *md)); +int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to, + const EVP_MD_CTX *from)); +int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2)); + +int EVP_MD_meth_get_input_blocksize(const EVP_MD *md); +int EVP_MD_meth_get_result_size(const EVP_MD *md); +int EVP_MD_meth_get_app_datasize(const EVP_MD *md); +unsigned long EVP_MD_meth_get_flags(const EVP_MD *md); +int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx, + const void *data, + size_t count); +int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx, + unsigned char *md); +int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to, + const EVP_MD_CTX *from); +int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* digest is extensible-output function, XOF */ +# define EVP_MD_FLAG_XOF 0x0002 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 +# define EVP_MD_CTRL_XOF_LEN 0x3 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# endif /* !EVP_MD */ + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_reset */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ +/* + * Some functions such as EVP_DigestSign only finalise copies of internal + * contexts so additional data can be included after the finalisation call. + * This is inefficient if this functionality is not required: it is disabled + * if the following flag is set. + */ +# define EVP_MD_CTX_FLAG_FINALISE 0x0200 +/* NOTE: 0x0400 is reserved for internal usage */ + +EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); +EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); +void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); + +int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); +int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); +int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); +int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc)); +int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher) (EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl)); +int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup) (EVP_CIPHER_CTX *)); +int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl) (EVP_CIPHER_CTX *, int type, + int arg, void *ptr)); + +int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc); +int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl); +int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); +int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + int type, int arg, + void *ptr); + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_WRAP_MODE 0x10002 +# define EVP_CIPH_OCB_MODE 0x10003 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Don't use standard iv length function */ +# define EVP_CIPH_CUSTOM_IV_LENGTH 0x800 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 +/* Cipher can handle pipeline operations */ +# define EVP_CIPH_FLAG_PIPELINE 0X800000 + +/* + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. + */ + +# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_AEAD_SET_IVLEN 0x9 +# define EVP_CTRL_AEAD_GET_TAG 0x10 +# define EVP_CTRL_AEAD_SET_TAG 0x11 +# define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_CCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 +# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a +# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b +# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c + +# define EVP_CTRL_SSL3_MASTER_SECRET 0x1d + +/* EVP_CTRL_SET_SBOX takes the char * specifying S-boxes */ +# define EVP_CTRL_SET_SBOX 0x1e +/* + * EVP_CTRL_SBOX_USED takes a 'size_t' and 'char *', pointing at a + * pre-allocated buffer with specified size + */ +# define EVP_CTRL_SBOX_USED 0x1f +/* EVP_CTRL_KEY_MESH takes 'size_t' number of bytes to mesh the key after, + * 0 switches meshing off + */ +# define EVP_CTRL_KEY_MESH 0x20 +/* EVP_CTRL_BLOCK_PADDING_MODE takes the padding mode */ +# define EVP_CTRL_BLOCK_PADDING_MODE 0x21 + +/* Set the output buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS 0x22 +/* Set the input buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_BUFS 0x23 +/* Set the input buffer lengths to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 + +# define EVP_CTRL_GET_IVLEN 0x25 + +/* Padding modes */ +#define EVP_PADDING_PKCS7 1 +#define EVP_PADDING_ISO7816_4 2 +#define EVP_PADDING_ANSI923 3 +#define EVP_PADDING_ISO10126 4 +#define EVP_PADDING_ZERO 5 + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +typedef struct { + unsigned char *out; + const unsigned char *inp; + size_t len; + unsigned int interleave; +} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +/* CCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_CCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 +/* Total length of CCM IV length for TLS */ +# define EVP_CCM_TLS_IV_LEN 12 +/* Length of tag for TLS */ +# define EVP_CCM_TLS_TAG_LEN 16 +/* Length of CCM8 tag for TLS */ +# define EVP_CCM8_TLS_TAG_LEN 8 + +/* Length of tag for TLS */ +# define EVP_CHACHAPOLY_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif +# ifndef OPENSSL_NO_SIPHASH +# define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),EVP_PKEY_SIPHASH,\ + (char *)(shkey)) +# endif + +# ifndef OPENSSL_NO_POLY1305 +# define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),EVP_PKEY_POLY1305,\ + (char *)(polykey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx, + const void *data, size_t count); +void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx, + int (*update) (EVP_MD_CTX *ctx, + const void *data, size_t count)); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) +EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); +void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); +void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx); +void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_flags(c) EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(c)) +# endif +# define EVP_CIPHER_CTX_mode(c) EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(c)) + +# define EVP_ENCODE_LENGTH(l) ((((l)+2)/3*4)+((l)/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) (((l)+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)(md)) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)(mdp)) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0, \ + (char *)(c_pp)) + +/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, + const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +EVP_MD_CTX *EVP_MD_CTX_new(void); +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +# define EVP_MD_CTX_create() EVP_MD_CTX_new() +# define EVP_MD_CTX_init(ctx) EVP_MD_CTX_reset((ctx)) +# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx)) +__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +__owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); +__owur int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, + size_t cnt); +__owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, + const EVP_MD *type, ENGINE *impl); + +__owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +__owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +__owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, + size_t len); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +__owur int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, + const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); +/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); + +__owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv, int enc); +__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +__owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, + size_t tbslen); + +__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +__owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + +/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen); + +__owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen); + +# ifndef OPENSSL_NO_RSA +__owur int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, + const unsigned char *iv, EVP_PKEY *priv); +__owur int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +__owur int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +__owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +# endif + +EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void); +void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx); +int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx); +int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx); +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_init(c) EVP_CIPHER_CTX_reset(c) +# define EVP_CIPHER_CTX_cleanup(c) EVP_CIPHER_CTX_reset(c) +# endif +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +const BIO_METHOD *BIO_f_md(void); +const BIO_METHOD *BIO_f_base64(void); +const BIO_METHOD *BIO_f_cipher(void); +const BIO_METHOD *BIO_f_reliable(void); +__owur int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +const EVP_MD *EVP_md5_sha1(void); +# endif +# ifndef OPENSSL_NO_BLAKE2 +const EVP_MD *EVP_blake2b512(void); +const EVP_MD *EVP_blake2s256(void); +# endif +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +const EVP_MD *EVP_sha512_224(void); +const EVP_MD *EVP_sha512_256(void); +const EVP_MD *EVP_sha3_224(void); +const EVP_MD *EVP_sha3_256(void); +const EVP_MD *EVP_sha3_384(void); +const EVP_MD *EVP_sha3_512(void); +const EVP_MD *EVP_shake128(void); +const EVP_MD *EVP_shake256(void); +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RMD160 +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +# ifndef OPENSSL_NO_SM3 +const EVP_MD *EVP_sm3(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +const EVP_CIPHER *EVP_des_ede3_wrap(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_128_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_128_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_192_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_192_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +const EVP_CIPHER *EVP_aes_256_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_256_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); +# ifndef OPENSSL_NO_ARIA +const EVP_CIPHER *EVP_aria_128_ecb(void); +const EVP_CIPHER *EVP_aria_128_cbc(void); +const EVP_CIPHER *EVP_aria_128_cfb1(void); +const EVP_CIPHER *EVP_aria_128_cfb8(void); +const EVP_CIPHER *EVP_aria_128_cfb128(void); +# define EVP_aria_128_cfb EVP_aria_128_cfb128 +const EVP_CIPHER *EVP_aria_128_ctr(void); +const EVP_CIPHER *EVP_aria_128_ofb(void); +const EVP_CIPHER *EVP_aria_128_gcm(void); +const EVP_CIPHER *EVP_aria_128_ccm(void); +const EVP_CIPHER *EVP_aria_192_ecb(void); +const EVP_CIPHER *EVP_aria_192_cbc(void); +const EVP_CIPHER *EVP_aria_192_cfb1(void); +const EVP_CIPHER *EVP_aria_192_cfb8(void); +const EVP_CIPHER *EVP_aria_192_cfb128(void); +# define EVP_aria_192_cfb EVP_aria_192_cfb128 +const EVP_CIPHER *EVP_aria_192_ctr(void); +const EVP_CIPHER *EVP_aria_192_ofb(void); +const EVP_CIPHER *EVP_aria_192_gcm(void); +const EVP_CIPHER *EVP_aria_192_ccm(void); +const EVP_CIPHER *EVP_aria_256_ecb(void); +const EVP_CIPHER *EVP_aria_256_cbc(void); +const EVP_CIPHER *EVP_aria_256_cfb1(void); +const EVP_CIPHER *EVP_aria_256_cfb8(void); +const EVP_CIPHER *EVP_aria_256_cfb128(void); +# define EVP_aria_256_cfb EVP_aria_256_cfb128 +const EVP_CIPHER *EVP_aria_256_ctr(void); +const EVP_CIPHER *EVP_aria_256_ofb(void); +const EVP_CIPHER *EVP_aria_256_gcm(void); +const EVP_CIPHER *EVP_aria_256_ccm(void); +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_128_ctr(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ctr(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ctr(void); +# endif +# ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +# ifndef OPENSSL_NO_POLY1305 +const EVP_CIPHER *EVP_chacha20_poly1305(void); +# endif +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +# ifndef OPENSSL_NO_SM4 +const EVP_CIPHER *EVP_sm4_ecb(void); +const EVP_CIPHER *EVP_sm4_cbc(void); +const EVP_CIPHER *EVP_sm4_cfb128(void); +# define EVP_sm4_cfb EVP_sm4_cfb128 +const EVP_CIPHER *EVP_sm4_ofb(void); +const EVP_CIPHER *EVP_sm4_ctr(void); +# endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_add_all_algorithms_conf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS \ + | OPENSSL_INIT_LOAD_CONFIG, NULL) +# define OPENSSL_add_all_algorithms_noconf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf() +# endif + +# define OpenSSL_add_all_ciphers() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL) +# define OpenSSL_add_all_digests() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# define EVP_cleanup() while(0) continue +# endif + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(const EVP_PKEY *pkey); +int EVP_PKEY_security_bits(const EVP_PKEY *pkey); +int EVP_PKEY_size(const EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); +# ifndef OPENSSL_NO_ENGINE +int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e); +ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); +# endif +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(const EVP_PKEY *pkey); +const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); +# ifndef OPENSSL_NO_POLY1305 +const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); +# endif +# ifndef OPENSSL_NO_SIPHASH +const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len); +# endif + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +int EVP_PKEY_up_ref(EVP_PKEY *pkey); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const unsigned char *pt, size_t ptlen); +size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_SCRYPT +int EVP_PBE_scrypt(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); + +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de); +#endif + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 +/* Is a PKCS#5 v2.0 KDF */ +# define EVP_PBE_TYPE_KDF 0x2 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); +int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 +# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + const PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)); + +void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth, + int (*siginf_set) (X509_SIG_INFO *siginf, + const X509_ALGOR *alg, + const ASN1_STRING *sig)); + +void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_pub_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_param_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_priv_key) (EVP_PKEY *pk, + const unsigned char + *priv, + size_t len)); +void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_pub_key) (EVP_PKEY *pk, + const unsigned char *pub, + size_t len)); +void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_priv_key) (const EVP_PKEY *pk, + unsigned char *priv, + size_t *len)); +void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_pub_key) (const EVP_PKEY *pk, + unsigned char *pub, + size_t *len)); + +void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_security_bits) (const EVP_PKEY + *pk)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key)) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_CTRL_GET_MD 13 + +# define EVP_PKEY_CTRL_SET_DIGEST_SIZE 14 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth); +size_t EVP_PKEY_meth_get_count(void); +const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); +int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, uint64_t value); + +int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str); +int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex); + +int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, + const unsigned char *priv, + size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, + const unsigned char *pub, + size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len); + +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth, + int (*digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth, + int (*digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth, + int (*digest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, + int (**digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth, + int (**digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, + int (**pdigest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); +void EVP_add_alg_module(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evperr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evperr.h new file mode 100644 index 00000000..d2b26ea5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/evperr.h @@ -0,0 +1,205 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EVPERR_H +# define HEADER_EVPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EVP_strings(void); + +/* + * EVP function codes. + */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_INIT_KEY 207 +# define EVP_F_AES_GCM_CTRL 196 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_OCB_CIPHER 169 +# define EVP_F_AES_T4_INIT_KEY 178 +# define EVP_F_AES_T4_XTS_INIT_KEY 208 +# define EVP_F_AES_WRAP_CIPHER 170 +# define EVP_F_AES_XTS_INIT_KEY 209 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_ARIA_CCM_INIT_KEY 175 +# define EVP_F_ARIA_GCM_CTRL 197 +# define EVP_F_ARIA_GCM_INIT_KEY 176 +# define EVP_F_ARIA_INIT_KEY 185 +# define EVP_F_B64_NEW 198 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CHACHA20_POLY1305_CTRL 182 +# define EVP_F_CMLL_T4_INIT_KEY 179 +# define EVP_F_DES_EDE3_WRAP_CIPHER 171 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_ENC_NEW 199 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_ASN1_TO_PARAM 204 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_CIPHER_PARAM_TO_ASN1 205 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DECRYPTUPDATE 166 +# define EVP_F_EVP_DIGESTFINALXOF 174 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_ENCRYPTUPDATE 167 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PBE_SCRYPT 181 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKEY2PKCS8 113 +# define EVP_F_EVP_PKEY_ASN1_ADD0 188 +# define EVP_F_EVP_PKEY_CHECK 186 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_CTX_MD 168 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET0_DH 119 +# define EVP_F_EVP_PKEY_GET0_DSA 120 +# define EVP_F_EVP_PKEY_GET0_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET0_HMAC 183 +# define EVP_F_EVP_PKEY_GET0_POLY1305 184 +# define EVP_F_EVP_PKEY_GET0_RSA 121 +# define EVP_F_EVP_PKEY_GET0_SIPHASH 172 +# define EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY 202 +# define EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY 203 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_METH_ADD0 194 +# define EVP_F_EVP_PKEY_METH_NEW 195 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_NEW_CMAC_KEY 193 +# define EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY 191 +# define EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY 192 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_PARAM_CHECK 189 +# define EVP_F_EVP_PKEY_PUBLIC_CHECK 190 +# define EVP_F_EVP_PKEY_SET1_ENGINE 187 +# define EVP_F_EVP_PKEY_SET_ALIAS_TYPE 206 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_OK_NEW 200 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 +# define EVP_F_R_32_12_16_INIT_KEY 242 +# define EVP_F_S390X_AES_GCM_CTRL 201 +# define EVP_F_UPDATE 173 + +/* + * EVP reason codes. + */ +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ARIA_KEY_SETUP_FAILED 176 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 195 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_COPY_ERROR 173 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EXPECTING_AN_HMAC_KEY 174 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_EXPECTING_A_POLY1305_KEY 164 +# define EVP_R_EXPECTING_A_SIPHASH_KEY 175 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_GET_RAW_KEY_FAILED 182 +# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_IV_LENGTH 194 +# define EVP_R_INVALID_KEY 163 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_KEY_SETUP_FAILED 180 +# define EVP_R_MEMORY_LIMIT_EXCEEDED 172 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NOT_XOF_OR_INVALID_LENGTH 178 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_ONLY_ONESHOT_SUPPORTED 177 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PARTIALLY_OVERLAPPING 162 +# define EVP_R_PBKDF2_ERROR 181 +# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_XTS_DUPLICATED_KEYS 183 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/hmac.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/hmac.h new file mode 100644 index 00000000..458efc1d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/hmac.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include + +# include + +# if OPENSSL_API_COMPAT < 0x10200000L +# define HMAC_MAX_MD_CBLOCK 128 /* Deprecated */ +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +size_t HMAC_size(const HMAC_CTX *e); +HMAC_CTX *HMAC_CTX_new(void); +int HMAC_CTX_reset(HMAC_CTX *ctx); +void HMAC_CTX_free(HMAC_CTX *ctx); + +DEPRECATEDIN_1_1_0(__owur int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md)) + +/*__owur*/ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +/*__owur*/ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, + size_t len); +/*__owur*/ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, + unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +__owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); +const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/idea.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/idea.h new file mode 100644 index 00000000..4334f3ea --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/idea.h @@ -0,0 +1,64 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include + +# ifndef OPENSSL_NO_IDEA +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int IDEA_INT; + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *IDEA_options(void); +void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void IDEA_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define idea_options IDEA_options +# define idea_ecb_encrypt IDEA_ecb_encrypt +# define idea_set_encrypt_key IDEA_set_encrypt_key +# define idea_set_decrypt_key IDEA_set_decrypt_key +# define idea_cbc_encrypt IDEA_cbc_encrypt +# define idea_cfb64_encrypt IDEA_cfb64_encrypt +# define idea_ofb64_encrypt IDEA_ofb64_encrypt +# define idea_encrypt IDEA_encrypt +# endif + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdf.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdf.h new file mode 100644 index 00000000..5abd4c37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdf.h @@ -0,0 +1,97 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDF_H +# define HEADER_KDF_H + +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL) +# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_PASS (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_SCRYPT_SALT (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_SCRYPT_N (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SCRYPT_R (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_SCRYPT_P (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES (EVP_PKEY_ALG_CTRL + 13) + +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)(sec)) + +# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)(seed)) + +# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) + +# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) + +# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL) + +# define EVP_PKEY_CTX_set1_pbe_pass(pctx, pass, passlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_PASS, passlen, (void *)(pass)) + +# define EVP_PKEY_CTX_set1_scrypt_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set_scrypt_N(pctx, n) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_N, n) + +# define EVP_PKEY_CTX_set_scrypt_r(pctx, r) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_R, r) + +# define EVP_PKEY_CTX_set_scrypt_p(pctx, p) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_P, p) + +# define EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, maxmem_bytes) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdferr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdferr.h new file mode 100644 index 00000000..3f51bd02 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/kdferr.h @@ -0,0 +1,55 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDFERR_H +# define HEADER_KDFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_KDF_strings(void); + +/* + * KDF function codes. + */ +# define KDF_F_PKEY_HKDF_CTRL_STR 103 +# define KDF_F_PKEY_HKDF_DERIVE 102 +# define KDF_F_PKEY_HKDF_INIT 108 +# define KDF_F_PKEY_SCRYPT_CTRL_STR 104 +# define KDF_F_PKEY_SCRYPT_CTRL_UINT64 105 +# define KDF_F_PKEY_SCRYPT_DERIVE 109 +# define KDF_F_PKEY_SCRYPT_INIT 106 +# define KDF_F_PKEY_SCRYPT_SET_MEMBUF 107 +# define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 +# define KDF_F_PKEY_TLS1_PRF_DERIVE 101 +# define KDF_F_PKEY_TLS1_PRF_INIT 110 +# define KDF_F_TLS1_PRF_ALG 111 + +/* + * KDF reason codes. + */ +# define KDF_R_INVALID_DIGEST 100 +# define KDF_R_MISSING_ITERATION_COUNT 109 +# define KDF_R_MISSING_KEY 104 +# define KDF_R_MISSING_MESSAGE_DIGEST 105 +# define KDF_R_MISSING_PARAMETER 101 +# define KDF_R_MISSING_PASS 110 +# define KDF_R_MISSING_SALT 111 +# define KDF_R_MISSING_SECRET 107 +# define KDF_R_MISSING_SEED 106 +# define KDF_R_UNKNOWN_PARAMETER_TYPE 103 +# define KDF_R_VALUE_ERROR 108 +# define KDF_R_VALUE_MISSING 102 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/lhash.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/lhash.h new file mode 100644 index 00000000..2e42d727 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/lhash.h @@ -0,0 +1,241 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st OPENSSL_LH_NODE; +typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); +typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); +typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); +typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); +typedef struct lhash_st OPENSSL_LHASH; + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + + +# define LH_LOAD_MULT 256 + +int OPENSSL_LH_error(OPENSSL_LHASH *lh); +OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); +void OPENSSL_LH_free(OPENSSL_LHASH *lh); +void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); +void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); +void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); +void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); +void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); +unsigned long OPENSSL_LH_strhash(const char *c); +unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); +unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); +void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); + +# ifndef OPENSSL_NO_STDIO +void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); +# endif +void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _LHASH OPENSSL_LHASH +# define LHASH_NODE OPENSSL_LH_NODE +# define lh_error OPENSSL_LH_error +# define lh_new OPENSSL_LH_new +# define lh_free OPENSSL_LH_free +# define lh_insert OPENSSL_LH_insert +# define lh_delete OPENSSL_LH_delete +# define lh_retrieve OPENSSL_LH_retrieve +# define lh_doall OPENSSL_LH_doall +# define lh_doall_arg OPENSSL_LH_doall_arg +# define lh_strhash OPENSSL_LH_strhash +# define lh_num_items OPENSSL_LH_num_items +# ifndef OPENSSL_NO_STDIO +# define lh_stats OPENSSL_LH_stats +# define lh_node_stats OPENSSL_LH_node_stats +# define lh_node_usage_stats OPENSSL_LH_node_usage_stats +# endif +# define lh_stats_bio OPENSSL_LH_stats_bio +# define lh_node_stats_bio OPENSSL_LH_node_stats_bio +# define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DEFINE_LHASH_OF(type) \ + LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ + static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ + int (*cfn)(const type *, const type *)) \ + { \ + return (LHASH_OF(type) *) \ + OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ + } \ + static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ + { \ + OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ + { \ + return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ + { \ + OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ + } \ + static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ + void (*doall)(type *)) \ + { \ + OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ + } \ + LHASH_OF(type) + +#define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ + int_implement_lhash_doall(type, argtype, const type) + +#define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ + int_implement_lhash_doall(type, argtype, type) + +#define int_implement_lhash_doall(type, argtype, cbargtype) \ + static ossl_unused ossl_inline void \ + lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ + void (*fn)(cbargtype *, argtype *), \ + argtype *arg) \ + { \ + OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ + } \ + LHASH_OF(type) + +DEFINE_LHASH_OF(OPENSSL_STRING); +# ifdef _MSC_VER +/* + * push and pop this warning: + * warning C4090: 'function': different 'const' qualifiers + */ +# pragma warning (push) +# pragma warning (disable: 4090) +# endif + +DEFINE_LHASH_OF(OPENSSL_CSTRING); + +# ifdef _MSC_VER +# pragma warning (pop) +# endif + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_LH_new +# pragma weak OPENSSL_LH_free +# pragma weak OPENSSL_LH_insert +# pragma weak OPENSSL_LH_delete +# pragma weak OPENSSL_LH_retrieve +# pragma weak OPENSSL_LH_error +# pragma weak OPENSSL_LH_num_items +# pragma weak OPENSSL_LH_node_stats_bio +# pragma weak OPENSSL_LH_node_usage_stats_bio +# pragma weak OPENSSL_LH_stats_bio +# pragma weak OPENSSL_LH_get_down_load +# pragma weak OPENSSL_LH_set_down_load +# pragma weak OPENSSL_LH_doall +# pragma weak OPENSSL_LH_doall_arg +# endif /* __SUNPRO_C */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md2.h new file mode 100644 index 00000000..7faf8e3d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md2.h @@ -0,0 +1,44 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD2_H +# define HEADER_MD2_H + +# include + +# ifndef OPENSSL_NO_MD2 +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned char MD2_INT; + +# define MD2_DIGEST_LENGTH 16 +# define MD2_BLOCK 16 + +typedef struct MD2state_st { + unsigned int num; + unsigned char data[MD2_BLOCK]; + MD2_INT cksm[MD2_BLOCK]; + MD2_INT state[MD2_BLOCK]; +} MD2_CTX; + +const char *MD2_options(void); +int MD2_Init(MD2_CTX *c); +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); +int MD2_Final(unsigned char *md, MD2_CTX *c); +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md4.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md4.h new file mode 100644 index 00000000..940e29db --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md4.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include + +# ifndef OPENSSL_NO_MD4 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD4_LONG unsigned int + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md5.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md5.h new file mode 100644 index 00000000..2deb7721 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/md5.h @@ -0,0 +1,50 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include + +# ifndef OPENSSL_NO_MD5 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD5_LONG unsigned int + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/mdc2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/mdc2.h new file mode 100644 index 00000000..aabd2bfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/mdc2.h @@ -0,0 +1,42 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include + +#ifndef OPENSSL_NO_MDC2 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/modes.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/modes.h new file mode 100644 index 00000000..d544f98d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/modes.h @@ -0,0 +1,208 @@ +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MODES_H +# define HEADER_MODES_H + +# include + +# ifdef __cplusplus +extern "C" { +# endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); +size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); +size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); + +# ifndef OPENSSL_NO_OCB +typedef struct ocb128_context OCB128_CONTEXT; + +typedef void (*ocb128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); + +OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, + void *keyenc, void *keydec); +int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv, + size_t len, size_t taglen); +int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx); +# endif /* OPENSSL_NO_OCB */ + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/obj_mac.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/obj_mac.h new file mode 100644 index 00000000..483fc050 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/obj_mac.h @@ -0,0 +1,5198 @@ +/* + * WARNING: do not edit! + * Generated by crypto/objects/objects.pl + * + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_x509ExtAdmission "x509ExtAdmission" +#define LN_x509ExtAdmission "Professional Information or basis for Admission" +#define NID_x509ExtAdmission 1093 +#define OBJ_x509ExtAdmission OBJ_identified_organization,36L,8L,3L,3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_ieee "ieee" +#define NID_ieee 1170 +#define OBJ_ieee OBJ_identified_organization,111L + +#define SN_ieee_siswg "ieee-siswg" +#define LN_ieee_siswg "IEEE Security in Storage Working Group" +#define NID_ieee_siswg 1171 +#define OBJ_ieee_siswg OBJ_ieee,2L,1619L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_ISO_CN "ISO-CN" +#define LN_ISO_CN "ISO CN Member Body" +#define NID_ISO_CN 1140 +#define OBJ_ISO_CN OBJ_member_body,156L + +#define SN_oscca "oscca" +#define NID_oscca 1141 +#define OBJ_oscca OBJ_ISO_CN,10197L + +#define SN_sm_scheme "sm-scheme" +#define NID_sm_scheme 1142 +#define OBJ_sm_scheme OBJ_oscca,1L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_sha512_224WithRSAEncryption "RSA-SHA512/224" +#define LN_sha512_224WithRSAEncryption "sha512-224WithRSAEncryption" +#define NID_sha512_224WithRSAEncryption 1145 +#define OBJ_sha512_224WithRSAEncryption OBJ_pkcs1,15L + +#define SN_sha512_256WithRSAEncryption "RSA-SHA512/256" +#define LN_sha512_256WithRSAEncryption "sha512-256WithRSAEncryption" +#define NID_sha512_256WithRSAEncryption 1146 +#define OBJ_sha512_256WithRSAEncryption OBJ_pkcs1,16L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_smime_ct_contentCollection "id-smime-ct-contentCollection" +#define NID_id_smime_ct_contentCollection 1058 +#define OBJ_id_smime_ct_contentCollection OBJ_id_smime_ct,19L + +#define SN_id_smime_ct_authEnvelopedData "id-smime-ct-authEnvelopedData" +#define NID_id_smime_ct_authEnvelopedData 1059 +#define OBJ_id_smime_ct_authEnvelopedData OBJ_id_smime_ct,23L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_ct_xml "id-ct-xml" +#define NID_id_ct_xml 1060 +#define OBJ_id_ct_xml OBJ_id_smime_ct,28L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" +#define NID_id_smime_aa_signingCertificateV2 1086 +#define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define SN_sm2 "SM2" +#define LN_sm2 "sm2" +#define NID_sm2 1172 +#define OBJ_sm2 OBJ_sm_scheme,301L + +#define SN_sm3 "SM3" +#define LN_sm3 "sm3" +#define NID_sm3 1143 +#define OBJ_sm3 OBJ_sm_scheme,401L + +#define SN_sm3WithRSAEncryption "RSA-SM3" +#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" +#define NID_sm3WithRSAEncryption 1144 +#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define LN_hmacWithSHA512_224 "hmacWithSHA512-224" +#define NID_hmacWithSHA512_224 1193 +#define OBJ_hmacWithSHA512_224 OBJ_rsadsi,2L,12L + +#define LN_hmacWithSHA512_256 "hmacWithSHA512-256" +#define NID_hmacWithSHA512_256 1194 +#define OBJ_hmacWithSHA512_256 OBJ_rsadsi,2L,13L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcard Login" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft User Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_tlsfeature "tlsfeature" +#define LN_tlsfeature "TLS Feature" +#define NID_tlsfeature 1020 +#define OBJ_tlsfeature OBJ_id_pe,24L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_ipsec_IKE "ipsecIKE" +#define LN_ipsec_IKE "ipsec Internet Key Exchange" +#define NID_ipsec_IKE 1022 +#define OBJ_ipsec_IKE OBJ_id_kp,17L + +#define SN_capwapAC "capwapAC" +#define LN_capwapAC "Ctrl/provision WAP Access" +#define NID_capwapAC 1023 +#define OBJ_capwapAC OBJ_id_kp,18L + +#define SN_capwapWTP "capwapWTP" +#define LN_capwapWTP "Ctrl/Provision WAP Termination" +#define NID_capwapWTP 1024 +#define OBJ_capwapWTP OBJ_id_kp,19L + +#define SN_sshClient "secureShellClient" +#define LN_sshClient "SSH Client" +#define NID_sshClient 1025 +#define OBJ_sshClient OBJ_id_kp,21L + +#define SN_sshServer "secureShellServer" +#define LN_sshServer "SSH Server" +#define NID_sshServer 1026 +#define OBJ_sshServer OBJ_id_kp,22L + +#define SN_sendRouter "sendRouter" +#define LN_sendRouter "Send Router" +#define NID_sendRouter 1027 +#define OBJ_sendRouter OBJ_id_kp,23L + +#define SN_sendProxiedRouter "sendProxiedRouter" +#define LN_sendProxiedRouter "Send Proxied Router" +#define NID_sendProxiedRouter 1028 +#define OBJ_sendProxiedRouter OBJ_id_kp,24L + +#define SN_sendOwner "sendOwner" +#define LN_sendOwner "Send Owner" +#define NID_sendOwner 1029 +#define OBJ_sendOwner OBJ_id_kp,25L + +#define SN_sendProxiedOwner "sendProxiedOwner" +#define LN_sendProxiedOwner "Send Proxied Owner" +#define NID_sendProxiedOwner 1030 +#define OBJ_sendProxiedOwner OBJ_id_kp,26L + +#define SN_cmcCA "cmcCA" +#define LN_cmcCA "CMC Certificate Authority" +#define NID_cmcCA 1131 +#define OBJ_cmcCA OBJ_id_kp,27L + +#define SN_cmcRA "cmcRA" +#define LN_cmcRA "CMC Registration Authority" +#define NID_cmcRA 1132 +#define OBJ_cmcRA OBJ_id_kp,28L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_blake2b512 "BLAKE2b512" +#define LN_blake2b512 "blake2b512" +#define NID_blake2b512 1056 +#define OBJ_blake2b512 1L,3L,6L,1L,4L,1L,1722L,12L,2L,1L,16L + +#define SN_blake2s256 "BLAKE2s256" +#define LN_blake2s256 "blake2s256" +#define NID_blake2s256 1057 +#define OBJ_blake2s256 1L,3L,6L,1L,4L,1L,1722L,12L,2L,2L,8L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define LN_organizationIdentifier "organizationIdentifier" +#define NID_organizationIdentifier 1089 +#define OBJ_organizationIdentifier OBJ_X509,97L + +#define SN_countryCode3c "c3" +#define LN_countryCode3c "countryCode3c" +#define NID_countryCode3c 1090 +#define OBJ_countryCode3c OBJ_X509,98L + +#define SN_countryCode3n "n3" +#define LN_countryCode3n "countryCode3n" +#define NID_countryCode3n 1091 +#define OBJ_countryCode3n OBJ_X509,99L + +#define LN_dnsName "dnsName" +#define NID_dnsName 1092 +#define OBJ_dnsName OBJ_X509,100L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 +#define OBJ_aes_128_xts OBJ_ieee_siswg,0L,1L,1L + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 +#define OBJ_aes_256_xts OBJ_ieee_siswg,0L,1L,2L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_ocb "AES-128-OCB" +#define LN_aes_128_ocb "aes-128-ocb" +#define NID_aes_128_ocb 958 + +#define SN_aes_192_ocb "AES-192-OCB" +#define LN_aes_192_ocb "aes-192-ocb" +#define NID_aes_192_ocb 959 + +#define SN_aes_256_ocb "AES-256-OCB" +#define LN_aes_256_ocb "aes-256-ocb" +#define NID_aes_256_ocb 960 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define SN_sha512_224 "SHA512-224" +#define LN_sha512_224 "sha512-224" +#define NID_sha512_224 1094 +#define OBJ_sha512_224 OBJ_nist_hashalgs,5L + +#define SN_sha512_256 "SHA512-256" +#define LN_sha512_256 "sha512-256" +#define NID_sha512_256 1095 +#define OBJ_sha512_256 OBJ_nist_hashalgs,6L + +#define SN_sha3_224 "SHA3-224" +#define LN_sha3_224 "sha3-224" +#define NID_sha3_224 1096 +#define OBJ_sha3_224 OBJ_nist_hashalgs,7L + +#define SN_sha3_256 "SHA3-256" +#define LN_sha3_256 "sha3-256" +#define NID_sha3_256 1097 +#define OBJ_sha3_256 OBJ_nist_hashalgs,8L + +#define SN_sha3_384 "SHA3-384" +#define LN_sha3_384 "sha3-384" +#define NID_sha3_384 1098 +#define OBJ_sha3_384 OBJ_nist_hashalgs,9L + +#define SN_sha3_512 "SHA3-512" +#define LN_sha3_512 "sha3-512" +#define NID_sha3_512 1099 +#define OBJ_sha3_512 OBJ_nist_hashalgs,10L + +#define SN_shake128 "SHAKE128" +#define LN_shake128 "shake128" +#define NID_shake128 1100 +#define OBJ_shake128 OBJ_nist_hashalgs,11L + +#define SN_shake256 "SHAKE256" +#define LN_shake256 "shake256" +#define NID_shake256 1101 +#define OBJ_shake256 OBJ_nist_hashalgs,12L + +#define SN_hmac_sha3_224 "id-hmacWithSHA3-224" +#define LN_hmac_sha3_224 "hmac-sha3-224" +#define NID_hmac_sha3_224 1102 +#define OBJ_hmac_sha3_224 OBJ_nist_hashalgs,13L + +#define SN_hmac_sha3_256 "id-hmacWithSHA3-256" +#define LN_hmac_sha3_256 "hmac-sha3-256" +#define NID_hmac_sha3_256 1103 +#define OBJ_hmac_sha3_256 OBJ_nist_hashalgs,14L + +#define SN_hmac_sha3_384 "id-hmacWithSHA3-384" +#define LN_hmac_sha3_384 "hmac-sha3-384" +#define NID_hmac_sha3_384 1104 +#define OBJ_hmac_sha3_384 OBJ_nist_hashalgs,15L + +#define SN_hmac_sha3_512 "id-hmacWithSHA3-512" +#define LN_hmac_sha3_512 "hmac-sha3-512" +#define NID_hmac_sha3_512 1105 +#define OBJ_hmac_sha3_512 OBJ_nist_hashalgs,16L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define OBJ_sigAlgs OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA384 "id-dsa-with-sha384" +#define LN_dsa_with_SHA384 "dsa_with_SHA384" +#define NID_dsa_with_SHA384 1106 +#define OBJ_dsa_with_SHA384 OBJ_sigAlgs,3L + +#define SN_dsa_with_SHA512 "id-dsa-with-sha512" +#define LN_dsa_with_SHA512 "dsa_with_SHA512" +#define NID_dsa_with_SHA512 1107 +#define OBJ_dsa_with_SHA512 OBJ_sigAlgs,4L + +#define SN_dsa_with_SHA3_224 "id-dsa-with-sha3-224" +#define LN_dsa_with_SHA3_224 "dsa_with_SHA3-224" +#define NID_dsa_with_SHA3_224 1108 +#define OBJ_dsa_with_SHA3_224 OBJ_sigAlgs,5L + +#define SN_dsa_with_SHA3_256 "id-dsa-with-sha3-256" +#define LN_dsa_with_SHA3_256 "dsa_with_SHA3-256" +#define NID_dsa_with_SHA3_256 1109 +#define OBJ_dsa_with_SHA3_256 OBJ_sigAlgs,6L + +#define SN_dsa_with_SHA3_384 "id-dsa-with-sha3-384" +#define LN_dsa_with_SHA3_384 "dsa_with_SHA3-384" +#define NID_dsa_with_SHA3_384 1110 +#define OBJ_dsa_with_SHA3_384 OBJ_sigAlgs,7L + +#define SN_dsa_with_SHA3_512 "id-dsa-with-sha3-512" +#define LN_dsa_with_SHA3_512 "dsa_with_SHA3-512" +#define NID_dsa_with_SHA3_512 1111 +#define OBJ_dsa_with_SHA3_512 OBJ_sigAlgs,8L + +#define SN_ecdsa_with_SHA3_224 "id-ecdsa-with-sha3-224" +#define LN_ecdsa_with_SHA3_224 "ecdsa_with_SHA3-224" +#define NID_ecdsa_with_SHA3_224 1112 +#define OBJ_ecdsa_with_SHA3_224 OBJ_sigAlgs,9L + +#define SN_ecdsa_with_SHA3_256 "id-ecdsa-with-sha3-256" +#define LN_ecdsa_with_SHA3_256 "ecdsa_with_SHA3-256" +#define NID_ecdsa_with_SHA3_256 1113 +#define OBJ_ecdsa_with_SHA3_256 OBJ_sigAlgs,10L + +#define SN_ecdsa_with_SHA3_384 "id-ecdsa-with-sha3-384" +#define LN_ecdsa_with_SHA3_384 "ecdsa_with_SHA3-384" +#define NID_ecdsa_with_SHA3_384 1114 +#define OBJ_ecdsa_with_SHA3_384 OBJ_sigAlgs,11L + +#define SN_ecdsa_with_SHA3_512 "id-ecdsa-with-sha3-512" +#define LN_ecdsa_with_SHA3_512 "ecdsa_with_SHA3-512" +#define NID_ecdsa_with_SHA3_512 1115 +#define OBJ_ecdsa_with_SHA3_512 OBJ_sigAlgs,12L + +#define SN_RSA_SHA3_224 "id-rsassa-pkcs1-v1_5-with-sha3-224" +#define LN_RSA_SHA3_224 "RSA-SHA3-224" +#define NID_RSA_SHA3_224 1116 +#define OBJ_RSA_SHA3_224 OBJ_sigAlgs,13L + +#define SN_RSA_SHA3_256 "id-rsassa-pkcs1-v1_5-with-sha3-256" +#define LN_RSA_SHA3_256 "RSA-SHA3-256" +#define NID_RSA_SHA3_256 1117 +#define OBJ_RSA_SHA3_256 OBJ_sigAlgs,14L + +#define SN_RSA_SHA3_384 "id-rsassa-pkcs1-v1_5-with-sha3-384" +#define LN_RSA_SHA3_384 "RSA-SHA3-384" +#define NID_RSA_SHA3_384 1118 +#define OBJ_RSA_SHA3_384 OBJ_sigAlgs,15L + +#define SN_RSA_SHA3_512 "id-rsassa-pkcs1-v1_5-with-sha3-512" +#define LN_RSA_SHA3_512 "RSA-SHA3-512" +#define NID_RSA_SHA3_512 1119 +#define OBJ_RSA_SHA3_512 OBJ_sigAlgs,16L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define SN_uniqueIdentifier "uid" +#define LN_uniqueIdentifier "uniqueIdentifier" +#define NID_uniqueIdentifier 102 +#define OBJ_uniqueIdentifier OBJ_pilotAttributeType,44L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_tc26 "id-tc26" +#define NID_id_tc26 974 +#define OBJ_id_tc26 OBJ_member_body,643L,7L,1L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_gost89_cnt_12 "gost89-cnt-12" +#define NID_gost89_cnt_12 975 + +#define SN_gost89_cbc "gost89-cbc" +#define NID_gost89_cbc 1009 + +#define SN_gost89_ecb "gost89-ecb" +#define NID_gost89_ecb 1010 + +#define SN_gost89_ctr "gost89-ctr" +#define NID_gost89_ctr 1011 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_gost_mac_12 "gost-mac-12" +#define NID_gost_mac_12 976 + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_id_tc26_algorithms "id-tc26-algorithms" +#define NID_id_tc26_algorithms 977 +#define OBJ_id_tc26_algorithms OBJ_id_tc26,1L + +#define SN_id_tc26_sign "id-tc26-sign" +#define NID_id_tc26_sign 978 +#define OBJ_id_tc26_sign OBJ_id_tc26_algorithms,1L + +#define SN_id_GostR3410_2012_256 "gost2012_256" +#define LN_id_GostR3410_2012_256 "GOST R 34.10-2012 with 256 bit modulus" +#define NID_id_GostR3410_2012_256 979 +#define OBJ_id_GostR3410_2012_256 OBJ_id_tc26_sign,1L + +#define SN_id_GostR3410_2012_512 "gost2012_512" +#define LN_id_GostR3410_2012_512 "GOST R 34.10-2012 with 512 bit modulus" +#define NID_id_GostR3410_2012_512 980 +#define OBJ_id_GostR3410_2012_512 OBJ_id_tc26_sign,2L + +#define SN_id_tc26_digest "id-tc26-digest" +#define NID_id_tc26_digest 981 +#define OBJ_id_tc26_digest OBJ_id_tc26_algorithms,2L + +#define SN_id_GostR3411_2012_256 "md_gost12_256" +#define LN_id_GostR3411_2012_256 "GOST R 34.11-2012 with 256 bit hash" +#define NID_id_GostR3411_2012_256 982 +#define OBJ_id_GostR3411_2012_256 OBJ_id_tc26_digest,2L + +#define SN_id_GostR3411_2012_512 "md_gost12_512" +#define LN_id_GostR3411_2012_512 "GOST R 34.11-2012 with 512 bit hash" +#define NID_id_GostR3411_2012_512 983 +#define OBJ_id_GostR3411_2012_512 OBJ_id_tc26_digest,3L + +#define SN_id_tc26_signwithdigest "id-tc26-signwithdigest" +#define NID_id_tc26_signwithdigest 984 +#define OBJ_id_tc26_signwithdigest OBJ_id_tc26_algorithms,3L + +#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" +#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_256 985 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_id_tc26_signwithdigest,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" +#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_512 986 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_id_tc26_signwithdigest,3L + +#define SN_id_tc26_mac "id-tc26-mac" +#define NID_id_tc26_mac 987 +#define OBJ_id_tc26_mac OBJ_id_tc26_algorithms,4L + +#define SN_id_tc26_hmac_gost_3411_2012_256 "id-tc26-hmac-gost-3411-2012-256" +#define LN_id_tc26_hmac_gost_3411_2012_256 "HMAC GOST 34.11-2012 256 bit" +#define NID_id_tc26_hmac_gost_3411_2012_256 988 +#define OBJ_id_tc26_hmac_gost_3411_2012_256 OBJ_id_tc26_mac,1L + +#define SN_id_tc26_hmac_gost_3411_2012_512 "id-tc26-hmac-gost-3411-2012-512" +#define LN_id_tc26_hmac_gost_3411_2012_512 "HMAC GOST 34.11-2012 512 bit" +#define NID_id_tc26_hmac_gost_3411_2012_512 989 +#define OBJ_id_tc26_hmac_gost_3411_2012_512 OBJ_id_tc26_mac,2L + +#define SN_id_tc26_cipher "id-tc26-cipher" +#define NID_id_tc26_cipher 990 +#define OBJ_id_tc26_cipher OBJ_id_tc26_algorithms,5L + +#define SN_id_tc26_cipher_gostr3412_2015_magma "id-tc26-cipher-gostr3412-2015-magma" +#define NID_id_tc26_cipher_gostr3412_2015_magma 1173 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma OBJ_id_tc26_cipher,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm "id-tc26-cipher-gostr3412-2015-magma-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1174 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_magma,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1175 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_magma,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik "id-tc26-cipher-gostr3412-2015-kuznyechik" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik 1176 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik OBJ_id_tc26_cipher,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1177 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1178 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,2L + +#define SN_id_tc26_agreement "id-tc26-agreement" +#define NID_id_tc26_agreement 991 +#define OBJ_id_tc26_agreement OBJ_id_tc26_algorithms,6L + +#define SN_id_tc26_agreement_gost_3410_2012_256 "id-tc26-agreement-gost-3410-2012-256" +#define NID_id_tc26_agreement_gost_3410_2012_256 992 +#define OBJ_id_tc26_agreement_gost_3410_2012_256 OBJ_id_tc26_agreement,1L + +#define SN_id_tc26_agreement_gost_3410_2012_512 "id-tc26-agreement-gost-3410-2012-512" +#define NID_id_tc26_agreement_gost_3410_2012_512 993 +#define OBJ_id_tc26_agreement_gost_3410_2012_512 OBJ_id_tc26_agreement,2L + +#define SN_id_tc26_wrap "id-tc26-wrap" +#define NID_id_tc26_wrap 1179 +#define OBJ_id_tc26_wrap OBJ_id_tc26_algorithms,7L + +#define SN_id_tc26_wrap_gostr3412_2015_magma "id-tc26-wrap-gostr3412-2015-magma" +#define NID_id_tc26_wrap_gostr3412_2015_magma 1180 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma OBJ_id_tc26_wrap,1L + +#define SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 "id-tc26-wrap-gostr3412-2015-magma-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 1181 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_magma,1L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik "id-tc26-wrap-gostr3412-2015-kuznyechik" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik 1182 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik OBJ_id_tc26_wrap,2L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1183 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_constants "id-tc26-constants" +#define NID_id_tc26_constants 994 +#define OBJ_id_tc26_constants OBJ_id_tc26,2L + +#define SN_id_tc26_sign_constants "id-tc26-sign-constants" +#define NID_id_tc26_sign_constants 995 +#define OBJ_id_tc26_sign_constants OBJ_id_tc26_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_constants "id-tc26-gost-3410-2012-256-constants" +#define NID_id_tc26_gost_3410_2012_256_constants 1147 +#define OBJ_id_tc26_gost_3410_2012_256_constants OBJ_id_tc26_sign_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetA "id-tc26-gost-3410-2012-256-paramSetA" +#define LN_id_tc26_gost_3410_2012_256_paramSetA "GOST R 34.10-2012 (256 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_256_paramSetA 1148 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetA OBJ_id_tc26_gost_3410_2012_256_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetB "id-tc26-gost-3410-2012-256-paramSetB" +#define LN_id_tc26_gost_3410_2012_256_paramSetB "GOST R 34.10-2012 (256 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_256_paramSetB 1184 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetB OBJ_id_tc26_gost_3410_2012_256_constants,2L + +#define SN_id_tc26_gost_3410_2012_256_paramSetC "id-tc26-gost-3410-2012-256-paramSetC" +#define LN_id_tc26_gost_3410_2012_256_paramSetC "GOST R 34.10-2012 (256 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_256_paramSetC 1185 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetC OBJ_id_tc26_gost_3410_2012_256_constants,3L + +#define SN_id_tc26_gost_3410_2012_256_paramSetD "id-tc26-gost-3410-2012-256-paramSetD" +#define LN_id_tc26_gost_3410_2012_256_paramSetD "GOST R 34.10-2012 (256 bit) ParamSet D" +#define NID_id_tc26_gost_3410_2012_256_paramSetD 1186 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetD OBJ_id_tc26_gost_3410_2012_256_constants,4L + +#define SN_id_tc26_gost_3410_2012_512_constants "id-tc26-gost-3410-2012-512-constants" +#define NID_id_tc26_gost_3410_2012_512_constants 996 +#define OBJ_id_tc26_gost_3410_2012_512_constants OBJ_id_tc26_sign_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetTest "id-tc26-gost-3410-2012-512-paramSetTest" +#define LN_id_tc26_gost_3410_2012_512_paramSetTest "GOST R 34.10-2012 (512 bit) testing parameter set" +#define NID_id_tc26_gost_3410_2012_512_paramSetTest 997 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetTest OBJ_id_tc26_gost_3410_2012_512_constants,0L + +#define SN_id_tc26_gost_3410_2012_512_paramSetA "id-tc26-gost-3410-2012-512-paramSetA" +#define LN_id_tc26_gost_3410_2012_512_paramSetA "GOST R 34.10-2012 (512 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_512_paramSetA 998 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetA OBJ_id_tc26_gost_3410_2012_512_constants,1L + +#define SN_id_tc26_gost_3410_2012_512_paramSetB "id-tc26-gost-3410-2012-512-paramSetB" +#define LN_id_tc26_gost_3410_2012_512_paramSetB "GOST R 34.10-2012 (512 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_512_paramSetB 999 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetB OBJ_id_tc26_gost_3410_2012_512_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetC "id-tc26-gost-3410-2012-512-paramSetC" +#define LN_id_tc26_gost_3410_2012_512_paramSetC "GOST R 34.10-2012 (512 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_512_paramSetC 1149 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetC OBJ_id_tc26_gost_3410_2012_512_constants,3L + +#define SN_id_tc26_digest_constants "id-tc26-digest-constants" +#define NID_id_tc26_digest_constants 1000 +#define OBJ_id_tc26_digest_constants OBJ_id_tc26_constants,2L + +#define SN_id_tc26_cipher_constants "id-tc26-cipher-constants" +#define NID_id_tc26_cipher_constants 1001 +#define OBJ_id_tc26_cipher_constants OBJ_id_tc26_constants,5L + +#define SN_id_tc26_gost_28147_constants "id-tc26-gost-28147-constants" +#define NID_id_tc26_gost_28147_constants 1002 +#define OBJ_id_tc26_gost_28147_constants OBJ_id_tc26_cipher_constants,1L + +#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" +#define LN_id_tc26_gost_28147_param_Z "GOST 28147-89 TC26 parameter set" +#define NID_id_tc26_gost_28147_param_Z 1003 +#define OBJ_id_tc26_gost_28147_param_Z OBJ_id_tc26_gost_28147_constants,1L + +#define SN_INN "INN" +#define LN_INN "INN" +#define NID_INN 1004 +#define OBJ_INN OBJ_member_body,643L,3L,131L,1L,1L + +#define SN_OGRN "OGRN" +#define LN_OGRN "OGRN" +#define NID_OGRN 1005 +#define OBJ_OGRN OBJ_member_body,643L,100L,1L + +#define SN_SNILS "SNILS" +#define LN_SNILS "SNILS" +#define NID_SNILS 1006 +#define OBJ_SNILS OBJ_member_body,643L,100L,3L + +#define SN_subjectSignTool "subjectSignTool" +#define LN_subjectSignTool "Signing Tool of Subject" +#define NID_subjectSignTool 1007 +#define OBJ_subjectSignTool OBJ_member_body,643L,100L,111L + +#define SN_issuerSignTool "issuerSignTool" +#define LN_issuerSignTool "Signing Tool of Issuer" +#define NID_issuerSignTool 1008 +#define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L + +#define SN_grasshopper_ecb "grasshopper-ecb" +#define NID_grasshopper_ecb 1012 + +#define SN_grasshopper_ctr "grasshopper-ctr" +#define NID_grasshopper_ctr 1013 + +#define SN_grasshopper_ofb "grasshopper-ofb" +#define NID_grasshopper_ofb 1014 + +#define SN_grasshopper_cbc "grasshopper-cbc" +#define NID_grasshopper_cbc 1015 + +#define SN_grasshopper_cfb "grasshopper-cfb" +#define NID_grasshopper_cfb 1016 + +#define SN_grasshopper_mac "grasshopper-mac" +#define NID_grasshopper_mac 1017 + +#define SN_magma_ecb "magma-ecb" +#define NID_magma_ecb 1187 + +#define SN_magma_ctr "magma-ctr" +#define NID_magma_ctr 1188 + +#define SN_magma_ofb "magma-ofb" +#define NID_magma_ofb 1189 + +#define SN_magma_cbc "magma-cbc" +#define NID_magma_cbc 1190 + +#define SN_magma_cfb "magma-cfb" +#define NID_magma_cfb 1191 + +#define SN_magma_mac "magma-mac" +#define NID_magma_mac 1192 + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_128_gcm "CAMELLIA-128-GCM" +#define LN_camellia_128_gcm "camellia-128-gcm" +#define NID_camellia_128_gcm 961 +#define OBJ_camellia_128_gcm OBJ_camellia,6L + +#define SN_camellia_128_ccm "CAMELLIA-128-CCM" +#define LN_camellia_128_ccm "camellia-128-ccm" +#define NID_camellia_128_ccm 962 +#define OBJ_camellia_128_ccm OBJ_camellia,7L + +#define SN_camellia_128_ctr "CAMELLIA-128-CTR" +#define LN_camellia_128_ctr "camellia-128-ctr" +#define NID_camellia_128_ctr 963 +#define OBJ_camellia_128_ctr OBJ_camellia,9L + +#define SN_camellia_128_cmac "CAMELLIA-128-CMAC" +#define LN_camellia_128_cmac "camellia-128-cmac" +#define NID_camellia_128_cmac 964 +#define OBJ_camellia_128_cmac OBJ_camellia,10L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_192_gcm "CAMELLIA-192-GCM" +#define LN_camellia_192_gcm "camellia-192-gcm" +#define NID_camellia_192_gcm 965 +#define OBJ_camellia_192_gcm OBJ_camellia,26L + +#define SN_camellia_192_ccm "CAMELLIA-192-CCM" +#define LN_camellia_192_ccm "camellia-192-ccm" +#define NID_camellia_192_ccm 966 +#define OBJ_camellia_192_ccm OBJ_camellia,27L + +#define SN_camellia_192_ctr "CAMELLIA-192-CTR" +#define LN_camellia_192_ctr "camellia-192-ctr" +#define NID_camellia_192_ctr 967 +#define OBJ_camellia_192_ctr OBJ_camellia,29L + +#define SN_camellia_192_cmac "CAMELLIA-192-CMAC" +#define LN_camellia_192_cmac "camellia-192-cmac" +#define NID_camellia_192_cmac 968 +#define OBJ_camellia_192_cmac OBJ_camellia,30L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_256_gcm "CAMELLIA-256-GCM" +#define LN_camellia_256_gcm "camellia-256-gcm" +#define NID_camellia_256_gcm 969 +#define OBJ_camellia_256_gcm OBJ_camellia,46L + +#define SN_camellia_256_ccm "CAMELLIA-256-CCM" +#define LN_camellia_256_ccm "camellia-256-ccm" +#define NID_camellia_256_ccm 970 +#define OBJ_camellia_256_ccm OBJ_camellia,47L + +#define SN_camellia_256_ctr "CAMELLIA-256-CTR" +#define LN_camellia_256_ctr "camellia-256-ctr" +#define NID_camellia_256_ctr 971 +#define OBJ_camellia_256_ctr OBJ_camellia,49L + +#define SN_camellia_256_cmac "CAMELLIA-256-CMAC" +#define LN_camellia_256_cmac "camellia-256-cmac" +#define NID_camellia_256_cmac 972 +#define OBJ_camellia_256_cmac OBJ_camellia,50L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define OBJ_aria 1L,2L,410L,200046L,1L,1L + +#define SN_aria_128_ecb "ARIA-128-ECB" +#define LN_aria_128_ecb "aria-128-ecb" +#define NID_aria_128_ecb 1065 +#define OBJ_aria_128_ecb OBJ_aria,1L + +#define SN_aria_128_cbc "ARIA-128-CBC" +#define LN_aria_128_cbc "aria-128-cbc" +#define NID_aria_128_cbc 1066 +#define OBJ_aria_128_cbc OBJ_aria,2L + +#define SN_aria_128_cfb128 "ARIA-128-CFB" +#define LN_aria_128_cfb128 "aria-128-cfb" +#define NID_aria_128_cfb128 1067 +#define OBJ_aria_128_cfb128 OBJ_aria,3L + +#define SN_aria_128_ofb128 "ARIA-128-OFB" +#define LN_aria_128_ofb128 "aria-128-ofb" +#define NID_aria_128_ofb128 1068 +#define OBJ_aria_128_ofb128 OBJ_aria,4L + +#define SN_aria_128_ctr "ARIA-128-CTR" +#define LN_aria_128_ctr "aria-128-ctr" +#define NID_aria_128_ctr 1069 +#define OBJ_aria_128_ctr OBJ_aria,5L + +#define SN_aria_192_ecb "ARIA-192-ECB" +#define LN_aria_192_ecb "aria-192-ecb" +#define NID_aria_192_ecb 1070 +#define OBJ_aria_192_ecb OBJ_aria,6L + +#define SN_aria_192_cbc "ARIA-192-CBC" +#define LN_aria_192_cbc "aria-192-cbc" +#define NID_aria_192_cbc 1071 +#define OBJ_aria_192_cbc OBJ_aria,7L + +#define SN_aria_192_cfb128 "ARIA-192-CFB" +#define LN_aria_192_cfb128 "aria-192-cfb" +#define NID_aria_192_cfb128 1072 +#define OBJ_aria_192_cfb128 OBJ_aria,8L + +#define SN_aria_192_ofb128 "ARIA-192-OFB" +#define LN_aria_192_ofb128 "aria-192-ofb" +#define NID_aria_192_ofb128 1073 +#define OBJ_aria_192_ofb128 OBJ_aria,9L + +#define SN_aria_192_ctr "ARIA-192-CTR" +#define LN_aria_192_ctr "aria-192-ctr" +#define NID_aria_192_ctr 1074 +#define OBJ_aria_192_ctr OBJ_aria,10L + +#define SN_aria_256_ecb "ARIA-256-ECB" +#define LN_aria_256_ecb "aria-256-ecb" +#define NID_aria_256_ecb 1075 +#define OBJ_aria_256_ecb OBJ_aria,11L + +#define SN_aria_256_cbc "ARIA-256-CBC" +#define LN_aria_256_cbc "aria-256-cbc" +#define NID_aria_256_cbc 1076 +#define OBJ_aria_256_cbc OBJ_aria,12L + +#define SN_aria_256_cfb128 "ARIA-256-CFB" +#define LN_aria_256_cfb128 "aria-256-cfb" +#define NID_aria_256_cfb128 1077 +#define OBJ_aria_256_cfb128 OBJ_aria,13L + +#define SN_aria_256_ofb128 "ARIA-256-OFB" +#define LN_aria_256_ofb128 "aria-256-ofb" +#define NID_aria_256_ofb128 1078 +#define OBJ_aria_256_ofb128 OBJ_aria,14L + +#define SN_aria_256_ctr "ARIA-256-CTR" +#define LN_aria_256_ctr "aria-256-ctr" +#define NID_aria_256_ctr 1079 +#define OBJ_aria_256_ctr OBJ_aria,15L + +#define SN_aria_128_cfb1 "ARIA-128-CFB1" +#define LN_aria_128_cfb1 "aria-128-cfb1" +#define NID_aria_128_cfb1 1080 + +#define SN_aria_192_cfb1 "ARIA-192-CFB1" +#define LN_aria_192_cfb1 "aria-192-cfb1" +#define NID_aria_192_cfb1 1081 + +#define SN_aria_256_cfb1 "ARIA-256-CFB1" +#define LN_aria_256_cfb1 "aria-256-cfb1" +#define NID_aria_256_cfb1 1082 + +#define SN_aria_128_cfb8 "ARIA-128-CFB8" +#define LN_aria_128_cfb8 "aria-128-cfb8" +#define NID_aria_128_cfb8 1083 + +#define SN_aria_192_cfb8 "ARIA-192-CFB8" +#define LN_aria_192_cfb8 "aria-192-cfb8" +#define NID_aria_192_cfb8 1084 + +#define SN_aria_256_cfb8 "ARIA-256-CFB8" +#define LN_aria_256_cfb8 "aria-256-cfb8" +#define NID_aria_256_cfb8 1085 + +#define SN_aria_128_ccm "ARIA-128-CCM" +#define LN_aria_128_ccm "aria-128-ccm" +#define NID_aria_128_ccm 1120 +#define OBJ_aria_128_ccm OBJ_aria,37L + +#define SN_aria_192_ccm "ARIA-192-CCM" +#define LN_aria_192_ccm "aria-192-ccm" +#define NID_aria_192_ccm 1121 +#define OBJ_aria_192_ccm OBJ_aria,38L + +#define SN_aria_256_ccm "ARIA-256-CCM" +#define LN_aria_256_ccm "aria-256-ccm" +#define NID_aria_256_ccm 1122 +#define OBJ_aria_256_ccm OBJ_aria,39L + +#define SN_aria_128_gcm "ARIA-128-GCM" +#define LN_aria_128_gcm "aria-128-gcm" +#define NID_aria_128_gcm 1123 +#define OBJ_aria_128_gcm OBJ_aria,34L + +#define SN_aria_192_gcm "ARIA-192-GCM" +#define LN_aria_192_gcm "aria-192-gcm" +#define NID_aria_192_gcm 1124 +#define OBJ_aria_192_gcm OBJ_aria,35L + +#define SN_aria_256_gcm "ARIA-256-GCM" +#define LN_aria_256_gcm "aria-256-gcm" +#define NID_aria_256_gcm 1125 +#define OBJ_aria_256_gcm OBJ_aria,36L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_sm4_ecb "SM4-ECB" +#define LN_sm4_ecb "sm4-ecb" +#define NID_sm4_ecb 1133 +#define OBJ_sm4_ecb OBJ_sm_scheme,104L,1L + +#define SN_sm4_cbc "SM4-CBC" +#define LN_sm4_cbc "sm4-cbc" +#define NID_sm4_cbc 1134 +#define OBJ_sm4_cbc OBJ_sm_scheme,104L,2L + +#define SN_sm4_ofb128 "SM4-OFB" +#define LN_sm4_ofb128 "sm4-ofb" +#define NID_sm4_ofb128 1135 +#define OBJ_sm4_ofb128 OBJ_sm_scheme,104L,3L + +#define SN_sm4_cfb128 "SM4-CFB" +#define LN_sm4_cfb128 "sm4-cfb" +#define NID_sm4_cfb128 1137 +#define OBJ_sm4_cfb128 OBJ_sm_scheme,104L,4L + +#define SN_sm4_cfb1 "SM4-CFB1" +#define LN_sm4_cfb1 "sm4-cfb1" +#define NID_sm4_cfb1 1136 +#define OBJ_sm4_cfb1 OBJ_sm_scheme,104L,5L + +#define SN_sm4_cfb8 "SM4-CFB8" +#define LN_sm4_cfb8 "sm4-cfb8" +#define NID_sm4_cfb8 1138 +#define OBJ_sm4_cfb8 OBJ_sm_scheme,104L,6L + +#define SN_sm4_ctr "SM4-CTR" +#define LN_sm4_ctr "sm4-ctr" +#define NID_sm4_ctr 1139 +#define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" +#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" +#define NID_aes_128_cbc_hmac_sha256 948 + +#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" +#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" +#define NID_aes_192_cbc_hmac_sha256 949 + +#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" +#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" +#define NID_aes_256_cbc_hmac_sha256 950 + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 1018 + +#define SN_chacha20 "ChaCha20" +#define LN_chacha20 "chacha20" +#define NID_chacha20 1019 + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 951 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 952 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 953 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 954 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_jurisdictionLocalityName "jurisdictionL" +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 955 +#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L + +#define SN_jurisdictionStateOrProvinceName "jurisdictionST" +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 956 +#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L + +#define SN_jurisdictionCountryName "jurisdictionC" +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 957 +#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L + +#define SN_id_scrypt "id-scrypt" +#define LN_id_scrypt "scrypt" +#define NID_id_scrypt 973 +#define OBJ_id_scrypt 1L,3L,6L,1L,4L,1L,11591L,4L,11L + +#define SN_tls1_prf "TLS1-PRF" +#define LN_tls1_prf "tls1-prf" +#define NID_tls1_prf 1021 + +#define SN_hkdf "HKDF" +#define LN_hkdf "hkdf" +#define NID_hkdf 1036 + +#define SN_id_pkinit "id-pkinit" +#define NID_id_pkinit 1031 +#define OBJ_id_pkinit 1L,3L,6L,1L,5L,2L,3L + +#define SN_pkInitClientAuth "pkInitClientAuth" +#define LN_pkInitClientAuth "PKINIT Client Auth" +#define NID_pkInitClientAuth 1032 +#define OBJ_pkInitClientAuth OBJ_id_pkinit,4L + +#define SN_pkInitKDC "pkInitKDC" +#define LN_pkInitKDC "Signing KDC Response" +#define NID_pkInitKDC 1033 +#define OBJ_pkInitKDC OBJ_id_pkinit,5L + +#define SN_X25519 "X25519" +#define NID_X25519 1034 +#define OBJ_X25519 1L,3L,101L,110L + +#define SN_X448 "X448" +#define NID_X448 1035 +#define OBJ_X448 1L,3L,101L,111L + +#define SN_ED25519 "ED25519" +#define NID_ED25519 1087 +#define OBJ_ED25519 1L,3L,101L,112L + +#define SN_ED448 "ED448" +#define NID_ED448 1088 +#define OBJ_ED448 1L,3L,101L,113L + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 1037 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 1038 + +#define SN_kx_dhe "KxDHE" +#define LN_kx_dhe "kx-dhe" +#define NID_kx_dhe 1039 + +#define SN_kx_ecdhe_psk "KxECDHE-PSK" +#define LN_kx_ecdhe_psk "kx-ecdhe-psk" +#define NID_kx_ecdhe_psk 1040 + +#define SN_kx_dhe_psk "KxDHE-PSK" +#define LN_kx_dhe_psk "kx-dhe-psk" +#define NID_kx_dhe_psk 1041 + +#define SN_kx_rsa_psk "KxRSA_PSK" +#define LN_kx_rsa_psk "kx-rsa-psk" +#define NID_kx_rsa_psk 1042 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 1043 + +#define SN_kx_srp "KxSRP" +#define LN_kx_srp "kx-srp" +#define NID_kx_srp 1044 + +#define SN_kx_gost "KxGOST" +#define LN_kx_gost "kx-gost" +#define NID_kx_gost 1045 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 1063 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 1046 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 1047 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 1048 + +#define SN_auth_dss "AuthDSS" +#define LN_auth_dss "auth-dss" +#define NID_auth_dss 1049 + +#define SN_auth_gost01 "AuthGOST01" +#define LN_auth_gost01 "auth-gost01" +#define NID_auth_gost01 1050 + +#define SN_auth_gost12 "AuthGOST12" +#define LN_auth_gost12 "auth-gost12" +#define NID_auth_gost12 1051 + +#define SN_auth_srp "AuthSRP" +#define LN_auth_srp "auth-srp" +#define NID_auth_srp 1052 + +#define SN_auth_null "AuthNULL" +#define LN_auth_null "auth-null" +#define NID_auth_null 1053 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 1064 + +#define SN_poly1305 "Poly1305" +#define LN_poly1305 "poly1305" +#define NID_poly1305 1061 + +#define SN_siphash "SipHash" +#define LN_siphash "siphash" +#define NID_siphash 1062 + +#define SN_ffdhe2048 "ffdhe2048" +#define NID_ffdhe2048 1126 + +#define SN_ffdhe3072 "ffdhe3072" +#define NID_ffdhe3072 1127 + +#define SN_ffdhe4096 "ffdhe4096" +#define NID_ffdhe4096 1128 + +#define SN_ffdhe6144 "ffdhe6144" +#define NID_ffdhe6144 1129 + +#define SN_ffdhe8192 "ffdhe8192" +#define NID_ffdhe8192 1130 + +#define SN_ISO_UA "ISO-UA" +#define NID_ISO_UA 1150 +#define OBJ_ISO_UA OBJ_member_body,804L + +#define SN_ua_pki "ua-pki" +#define NID_ua_pki 1151 +#define OBJ_ua_pki OBJ_ISO_UA,2L,1L,1L,1L + +#define SN_dstu28147 "dstu28147" +#define LN_dstu28147 "DSTU Gost 28147-2009" +#define NID_dstu28147 1152 +#define OBJ_dstu28147 OBJ_ua_pki,1L,1L,1L + +#define SN_dstu28147_ofb "dstu28147-ofb" +#define LN_dstu28147_ofb "DSTU Gost 28147-2009 OFB mode" +#define NID_dstu28147_ofb 1153 +#define OBJ_dstu28147_ofb OBJ_dstu28147,2L + +#define SN_dstu28147_cfb "dstu28147-cfb" +#define LN_dstu28147_cfb "DSTU Gost 28147-2009 CFB mode" +#define NID_dstu28147_cfb 1154 +#define OBJ_dstu28147_cfb OBJ_dstu28147,3L + +#define SN_dstu28147_wrap "dstu28147-wrap" +#define LN_dstu28147_wrap "DSTU Gost 28147-2009 key wrap" +#define NID_dstu28147_wrap 1155 +#define OBJ_dstu28147_wrap OBJ_dstu28147,5L + +#define SN_hmacWithDstu34311 "hmacWithDstu34311" +#define LN_hmacWithDstu34311 "HMAC DSTU Gost 34311-95" +#define NID_hmacWithDstu34311 1156 +#define OBJ_hmacWithDstu34311 OBJ_ua_pki,1L,1L,2L + +#define SN_dstu34311 "dstu34311" +#define LN_dstu34311 "DSTU Gost 34311-95" +#define NID_dstu34311 1157 +#define OBJ_dstu34311 OBJ_ua_pki,1L,2L,1L + +#define SN_dstu4145le "dstu4145le" +#define LN_dstu4145le "DSTU 4145-2002 little endian" +#define NID_dstu4145le 1158 +#define OBJ_dstu4145le OBJ_ua_pki,1L,3L,1L,1L + +#define SN_dstu4145be "dstu4145be" +#define LN_dstu4145be "DSTU 4145-2002 big endian" +#define NID_dstu4145be 1159 +#define OBJ_dstu4145be OBJ_dstu4145le,1L,1L + +#define SN_uacurve0 "uacurve0" +#define LN_uacurve0 "DSTU curve 0" +#define NID_uacurve0 1160 +#define OBJ_uacurve0 OBJ_dstu4145le,2L,0L + +#define SN_uacurve1 "uacurve1" +#define LN_uacurve1 "DSTU curve 1" +#define NID_uacurve1 1161 +#define OBJ_uacurve1 OBJ_dstu4145le,2L,1L + +#define SN_uacurve2 "uacurve2" +#define LN_uacurve2 "DSTU curve 2" +#define NID_uacurve2 1162 +#define OBJ_uacurve2 OBJ_dstu4145le,2L,2L + +#define SN_uacurve3 "uacurve3" +#define LN_uacurve3 "DSTU curve 3" +#define NID_uacurve3 1163 +#define OBJ_uacurve3 OBJ_dstu4145le,2L,3L + +#define SN_uacurve4 "uacurve4" +#define LN_uacurve4 "DSTU curve 4" +#define NID_uacurve4 1164 +#define OBJ_uacurve4 OBJ_dstu4145le,2L,4L + +#define SN_uacurve5 "uacurve5" +#define LN_uacurve5 "DSTU curve 5" +#define NID_uacurve5 1165 +#define OBJ_uacurve5 OBJ_dstu4145le,2L,5L + +#define SN_uacurve6 "uacurve6" +#define LN_uacurve6 "DSTU curve 6" +#define NID_uacurve6 1166 +#define OBJ_uacurve6 OBJ_dstu4145le,2L,6L + +#define SN_uacurve7 "uacurve7" +#define LN_uacurve7 "DSTU curve 7" +#define NID_uacurve7 1167 +#define OBJ_uacurve7 OBJ_dstu4145le,2L,7L + +#define SN_uacurve8 "uacurve8" +#define LN_uacurve8 "DSTU curve 8" +#define NID_uacurve8 1168 +#define OBJ_uacurve8 OBJ_dstu4145le,2L,8L + +#define SN_uacurve9 "uacurve9" +#define LN_uacurve9 "DSTU curve 9" +#define NID_uacurve9 1169 +#define OBJ_uacurve9 OBJ_dstu4145le,2L,9L diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objects.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objects.h new file mode 100644 index 00000000..5e8b5762 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objects.h @@ -0,0 +1,175 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# include +# include +# include +# include + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignment discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, declare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +#if OPENSSL_API_COMPAT < 0x10100000L +# define OBJ_cleanup() while(0) continue +#endif +int OBJ_create_objects(BIO *in); + +size_t OBJ_length(const ASN1_OBJECT *obj); +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objectserr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objectserr.h new file mode 100644 index 00000000..02e166f1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/objectserr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJERR_H +# define HEADER_OBJERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OBJ_strings(void); + +/* + * OBJ function codes. + */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_ADD_SIGID 107 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 +# define OBJ_F_OBJ_TXT2OBJ 108 + +/* + * OBJ reason codes. + */ +# define OBJ_R_OID_EXISTS 102 +# define OBJ_R_UNKNOWN_NID 101 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsp.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsp.h new file mode 100644 index 00000000..4d759a49 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsp.h @@ -0,0 +1,352 @@ +/* + * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +#include + +/* + * These definitions are outside the OPENSSL_NO_OCSP guard because although for + * historical reasons they have OCSP_* names, they can actually be used + * independently of OCSP. E.g. see RFC5280 + */ +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + + +# ifndef OPENSSL_NO_OCSP + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +typedef struct ocsp_cert_id_st OCSP_CERTID; + +DEFINE_STACK_OF(OCSP_CERTID) + +typedef struct ocsp_one_request_st OCSP_ONEREQ; + +DEFINE_STACK_OF(OCSP_ONEREQ) + +typedef struct ocsp_req_info_st OCSP_REQINFO; +typedef struct ocsp_signature_st OCSP_SIGNATURE; +typedef struct ocsp_request_st OCSP_REQUEST; + +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; + +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 + +DEFINE_STACK_OF(OCSP_RESPID) + +typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; + +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 + +typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; +typedef struct ocsp_single_response_st OCSP_SINGLERESP; + +DEFINE_STACK_OF(OCSP_SINGLERESP) + +typedef struct ocsp_response_data_st OCSP_RESPDATA; + +typedef struct ocsp_basic_response_st OCSP_BASICRESP; + +typedef struct ocsp_crl_id_st OCSP_CRLID; +typedef struct ocsp_service_locator_st OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST, \ + bp,(char **)(x),cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) (OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE, \ + bp,(char **)(x),cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, + const X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, + const ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs); +const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs); +const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs); +const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, + const ASN1_OCTET_STRING **pid, + const X509_NAME **pname); +int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, + ASN1_OCTET_STRING **pid, + X509_NAME **pname); + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); +int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, + X509 *signer, EVP_MD_CTX *ctx, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert); + +X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); +const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsperr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsperr.h new file mode 100644 index 00000000..8dd9e01a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ocsperr.h @@ -0,0 +1,78 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSPERR_H +# define HEADER_OCSPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_OCSP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OCSP_strings(void); + +/* + * OCSP function codes. + */ +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_SIGN_CTX 119 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_PARSE_HTTP_LINE1 118 + +/* + * OCSP reason codes. + */ +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_NO_SIGNER_KEY 130 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslconf.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslconf.h new file mode 100644 index 00000000..e4c111ae --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslconf.h @@ -0,0 +1,195 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/opensslconf.h.in + * + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_ALGORITHM_DEFINES +# error OPENSSL_ALGORITHM_DEFINES no longer supported +#endif + +/* + * OpenSSL was configured with the following options: + */ + +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_RAND_SEED_OS +# define OPENSSL_RAND_SEED_OS +#endif +#ifndef OPENSSL_NO_AFALGENG +# define OPENSSL_NO_AFALGENG +#endif +#ifndef OPENSSL_NO_ASAN +# define OPENSSL_NO_ASAN +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_NO_CRYPTO_MDEBUG +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +#endif +#ifndef OPENSSL_NO_DEVCRYPTOENG +# define OPENSSL_NO_DEVCRYPTOENG +#endif +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_EGD +# define OPENSSL_NO_EGD +#endif +#ifndef OPENSSL_NO_EXTERNAL_TESTS +# define OPENSSL_NO_EXTERNAL_TESTS +#endif +#ifndef OPENSSL_NO_FUZZ_AFL +# define OPENSSL_NO_FUZZ_AFL +#endif +#ifndef OPENSSL_NO_FUZZ_LIBFUZZER +# define OPENSSL_NO_FUZZ_LIBFUZZER +#endif +#ifndef OPENSSL_NO_HEARTBEATS +# define OPENSSL_NO_HEARTBEATS +#endif +#ifndef OPENSSL_NO_MSAN +# define OPENSSL_NO_MSAN +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL3 +# define OPENSSL_NO_SSL3 +#endif +#ifndef OPENSSL_NO_SSL3_METHOD +# define OPENSSL_NO_SSL3_METHOD +#endif +#ifndef OPENSSL_NO_UBSAN +# define OPENSSL_NO_UBSAN +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif +#ifndef OPENSSL_NO_STATIC_ENGINE +# define OPENSSL_NO_STATIC_ENGINE +#endif + + +/* + * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers + * don't like that. This will hopefully silence them. + */ +#define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy; + +/* + * Applications should use -DOPENSSL_API_COMPAT= to suppress the + * declarations of functions deprecated in or before . Otherwise, they + * still won't see them if the library has been built to disable deprecated + * functions. + */ +#ifndef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f; +# ifdef __GNUC__ +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) +# undef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); +# endif +# endif +#endif + +#ifndef OPENSSL_FILE +# ifdef OPENSSL_NO_FILENAMES +# define OPENSSL_FILE "" +# define OPENSSL_LINE 0 +# else +# define OPENSSL_FILE __FILE__ +# define OPENSSL_LINE __LINE__ +# endif +#endif + +#ifndef OPENSSL_MIN_API +# define OPENSSL_MIN_API 0 +#endif + +#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API +# undef OPENSSL_API_COMPAT +# define OPENSSL_API_COMPAT OPENSSL_MIN_API +#endif + +/* + * Do not deprecate things to be deprecated in version 1.2.0 before the + * OpenSSL version number matches. + */ +#if OPENSSL_VERSION_NUMBER < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) f; +#elif OPENSSL_API_COMPAT < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_2_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10100000L +# define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_1_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10000000L +# define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_0_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x00908000L +# define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_0_9_8(f) +#endif + +/* Generate 80386 code? */ +#undef I386_ONLY + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* + * The following are cipher-specific, but are part of the public API. + */ +#if !defined(OPENSSL_SYS_UEFI) +# define BN_LLONG +/* Only one for the following should be defined */ +# undef SIXTY_FOUR_BIT_LONG +# undef SIXTY_FOUR_BIT +# define THIRTY_TWO_BIT +#endif + +#define RC4_INT unsigned char + +#ifdef __cplusplus +} +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslv.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslv.h new file mode 100644 index 00000000..17d271f5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/opensslv.h @@ -0,0 +1,101 @@ +/* + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1010107fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1g 21 Apr 2020" + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major version number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.1" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ossl_typ.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ossl_typ.h new file mode 100644 index 00000000..e0edfaaf --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ossl_typ.h @@ -0,0 +1,197 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_sctx_st ASN1_SCTX; + +# ifdef _WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +struct dane_st; +typedef struct bio_st BIO; +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_md_st EVP_MD; +typedef struct evp_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; + +typedef struct hmac_ctx_st HMAC_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_pss_params_st RSA_PSS_PARAMS; + +typedef struct ec_key_st EC_KEY; +typedef struct ec_key_method_st EC_KEY_METHOD; + +typedef struct rand_meth_st RAND_METHOD; +typedef struct rand_drbg_st RAND_DRBG; + +typedef struct ssl_dane_st SSL_DANE; +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + +typedef struct x509_sig_info_st X509_SIG_INFO; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct comp_ctx_st COMP_CTX; +typedef struct comp_method_st COMP_METHOD; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +typedef struct sct_st SCT; +typedef struct sct_ctx_st SCT_CTX; +typedef struct ctlog_st CTLOG; +typedef struct ctlog_store_st CTLOG_STORE; +typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; + +typedef struct ossl_store_info_st OSSL_STORE_INFO; +typedef struct ossl_store_search_st OSSL_STORE_SEARCH; + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ + defined(INTMAX_MAX) && defined(UINTMAX_MAX) +typedef intmax_t ossl_intmax_t; +typedef uintmax_t ossl_uintmax_t; +#else +/* + * Not long long, because the C-library can only be expected to provide + * strtoll(), strtoull() at the same time as intmax_t and strtoimax(), + * strtoumax(). Since we use these for parsing arguments, we need the + * conversion functions, not just the sizes. + */ +typedef long ossl_intmax_t; +typedef unsigned long ossl_uintmax_t; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem.h new file mode 100644 index 00000000..2ef5b5d0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem.h @@ -0,0 +1,378 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_STDIO) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_fp_const(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +# define PEM_FLAG_SECURE 0x1 +# define PEM_FLAG_EAY_COMPATIBLE 0x2 +# define PEM_FLAG_ONLY_B64 0x4 +int PEM_read_bio_ex(BIO *bp, char **name, char **header, + unsigned char **data, long *len, unsigned int flags); +int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); + +#ifndef OPENSSL_NO_STDIO +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +#endif + +int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +/* The default pem_password_cb that's used internally */ +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +DECLARE_PEM_write_const(DHxparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); +# endif +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +# ifndef OPENSSL_NO_DSA +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif +# endif + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem2.h new file mode 100644 index 00000000..038fe790 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pem2.h @@ -0,0 +1,13 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM2_H +# define HEADER_PEM2_H +# include +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pemerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pemerr.h new file mode 100644 index 00000000..0c45918f --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pemerr.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEMERR_H +# define HEADER_PEMERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PEM_strings(void); + +/* + * PEM function codes. + */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_I2B 146 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_GET_HEADER_AND_DATA 143 +# define PEM_F_GET_NAME 144 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_DHPARAMS 141 +# define PEM_F_PEM_READ_BIO_EX 145 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_DHPARAMS 142 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* + * PEM reason codes. + */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_HEADER_TOO_LONG 128 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_MISSING_DEK_IV 129 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNEXPECTED_DEK_IV 130 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12.h new file mode 100644 index 00000000..3f43dad6 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12.h @@ -0,0 +1,223 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* It's not clear if these are actually needed... */ +# define PKCS12_key_gen PKCS12_key_gen_utf8 +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_utf8 + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA; + +typedef struct PKCS12_st PKCS12; + +typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; + +DEFINE_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +#if OPENSSL_API_COMPAT < 0x10100000L + +# define M_PKCS12_bag_type PKCS12_bag_type +# define M_PKCS12_cert_bag_type PKCS12_cert_bag_type +# define M_PKCS12_crl_bag_type PKCS12_cert_bag_type + +# define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert +# define PKCS12_certbag2scrl PKCS12_SAFEBAG_get1_crl +# define PKCS12_bag_type PKCS12_SAFEBAG_get_nid +# define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid +# define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert +# define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl +# define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf +# define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt + +#endif + +DEPRECATEDIN_1_1_0(ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)) + +ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid); +int PKCS12_mac_present(const PKCS12 *p12); +void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, + const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, + const ASN1_INTEGER **piter, + const PKCS12 *p12); + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, + int attr_nid); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); + +X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); +const STACK_OF(PKCS12_SAFEBAG) * +PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); +const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); +const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, + int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +const STACK_OF(X509_ATTRIBUTE) * +PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(const unsigned char *uni, int unilen); +unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, const char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, const char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +# endif +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +# ifndef OPENSSL_NO_STDIO +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +# endif +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12err.h new file mode 100644 index 00000000..eff5eb26 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs12err.h @@ -0,0 +1,81 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12ERR_H +# define HEADER_PKCS12ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS12_strings(void); + +/* + * PKCS12 function codes. + */ +# define PKCS12_F_OPENSSL_ASC2UNI 121 +# define PKCS12_F_OPENSSL_UNI2ASC 124 +# define PKCS12_F_OPENSSL_UNI2UTF8 127 +# define PKCS12_F_OPENSSL_UTF82UNI 129 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_KEY_GEN_UTF8 116 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF 112 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 113 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT 133 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ENCRYPT 125 +# define PKCS12_F_PKCS8_SET0_PBE 132 + +/* + * PKCS12 reason codes. + */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7.h new file mode 100644 index 00000000..9b66e002 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7.h @@ -0,0 +1,319 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DEFINE_STACK_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DEFINE_STACK_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DEFINE_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 +# define PKCS7_NO_DUAL_CONTENT 0x10000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +/* CRLF ASCII canonicalisation */ +# define SMIME_ASCIICRLF 0x80000 + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_STDIO +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7err.h new file mode 100644 index 00000000..02e0299a --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/pkcs7err.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7ERR_H +# define HEADER_PKCS7ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS7_strings(void); + +/* + * PKCS7 function codes. + */ +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 + +/* + * PKCS7 reason codes. + */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand.h new file mode 100644 index 00000000..38a2a271 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand.h @@ -0,0 +1,77 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct rand_meth_st { + int (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + int (*add) (const void *buf, int num, double randomness); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif + +RAND_METHOD *RAND_OpenSSL(void); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define RAND_cleanup() while(0) continue +# endif +int RAND_bytes(unsigned char *buf, int num); +int RAND_priv_bytes(unsigned char *buf, int num); +DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num)) + +void RAND_seed(const void *buf, int num); +void RAND_keep_random_devices_open(int keep); + +# if defined(__ANDROID__) && defined(__NDK_FPABI__) +__NDK_FPABI__ /* __attribute__((pcs("aapcs"))) on ARM */ +# endif +void RAND_add(const void *buf, int num, double randomness); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); + +# ifndef OPENSSL_NO_EGD +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +# endif + +int RAND_poll(void); + +# if defined(_WIN32) && (defined(BASETYPES) || defined(_WINDEF_H)) +/* application has to include in order to use these */ +DEPRECATEDIN_1_1_0(void RAND_screen(void)) +DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM)) +# endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand_drbg.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand_drbg.h new file mode 100644 index 00000000..45b731b7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rand_drbg.h @@ -0,0 +1,130 @@ +/* + * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DRBG_RAND_H +# define HEADER_DRBG_RAND_H + +# include +# include +# include + +/* + * RAND_DRBG flags + * + * Note: if new flags are added, the constant `rand_drbg_used_flags` + * in drbg_lib.c needs to be updated accordingly. + */ + +/* In CTR mode, disable derivation function ctr_df */ +# define RAND_DRBG_FLAG_CTR_NO_DF 0x1 + + +# if OPENSSL_API_COMPAT < 0x10200000L +/* This #define was replaced by an internal constant and should not be used. */ +# define RAND_DRBG_USED_FLAGS (RAND_DRBG_FLAG_CTR_NO_DF) +# endif + +/* + * Default security strength (in the sense of [NIST SP 800-90Ar1]) + * + * NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that + * of the cipher by collecting less entropy. The current DRBG implementation + * does not take RAND_DRBG_STRENGTH into account and sets the strength of the + * DRBG to that of the cipher. + * + * RAND_DRBG_STRENGTH is currently only used for the legacy RAND + * implementation. + * + * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and + * NID_aes_256_ctr + */ +# define RAND_DRBG_STRENGTH 256 +/* Default drbg type */ +# define RAND_DRBG_TYPE NID_aes_256_ctr +/* Default drbg flags */ +# define RAND_DRBG_FLAGS 0 + + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * Object lifetime functions. + */ +RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent); +RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent); +int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags); +int RAND_DRBG_set_defaults(int type, unsigned int flags); +int RAND_DRBG_instantiate(RAND_DRBG *drbg, + const unsigned char *pers, size_t perslen); +int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); +void RAND_DRBG_free(RAND_DRBG *drbg); + +/* + * Object "use" functions. + */ +int RAND_DRBG_reseed(RAND_DRBG *drbg, + const unsigned char *adin, size_t adinlen, + int prediction_resistance); +int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); +int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen); + +int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval); +int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval); + +int RAND_DRBG_set_reseed_defaults( + unsigned int master_reseed_interval, + unsigned int slave_reseed_interval, + time_t master_reseed_time_interval, + time_t slave_reseed_time_interval + ); + +RAND_DRBG *RAND_DRBG_get0_master(void); +RAND_DRBG *RAND_DRBG_get0_public(void); +RAND_DRBG *RAND_DRBG_get0_private(void); + +/* + * EXDATA + */ +# define RAND_DRBG_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DRBG, l, p, newf, dupf, freef) +int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg); +void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); + +/* + * Callback function typedefs + */ +typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *drbg, + unsigned char **pout, + int entropy, size_t min_len, + size_t max_len, + int prediction_resistance); +typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx, + unsigned char *out, size_t outlen); +typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *drbg, unsigned char **pout, + int entropy, size_t min_len, + size_t max_len); +typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + +int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, + RAND_DRBG_get_entropy_fn get_entropy, + RAND_DRBG_cleanup_entropy_fn cleanup_entropy, + RAND_DRBG_get_nonce_fn get_nonce, + RAND_DRBG_cleanup_nonce_fn cleanup_nonce); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/randerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/randerr.h new file mode 100644 index 00000000..79d57905 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/randerr.h @@ -0,0 +1,94 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RANDERR_H +# define HEADER_RANDERR_H + +# include + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RAND_strings(void); + +/* + * RAND function codes. + */ +# define RAND_F_DATA_COLLECT_METHOD 127 +# define RAND_F_DRBG_BYTES 101 +# define RAND_F_DRBG_GET_ENTROPY 105 +# define RAND_F_DRBG_SETUP 117 +# define RAND_F_GET_ENTROPY 106 +# define RAND_F_RAND_BYTES 100 +# define RAND_F_RAND_DRBG_ENABLE_LOCKING 119 +# define RAND_F_RAND_DRBG_GENERATE 107 +# define RAND_F_RAND_DRBG_GET_ENTROPY 120 +# define RAND_F_RAND_DRBG_GET_NONCE 123 +# define RAND_F_RAND_DRBG_INSTANTIATE 108 +# define RAND_F_RAND_DRBG_NEW 109 +# define RAND_F_RAND_DRBG_RESEED 110 +# define RAND_F_RAND_DRBG_RESTART 102 +# define RAND_F_RAND_DRBG_SET 104 +# define RAND_F_RAND_DRBG_SET_DEFAULTS 121 +# define RAND_F_RAND_DRBG_UNINSTANTIATE 118 +# define RAND_F_RAND_LOAD_FILE 111 +# define RAND_F_RAND_POOL_ACQUIRE_ENTROPY 122 +# define RAND_F_RAND_POOL_ADD 103 +# define RAND_F_RAND_POOL_ADD_BEGIN 113 +# define RAND_F_RAND_POOL_ADD_END 114 +# define RAND_F_RAND_POOL_ATTACH 124 +# define RAND_F_RAND_POOL_BYTES_NEEDED 115 +# define RAND_F_RAND_POOL_GROW 125 +# define RAND_F_RAND_POOL_NEW 116 +# define RAND_F_RAND_PSEUDO_BYTES 126 +# define RAND_F_RAND_WRITE_FILE 112 + +/* + * RAND reason codes. + */ +# define RAND_R_ADDITIONAL_INPUT_TOO_LONG 102 +# define RAND_R_ALREADY_INSTANTIATED 103 +# define RAND_R_ARGUMENT_OUT_OF_RANGE 105 +# define RAND_R_CANNOT_OPEN_FILE 121 +# define RAND_R_DRBG_ALREADY_INITIALIZED 129 +# define RAND_R_DRBG_NOT_INITIALISED 104 +# define RAND_R_ENTROPY_INPUT_TOO_LONG 106 +# define RAND_R_ENTROPY_OUT_OF_RANGE 124 +# define RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED 127 +# define RAND_R_ERROR_INITIALISING_DRBG 107 +# define RAND_R_ERROR_INSTANTIATING_DRBG 108 +# define RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 109 +# define RAND_R_ERROR_RETRIEVING_ENTROPY 110 +# define RAND_R_ERROR_RETRIEVING_NONCE 111 +# define RAND_R_FAILED_TO_CREATE_LOCK 126 +# define RAND_R_FUNC_NOT_IMPLEMENTED 101 +# define RAND_R_FWRITE_ERROR 123 +# define RAND_R_GENERATE_ERROR 112 +# define RAND_R_INTERNAL_ERROR 113 +# define RAND_R_IN_ERROR_STATE 114 +# define RAND_R_NOT_A_REGULAR_FILE 122 +# define RAND_R_NOT_INSTANTIATED 115 +# define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128 +# define RAND_R_PARENT_LOCKING_NOT_ENABLED 130 +# define RAND_R_PARENT_STRENGTH_TOO_WEAK 131 +# define RAND_R_PERSONALISATION_STRING_TOO_LONG 116 +# define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED 133 +# define RAND_R_PRNG_NOT_SEEDED 100 +# define RAND_R_RANDOM_POOL_OVERFLOW 125 +# define RAND_R_RANDOM_POOL_UNDERFLOW 134 +# define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117 +# define RAND_R_RESEED_ERROR 118 +# define RAND_R_SELFTEST_FAILURE 119 +# define RAND_R_TOO_LITTLE_NONCE_REQUESTED 135 +# define RAND_R_TOO_MUCH_NONCE_REQUESTED 136 +# define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 +# define RAND_R_UNSUPPORTED_DRBG_TYPE 120 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc2.h new file mode 100644 index 00000000..585f9e4c --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc2.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include + +# ifndef OPENSSL_NO_RC2 +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int RC2_INT; + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc4.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc4.h new file mode 100644 index 00000000..86803b37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc4.h @@ -0,0 +1,36 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include + +# ifndef OPENSSL_NO_RC4 +# include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc5.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc5.h new file mode 100644 index 00000000..793f88e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rc5.h @@ -0,0 +1,63 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC5_H +# define HEADER_RC5_H + +# include + +# ifndef OPENSSL_NO_RC5 +# ifdef __cplusplus +extern "C" { +# endif + +# define RC5_ENCRYPT 1 +# define RC5_DECRYPT 0 + +# define RC5_32_INT unsigned int + +# define RC5_32_BLOCK 8 +# define RC5_32_KEY_LENGTH 16/* This is a default, max is 255 */ + +/* + * This are the only values supported. Tweak the code if you want more The + * most supported modes will be RC5-32/12/16 RC5-32/16/8 + */ +# define RC5_8_ROUNDS 8 +# define RC5_12_ROUNDS 12 +# define RC5_16_ROUNDS 16 + +typedef struct rc5_key_st { + /* Number of rounds */ + int rounds; + RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)]; +} RC5_32_KEY; + +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds); +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC5_32_KEY *key, int enc); +void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *ks, unsigned char *iv, + int enc); +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ripemd.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ripemd.h new file mode 100644 index 00000000..c42026aa --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ripemd.h @@ -0,0 +1,47 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include + +#ifndef OPENSSL_NO_RMD160 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define RIPEMD160_LONG unsigned int + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsa.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsa.h new file mode 100644 index 00000000..5e76365c --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsa.h @@ -0,0 +1,513 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include + +# ifndef OPENSSL_NO_RSA +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* The types RSA and RSA_METHOD are defined in ossl_typ.h */ + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +/* based on RFC 8017 appendix A.1.2 */ +# define RSA_ASN1_VERSION_DEFAULT 0 +# define RSA_ASN1_VERSION_MULTI 1 + +# define RSA_DEFAULT_PRIME_NUM 2 + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0000 +# endif +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) +/* Salt length matches digest */ +# define RSA_PSS_SALTLEN_DIGEST -1 +/* Verify only: auto detect salt length */ +# define RSA_PSS_SALTLEN_AUTO -2 +/* Set salt length to maximum possible */ +# define RSA_PSS_SALTLEN_MAX -3 +/* Old compatible max salt length for sign only */ +# define RSA_PSS_SALTLEN_MAX_SIGN -2 + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes, NULL) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)(l)) + +# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)(l)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \ + EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, \ + 0, (void *)(md)) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES (EVP_PKEY_ALG_CTRL + 13) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_bits(const RSA *rsa); +int RSA_size(const RSA *rsa); +int RSA_security_bits(const RSA *rsa); + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r,BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], + BIGNUM *coeffs[], int pnum); +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +int RSA_get_multi_prime_extra_count(const RSA *r); +int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]); +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); +int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], + const BIGNUM *coeffs[]); +const BIGNUM *RSA_get0_n(const RSA *d); +const BIGNUM *RSA_get0_e(const RSA *d); +const BIGNUM *RSA_get0_d(const RSA *d); +const BIGNUM *RSA_get0_p(const RSA *d); +const BIGNUM *RSA_get0_q(const RSA *d); +const BIGNUM *RSA_get0_dmp1(const RSA *r); +const BIGNUM *RSA_get0_dmq1(const RSA *r); +const BIGNUM *RSA_get0_iqmp(const RSA *r); +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r); +void RSA_clear_flags(RSA *r, int flags); +int RSA_test_flags(const RSA *r, int flags); +void RSA_set_flags(RSA *r, int flags); +int RSA_get_version(RSA *r); +ENGINE *RSA_get0_engine(const RSA *r); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), + void *cb_arg)) + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +/* Multi-prime version */ +int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb); + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, + const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb); + +int RSA_check_key(const RSA *); +int RSA_check_key_ex(const RSA *, BN_GENCB *cb); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_null_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* these are the actual RSA functions */ +const RSA_METHOD *RSA_PKCS1_OpenSSL(void); + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + /* Decoded hash algorithm from maskGenAlgorithm */ + X509_ALGOR *maskHash; +}; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; + /* Decoded hash algorithm from maskGenFunc */ + X509_ALGOR *maskHash; +} RSA_OAEP_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_STDIO +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +int RSA_print(BIO *bp, const RSA *r, int offset); + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +#define RSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef) +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +RSA_METHOD *RSA_meth_new(const char *name, int flags); +void RSA_meth_free(RSA_METHOD *meth); +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +const char *RSA_meth_get0_name(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +int RSA_meth_get_flags(const RSA_METHOD *meth); +int RSA_meth_set_flags(RSA_METHOD *meth, int flags); +void *RSA_meth_get0_app_data(const RSA_METHOD *meth); +int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data); +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_enc(RSA_METHOD *rsa, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_dec(RSA_METHOD *rsa, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_enc(RSA_METHOD *rsa, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_dec(RSA_METHOD *rsa, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); +int RSA_meth_set_mod_exp(RSA_METHOD *rsa, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx)); +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx)); +int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa)); +int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa)); +int (*RSA_meth_get_sign(const RSA_METHOD *meth)) + (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); +int RSA_meth_set_sign(RSA_METHOD *rsa, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)); +int (*RSA_meth_get_verify(const RSA_METHOD *meth)) + (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +int RSA_meth_set_verify(RSA_METHOD *rsa, + int (*verify) (int dtype, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)); +int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_keygen(RSA_METHOD *rsa, + int (*keygen) (RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb)); +int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb)); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsaerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsaerr.h new file mode 100644 index 00000000..59b15e13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/rsaerr.h @@ -0,0 +1,167 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSAERR_H +# define HEADER_RSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RSA_strings(void); + +/* + * RSA function codes. + */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_ENCODE_PKCS1 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_PSS_INIT 165 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 149 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_ALGOR_TO_MD 156 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_CHECK_KEY_EX 160 +# define RSA_F_RSA_CMS_DECRYPT 159 +# define RSA_F_RSA_CMS_VERIFY 158 +# define RSA_F_RSA_ITEM_VERIFY 148 +# define RSA_F_RSA_METH_DUP 161 +# define RSA_F_RSA_METH_NEW 162 +# define RSA_F_RSA_METH_SET1_NAME 163 +# define RSA_F_RSA_MGF1_TO_MD 157 +# define RSA_F_RSA_MULTIP_INFO_NEW 166 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_OSSL_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_OSSL_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_OSSL_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 154 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 152 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 153 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PARAM_DECODE 164 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIV_DECODE 150 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PSS_GET_PARAM 151 +# define RSA_F_RSA_PSS_TO_CTX 155 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 126 +# define RSA_F_SETUP_TBUF 167 + +/* + * RSA reason codes. + */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_DOES_NOT_MATCH 158 +# define RSA_R_DIGEST_NOT_ALLOWED 145 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST 157 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_LABEL 160 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_MULTI_PRIME_KEY 167 +# define RSA_R_INVALID_OAEP_PARAMETERS 161 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_PRIME_NUM_INVALID 165 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MISSING_PRIVATE_KEY 179 +# define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 +# define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 +# define RSA_R_MP_R_NOT_PRIME 170 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_PSS_SALTLEN_TOO_SMALL 164 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_DIGEST 166 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 162 +# define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/safestack.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/safestack.h new file mode 100644 index 00000000..38b55789 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/safestack.h @@ -0,0 +1,207 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define STACK_OF(type) struct stack_st_##type + +# define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ + { \ + return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ + { \ + return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ + { \ + return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ + { \ + OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ + { \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ + sk_##t1##_copyfunc copyfunc, \ + sk_##t1##_freefunc freefunc) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \ + (OPENSSL_sk_copyfunc)copyfunc, \ + (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ + { \ + return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \ + } + +# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2) +# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) +# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \ + SKM_DEFINE_STACK_OF(t1, const t2, t2) +# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; +typedef const char *OPENSSL_CSTRING; + +/*- + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char) +DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_sk_num +# pragma weak OPENSSL_sk_value +# pragma weak OPENSSL_sk_new +# pragma weak OPENSSL_sk_new_null +# pragma weak OPENSSL_sk_new_reserve +# pragma weak OPENSSL_sk_reserve +# pragma weak OPENSSL_sk_free +# pragma weak OPENSSL_sk_zero +# pragma weak OPENSSL_sk_delete +# pragma weak OPENSSL_sk_delete_ptr +# pragma weak OPENSSL_sk_push +# pragma weak OPENSSL_sk_unshift +# pragma weak OPENSSL_sk_pop +# pragma weak OPENSSL_sk_shift +# pragma weak OPENSSL_sk_pop_free +# pragma weak OPENSSL_sk_insert +# pragma weak OPENSSL_sk_set +# pragma weak OPENSSL_sk_find +# pragma weak OPENSSL_sk_find_ex +# pragma weak OPENSSL_sk_sort +# pragma weak OPENSSL_sk_is_sorted +# pragma weak OPENSSL_sk_dup +# pragma weak OPENSSL_sk_deep_copy +# pragma weak OPENSSL_sk_set_cmp_func +# endif /* __SUNPRO_C */ + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/seed.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/seed.h new file mode 100644 index 00000000..de10b085 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/seed.h @@ -0,0 +1,96 @@ +/* + * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include + +# ifndef OPENSSL_NO_SEED +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# include + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sha.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sha.h new file mode 100644 index 00000000..6a1eb0de --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sha.h @@ -0,0 +1,119 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define SHA_LONG unsigned int + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); + +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; + +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srp.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srp.h new file mode 100644 index 00000000..aaf13558 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srp.h @@ -0,0 +1,135 @@ +/* + * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2004, EdelKey Project. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Christophe Renou and Peter Sylvester, + * for the EdelKey project. + */ + +#ifndef HEADER_SRP_H +# define HEADER_SRP_H + +#include + +#ifndef OPENSSL_NO_SRP +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DEFINE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +DEFINE_STACK_OF(SRP_user_pwd) + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + const BIGNUM *default_g; + const BIGNUM *default_N; +} SRP_VBASE; + +/* + * Internal structure storing N and g pair + */ +typedef struct SRP_gN_st { + char *id; + const BIGNUM *g; + const BIGNUM *N; +} SRP_gN; + +DEFINE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +void SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +DEPRECATEDIN_1_1_0(SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)) +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, + const BIGNUM *b, const BIGNUM *N); +BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v); +int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N); +BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g); +BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u); +int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srtp.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srtp.h new file mode 100644 index 00000000..0b57c235 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/srtp.h @@ -0,0 +1,50 @@ +/* + * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +/* AEAD SRTP protection profiles from RFC 7714 */ +# define SRTP_AEAD_AES_128_GCM 0x0007 +# define SRTP_AEAD_AES_256_GCM 0x0008 + +# ifndef OPENSSL_NO_SRTP + +__owur int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +__owur int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +__owur STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +__owur SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl.h new file mode 100644 index 00000000..6724ccf2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl.h @@ -0,0 +1,2438 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif +# include +# include +# include +# include + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* OpenSSL version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* The maximum number of encrypt/decrypt pipelines we can support */ +# define SSL_MAX_PIPELINES 32 + +/* text strings for the ciphers */ + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr"/* this cipher class has been removed */ +# define SSL_TXT_kDHd "kDHd"/* this cipher class has been removed */ +# define SSL_TXT_kDH "kDH"/* this cipher class has been removed */ +# define SSL_TXT_kEDH "kEDH"/* alias for kDHE */ +# define SSL_TXT_kDHE "kDHE" +# define SSL_TXT_kECDHr "kECDHr"/* this cipher class has been removed */ +# define SSL_TXT_kECDHe "kECDHe"/* this cipher class has been removed */ +# define SSL_TXT_kECDH "kECDH"/* this cipher class has been removed */ +# define SSL_TXT_kEECDH "kEECDH"/* alias for kECDHE */ +# define SSL_TXT_kECDHE "kECDHE" +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kRSAPSK "kRSAPSK" +# define SSL_TXT_kECDHEPSK "kECDHEPSK" +# define SSL_TXT_kDHEPSK "kDHEPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDH "aECDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST12 "aGOST12" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_DHE "DHE"/* same as "kDHE:-ADH" */ +# define SSL_TXT_EDH "EDH"/* alias for DHE */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* alias for ECDHE" */ +# define SSL_TXT_ECDHE "ECDHE"/* same as "kECDHE:-AECDH" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_AES_CCM "AESCCM" +# define SSL_TXT_AES_CCM_8 "AESCCM8" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" +# define SSL_TXT_CHACHA20 "CHACHA20" +# define SSL_TXT_GOST "GOST89" +# define SSL_TXT_ARIA "ARIA" +# define SSL_TXT_ARIA_GCM "ARIAGCM" +# define SSL_TXT_ARIA128 "ARIA128" +# define SSL_TXT_ARIA256 "ARIA256" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_GOST12 "GOST12" +# define SSL_TXT_GOST89MAC12 "GOST89MAC12" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + * This applies to ciphersuites for TLSv1.2 and below. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL" +/* This is the default set of TLSv1.3 ciphersuites */ +# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_CHACHA20_POLY1305_SHA256:" \ + "TLS_AES_128_GCM_SHA256" +# else +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_AES_128_GCM_SHA256" +#endif +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; +typedef struct ssl_comp_st SSL_COMP; + +STACK_OF(SSL_CIPHER); +STACK_OF(SSL_COMP); + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg); + +/* Extension context codes */ +/* This extension is only allowed in TLS */ +#define SSL_EXT_TLS_ONLY 0x0001 +/* This extension is only allowed in DTLS */ +#define SSL_EXT_DTLS_ONLY 0x0002 +/* Some extensions may be allowed in DTLS but we don't implement them for it */ +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +/* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ +#define SSL_EXT_SSL3_ALLOWED 0x0008 +/* Extension is only defined for TLS1.2 and below */ +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +/* Extension is only defined for TLS1.3 and above */ +#define SSL_EXT_TLS1_3_ONLY 0x0020 +/* Ignore this extension during parsing if we are resuming */ +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 +#define SSL_EXT_CLIENT_HELLO 0x0080 +/* Really means TLS1.2 or below */ +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb)(SSL *s, unsigned int ext_type, + const unsigned char **out, size_t *outlen, + int *al, void *add_arg); + +typedef void (*custom_ext_free_cb)(SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb)(SSL *s, unsigned int ext_type, + const unsigned char *in, size_t inlen, + int *al, void *parse_arg); + + +typedef int (*SSL_custom_ext_add_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, + size_t *outlen, X509 *x, + size_t chainidx, + int *al, void *add_arg); + +typedef void (*SSL_custom_ext_free_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *out, + void *add_arg); + +typedef int (*SSL_custom_ext_parse_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *in, + size_t inlen, X509 *x, + size_t chainidx, + int *al, void *parse_arg); + +/* Typedef for verification callback */ +typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/* + * Some values are reserved until OpenSSL 1.2.0 because they were previously + * included in SSL_OP_ALL in a 1.1.x release. + * + * Reserved value (until OpenSSL 1.2.0) 0x00000001U + * Reserved value (until OpenSSL 1.2.0) 0x00000002U + */ +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U + +/* Reserved value (until OpenSSL 1.2.0) 0x00000008U */ +# define SSL_OP_TLSEXT_PADDING 0x00000010U +/* Reserved value (until OpenSSL 1.2.0) 0x00000020U */ +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U +/* + * Reserved value (until OpenSSL 1.2.0) 0x00000080U + * Reserved value (until OpenSSL 1.2.0) 0x00000100U + * Reserved value (until OpenSSL 1.2.0) 0x00000200U + */ + +/* In TLSv1.3 allow a non-(ec)dhe based kex_mode */ +# define SSL_OP_ALLOW_NO_DHE_KEX 0x00000400U + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. Added in 0.9.6e + */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800U + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000U +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000U +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000U +# ifndef OPENSSL_NO_DTLS1_METHOD +/* Use Cisco's "speshul" version of DTLS_BAD_VER + * (only with deprecated DTLSv1_client_method()) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# endif + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000U +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000U +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000U +/* Disable encrypt-then-mac */ +# define SSL_OP_NO_ENCRYPT_THEN_MAC 0x00080000U + +/* + * Enable TLSv1.3 Compatibility mode. This is on by default. A future version + * of OpenSSL may have this disabled by default. + */ +# define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0x00100000U + +/* Prioritize Chacha20Poly1305 when client does. + * Modifies SSL_OP_CIPHER_SERVER_PREFERENCE */ +# define SSL_OP_PRIORITIZE_CHACHA 0x00200000U + +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000U +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000U + +/* + * Switches off automatic TLSv1.3 anti-replay protection for early data. This + * is a server-side option only (no effect on the client). + */ +# define SSL_OP_NO_ANTI_REPLAY 0x01000000U + +# define SSL_OP_NO_SSLv3 0x02000000U +# define SSL_OP_NO_TLSv1 0x04000000U +# define SSL_OP_NO_TLSv1_2 0x08000000U +# define SSL_OP_NO_TLSv1_1 0x10000000U +# define SSL_OP_NO_TLSv1_3 0x20000000U + +# define SSL_OP_NO_DTLSv1 0x04000000U +# define SSL_OP_NO_DTLSv1_2 0x08000000U + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +# define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) + +/* Disallow all renegotiation */ +# define SSL_OP_NO_RENEGOTIATION 0x40000000U + +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000U + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. + * This used to be 0x80000BFFU before 1.1.1. + */ +# define SSL_OP_ALL (SSL_OP_CRYPTOPRO_TLSEXT_BUG|\ + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS|\ + SSL_OP_LEGACY_SERVER_CONNECT|\ + SSL_OP_TLSEXT_PADDING|\ + SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + +/* OBSOLETE OPTIONS: retained for compatibility */ + +/* Removed from OpenSSL 1.1.0. Was 0x00000001L */ +/* Related to removed SSLv2. */ +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000002L */ +/* Related to removed SSLv2. */ +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +/* Removed from OpenSSL 0.9.8q and 1.0.0c. Was 0x00000008L */ +/* Dead forever, see CVE-2010-4180 */ +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +/* Removed from OpenSSL 1.0.1h and 1.0.2. Was 0x00000010L */ +/* Refers to ancient SSLREF and SSLv2. */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000020 */ +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +/* Removed from OpenSSL 0.9.7h and 0.9.8b. Was 0x00000040L */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000080 */ +/* Ancient SSLeay version. */ +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000100L */ +# define SSL_OP_TLS_D5_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000200L */ +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00080000L */ +# define SSL_OP_SINGLE_ECDH_USE 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00100000L */ +# define SSL_OP_SINGLE_DH_USE 0x0 +/* Removed from OpenSSL 1.0.1k and 1.0.2. Was 0x00200000L */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x01000000L */ +# define SSL_OP_NO_SSLv2 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x08000000L */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x10000000L */ +# define SSL_OP_PKCS1_CHECK_2 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x20000000L */ +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x40000000L */ +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001U +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004U +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008U +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) Released buffers are freed. + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010U +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020U +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040U +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U +/* + * Support Asynchronous operation + */ +# define SSL_MODE_ASYNC 0x00000100U + +/* + * When using DTLS/SCTP, include the terminating zero in the label + * used for computing the endpoint-pair shared secret. Required for + * interoperability with implementations having this bug like these + * older version of OpenSSL: + * - OpenSSL 1.0.0 series + * - OpenSSL 1.0.1 series + * - OpenSSL 1.0.2 series + * - OpenSSL 1.1.0 series + * - OpenSSL 1.1.1 and 1.1.1a + */ +# define SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certificate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001U + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +# define SSL_CONF_FLAG_REQUIRE_PRIVATE 0x40 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 +# define SSL_CONF_TYPE_NONE 0x4 + +/* Maximum length of the application-controlled segment of a a TLSv1.3 cookie */ +# define SSL_COOKIE_LENGTH 4096 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +unsigned long SSL_CTX_get_options(const SSL_CTX *ctx); +unsigned long SSL_get_options(const SSL *s); +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_clear_options(SSL *s, unsigned long op); +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_set_options(SSL *s, unsigned long op); + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# define SSL_get_extms_support(s) \ + SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL) + +# ifndef OPENSSL_NO_SRP + +/* see tls_srp.c */ +__owur int SSL_SRP_CTX_init(SSL *s); +__owur int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +__owur int SSL_srp_server_param_with_username(SSL *s, int *ad); +__owur int SRP_Calc_A_param(SSL *s); + +# endif + +/* 100k max cert list */ +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv3/TLSv1 it is 32 + * bytes. The callback can alter this length to be less if desired. It is + * also an error for the callback to set the size to zero. + */ +typedef int (*GEN_SESSION_CB) (SSL *ssl, unsigned char *id, + unsigned int *id_len); + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + const unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + const unsigned char *data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +__owur int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + const unsigned + char *cookie, + unsigned int + cookie_len)); + +void SSL_CTX_set_stateless_cookie_generate_cb( + SSL_CTX *ctx, + int (*gen_stateless_cookie_cb) (SSL *ssl, + unsigned char *cookie, + size_t *cookie_len)); +void SSL_CTX_set_stateless_cookie_verify_cb( + SSL_CTX *ctx, + int (*verify_stateless_cookie_cb) (SSL *ssl, + const unsigned char *cookie, + size_t cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG + +typedef int (*SSL_CTX_npn_advertised_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned int *outlen, + void *arg); +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + SSL_CTX_npn_advertised_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_advertised_cb SSL_CTX_set_next_protos_advertised_cb + +typedef int (*SSL_CTX_npn_select_cb_func)(SSL *s, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + SSL_CTX_npn_select_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_select_cb SSL_CTX_set_next_proto_select_cb + +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# define SSL_get0_npn_negotiated SSL_get0_next_proto_negotiated +# endif + +__owur int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +__owur int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +typedef int (*SSL_CTX_alpn_select_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + SSL_CTX_alpn_select_cb_func cb, + void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); +void SSL_set_psk_client_callback(SSL *ssl, SSL_psk_client_cb_func cb); + +typedef unsigned int (*SSL_psk_server_cb_func)(SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb); +void SSL_set_psk_server_callback(SSL *ssl, SSL_psk_server_cb_func cb); + +__owur int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +__owur int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +typedef int (*SSL_psk_find_session_cb_func)(SSL *ssl, + const unsigned char *identity, + size_t identity_len, + SSL_SESSION **sess); +typedef int (*SSL_psk_use_session_cb_func)(SSL *ssl, const EVP_MD *md, + const unsigned char **id, + size_t *idlen, + SSL_SESSION **sess); + +void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb); +void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, + SSL_psk_find_session_cb_func cb); +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb); +void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, + SSL_psk_use_session_cb_func cb); + +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +__owur int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, + unsigned int ext_type); + +__owur int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg); + +__owur int SSL_extension_supported(unsigned int ext_type); + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 +# define SSL_ASYNC_PAUSED 5 +# define SSL_ASYNC_NO_JOBS 6 +# define SSL_CLIENT_HELLO_CB 7 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) +# define SSL_want_async(s) (SSL_want(s) == SSL_ASYNC_PAUSED) +# define SSL_want_async_job(s) (SSL_want(s) == SSL_ASYNC_NO_JOBS) +# define SSL_want_client_hello_cb(s) (SSL_want(s) == SSL_CLIENT_HELLO_CB) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +/* + * A callback for logging out TLS key material. This callback should log out + * |line| followed by a newline. + */ +typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line); + +/* + * SSL_CTX_set_keylog_callback configures a callback to log key material. This + * is intended for debugging use with tools like Wireshark. The cb function + * should log line followed by a newline. + */ +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); + +/* + * SSL_CTX_get_keylog_callback returns the callback configured by + * SSL_CTX_set_keylog_callback. + */ +SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); +uint32_t SSL_get_max_early_data(const SSL *s); +int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data); +uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx); +int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data); +uint32_t SSL_get_recv_max_early_data(const SSL *s); + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These need to be after the above set of includes due to a compiler bug + * in VisualStudio 2015 + */ +DEFINE_STACK_OF_CONST(SSL_CIPHER) +DEFINE_STACK_OF(SSL_COMP) + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)(arg))) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0, \ + (char *)(a))) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0, \ + (char *)(arg))) +DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug)) + +/* TLSv1.3 KeyUpdate message types */ +/* -1 used so that this is an invalid value for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NONE -1 +/* Values as defined for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +/* + * The valid handshake states (one for each type message sent and one for each + * type of message received). There are also two "special" states: + * TLS = TLS or DTLS state + * DTLS = DTLS specific state + * CR/SR = Client Read/Server Read + * CW/SW = Client Write/Server Write + * + * The "special" states are: + * TLS_ST_BEFORE = No handshake has been initiated yet + * TLS_ST_OK = A handshake has been successfully completed + */ +typedef enum { + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED, + TLS_ST_SW_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_CERT_VRFY, + TLS_ST_SW_CERT_VRFY, + TLS_ST_CR_HELLO_REQ, + TLS_ST_SW_KEY_UPDATE, + TLS_ST_CW_KEY_UPDATE, + TLS_ST_SR_KEY_UPDATE, + TLS_ST_CR_KEY_UPDATE, + TLS_ST_EARLY_DATA, + TLS_ST_PENDING_EARLY_DATA_END, + TLS_ST_CW_END_OF_EARLY_DATA, + TLS_ST_SR_END_OF_EARLY_DATA +} OSSL_HANDSHAKE_STATE; + +/* + * Most of the following state values are no longer used and are defined to be + * the closest equivalent value in the current state machine code. Not all + * defines have an equivalent and are set to a dummy value (-1). SSL_ST_CONNECT + * and SSL_ST_ACCEPT are still in use in the definition of SSL_CB_ACCEPT_LOOP, + * SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP and SSL_CB_CONNECT_EXIT. + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 + +# define SSL_ST_MASK 0x0FFF + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_in_connect_init(a) (SSL_in_init(a) && !SSL_is_server(a)) +# define SSL_in_accept_init(a) (SSL_in_init(a) && SSL_is_server(a)) +int SSL_in_init(const SSL *s); +int SSL_in_before(const SSL *s); +int SSL_is_init_finished(const SSL *s); + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 +# define SSL_VERIFY_POST_HANDSHAKE 0x08 + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() +# endif + +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION +# define SSL_AD_CERTIFICATE_REQUIRED TLS13_AD_CERTIFICATE_REQUIRED +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_ERROR_WANT_ASYNC 9 +# define SSL_ERROR_WANT_ASYNC_JOB 10 +# define SSL_ERROR_WANT_CLIENT_HELLO_CB 11 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 */ +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB 79 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_GROUPS 90 +# define SSL_CTRL_SET_GROUPS 91 +# define SSL_CTRL_SET_GROUPS_LIST 92 +# define SSL_CTRL_GET_SHARED_GROUP 93 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_PEER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_SET_DH_AUTO 118 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CTRL_GET_EXTMS_SUPPORT 122 +# define SSL_CTRL_SET_MIN_PROTO_VERSION 123 +# define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +# define SSL_CTRL_SET_SPLIT_SEND_FRAGMENT 125 +# define SSL_CTRL_SET_MAX_PIPELINES 126 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE 127 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB 128 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129 +# define SSL_CTRL_GET_MIN_PROTO_VERSION 130 +# define SSL_CTRL_GET_MAX_PROTO_VERSION 131 +# define SSL_CTRL_GET_SIGNATURE_NID 132 +# define SSL_CTRL_GET_TMP_KEY 133 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)(arg)) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_set1_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_add0_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_add1_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_get0_chain_certs(s,px509) \ + SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(s) \ + SSL_set0_chain(s,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_set_current_cert(s,op) \ + SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_get1_groups(s, glist) \ + SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_CTX_set1_groups(ctx, glist, glistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_CTX_set1_groups_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s)) +# define SSL_set1_groups(s, glist, glistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_set1_groups_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str)) +# define SSL_get_shared_group(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str)) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_client_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_client_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str)) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist)) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen, \ + (char *)(clist)) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)(clist)) +# define SSL_get_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_SIGNATURE_NID,0,pn) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_peer_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_TMP_KEY,0,pk) +# define SSL_get_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,plst) +# define SSL_CTX_set_min_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_CTX_set_max_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_CTX_get_min_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_CTX_get_max_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +# define SSL_set_min_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_set_max_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_get_min_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_get_max_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) + +/* Backwards compatibility, original 1.1.0 names */ +# define SSL_CTRL_GET_SERVER_TMP_KEY \ + SSL_CTRL_GET_PEER_TMP_KEY +# define SSL_get_server_tmp_key(s, pk) \ + SSL_get_peer_tmp_key(s, pk) + +/* + * The following symbol names are old and obsolete. They are kept + * for compatibility reasons only and should not be used anymore. + */ +# define SSL_CTRL_GET_CURVES SSL_CTRL_GET_GROUPS +# define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS +# define SSL_CTRL_SET_CURVES_LIST SSL_CTRL_SET_GROUPS_LIST +# define SSL_CTRL_GET_SHARED_CURVE SSL_CTRL_GET_SHARED_GROUP + +# define SSL_get1_curves SSL_get1_groups +# define SSL_CTX_set1_curves SSL_CTX_set1_groups +# define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +# define SSL_set1_curves SSL_set1_groups +# define SSL_set1_curves_list SSL_set1_groups_list +# define SSL_get_shared_curve SSL_get_shared_group + + +# if OPENSSL_API_COMPAT < 0x10100000L +/* Provide some compatibility macros for removed functionality. */ +# define SSL_CTX_need_tmp_RSA(ctx) 0 +# define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +# define SSL_need_tmp_RSA(ssl) 0 +# define SSL_set_tmp_rsa(ssl,rsa) 1 +# define SSL_CTX_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +# define SSL_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +/* + * We "pretend" to call the callback to avoid warnings about unused static + * functions. + */ +# define SSL_CTX_set_tmp_rsa_callback(ctx, cb) while(0) (cb)(NULL, 0, 0) +# define SSL_set_tmp_rsa_callback(ssl, cb) while(0) (cb)(NULL, 0, 0) +# endif +__owur const BIO_METHOD *BIO_f_ssl(void); +__owur BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +__owur BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +__owur BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +__owur int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +__owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +__owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +int SSL_CTX_up_ref(SSL_CTX *ctx); +void SSL_CTX_free(SSL_CTX *); +__owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +__owur long SSL_CTX_get_timeout(const SSL_CTX *ctx); +__owur X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +void SSL_CTX_set1_cert_store(SSL_CTX *, X509_STORE *); +__owur int SSL_want(const SSL *s); +__owur int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +__owur const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +__owur const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s); +__owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +__owur const char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +__owur const char *OPENSSL_cipher_name(const char *rfc_name); +__owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); +__owur uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +__owur const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c); +__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c); + +__owur int SSL_get_fd(const SSL *s); +__owur int SSL_get_rfd(const SSL *s); +__owur int SSL_get_wfd(const SSL *s); +__owur const char *SSL_get_cipher_list(const SSL *s, int n); +__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); +__owur int SSL_get_read_ahead(const SSL *s); +__owur int SSL_pending(const SSL *s); +__owur int SSL_has_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +__owur int SSL_set_fd(SSL *s, int fd); +__owur int SSL_set_rfd(SSL *s, int fd); +__owur int SSL_set_wfd(SSL *s, int fd); +# endif +void SSL_set0_rbio(SSL *s, BIO *rbio); +void SSL_set0_wbio(SSL *s, BIO *wbio); +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +__owur BIO *SSL_get_rbio(const SSL *s); +__owur BIO *SSL_get_wbio(const SSL *s); +__owur int SSL_set_cipher_list(SSL *s, const char *str); +__owur int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +__owur int SSL_set_ciphersuites(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +__owur int SSL_get_verify_mode(const SSL *s); +__owur int SSL_get_verify_depth(const SSL *s); +__owur SSL_verify_cb SSL_get_verify_callback(const SSL *s); +void SSL_set_verify(SSL *s, int mode, SSL_verify_cb callback); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +__owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, + long len); +# endif +__owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +__owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +__owur int SSL_use_certificate(SSL *ssl, X509 *x); +__owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +__owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + + +/* serverinfo file format versions */ +# define SSL_SERVERINFOV1 1 +# define SSL_SERVERINFOV2 2 + +/* Set serverinfo data for the current active cert. */ +__owur int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, + const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +#endif + +__owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +__owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +#endif +__owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +__owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +/* PEM type */ +__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file); +__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_load_error_strings() \ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \ + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# endif + +__owur const char *SSL_state_string(const SSL *s); +__owur const char *SSL_rstate_string(const SSL *s); +__owur const char *SSL_state_string_long(const SSL *s); +__owur const char *SSL_rstate_string_long(const SSL *s); +__owur long SSL_SESSION_get_time(const SSL_SESSION *s); +__owur long SSL_SESSION_set_time(SSL_SESSION *s, long t); +__owur long SSL_SESSION_get_timeout(const SSL_SESSION *s); +__owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +__owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); +__owur int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version); + +__owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s); +__owur int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname); +void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, + const unsigned char **alpn, + size_t *len); +__owur int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, + const unsigned char *alpn, + size_t len); +__owur const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s); +__owur int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher); +__owur int SSL_SESSION_has_ticket(const SSL_SESSION *s); +__owur unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s); +void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick, + size_t *len); +__owur uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s); +__owur int SSL_SESSION_set_max_early_data(SSL_SESSION *s, + uint32_t max_early_data); +__owur int SSL_copy_session_id(SSL *to, const SSL *from); +__owur X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +__owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); +__owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len); +__owur int SSL_SESSION_is_resumable(const SSL_SESSION *s); + +__owur SSL_SESSION *SSL_SESSION_new(void); +__owur SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s, + unsigned int *len); +__owur unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_STDIO +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); +int SSL_SESSION_up_ref(SSL_SESSION *ses); +void SSL_SESSION_free(SSL_SESSION *ses); +__owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +__owur int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); +__owur int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); +__owur int SSL_set_generate_session_id(SSL *s, GEN_SESSION_CB cb); +__owur int SSL_has_matching_session_id(const SSL *s, + const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +__owur X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +__owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +__owur int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +__owur int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +__owur SSL_verify_cb SSL_CTX_get_verify_callback(const SSL_CTX *ctx); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +__owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +# endif +__owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +__owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +__owur int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +__owur int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); +__owur int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); +pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx); +void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx); +void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb); +void SSL_set_default_passwd_cb_userdata(SSL *s, void *u); +pem_password_cb *SSL_get_default_passwd_cb(SSL *s); +void *SSL_get_default_passwd_cb_userdata(SSL *s); + +__owur int SSL_CTX_check_private_key(const SSL_CTX *ctx); +__owur int SSL_check_private_key(const SSL *ctx); + +__owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_up_ref(SSL *s); +int SSL_is_dtls(const SSL *s); +__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +__owur int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); +__owur int SSL_set_purpose(SSL *ssl, int purpose); +__owur int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); +__owur int SSL_set_trust(SSL *ssl, int trust); + +__owur int SSL_set1_host(SSL *s, const char *hostname); +__owur int SSL_add1_host(SSL *s, const char *hostname); +__owur const char *SSL_get0_peername(SSL *s); +void SSL_set_hostflags(SSL *s, unsigned int flags); + +__owur int SSL_CTX_dane_enable(SSL_CTX *ctx); +__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, + uint8_t mtype, uint8_t ord); +__owur int SSL_dane_enable(SSL *s, const char *basedomain); +__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, + uint8_t mtype, unsigned const char *data, size_t dlen); +__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki); +__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, + uint8_t *mtype, unsigned const char **data, + size_t *dlen); +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +SSL_DANE *SSL_get0_dane(SSL *ssl); +/* + * DANE flags + */ +unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags); +unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags); + +__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +__owur X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +__owur X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +__owur BIGNUM *SSL_get_srp_g(SSL *s); +__owur BIGNUM *SSL_get_srp_N(SSL *s); + +__owur char *SSL_get_srp_username(SSL *s); +__owur char *SSL_get_srp_userinfo(SSL *s); +# endif + +/* + * ClientHello callback and helpers. + */ + +# define SSL_CLIENT_HELLO_SUCCESS 1 +# define SSL_CLIENT_HELLO_ERROR 0 +# define SSL_CLIENT_HELLO_RETRY (-1) + +typedef int (*SSL_client_hello_cb_fn) (SSL *s, int *al, void *arg); +void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb, + void *arg); +int SSL_client_hello_isv2(SSL *s); +unsigned int SSL_client_hello_get0_legacy_version(SSL *s); +size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_compression_methods(SSL *s, + const unsigned char **out); +int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get0_ext(SSL *s, unsigned int type, + const unsigned char **out, size_t *outlen); + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +# ifdef OSSL_ASYNC_FD +/* + * Windows application developer has to include windows.h to use these. + */ +__owur int SSL_waiting_for_async(SSL *s); +__owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); +__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +# endif +__owur int SSL_accept(SSL *ssl); +__owur int SSL_stateless(SSL *s); +__owur int SSL_connect(SSL *ssl); +__owur int SSL_read(SSL *ssl, void *buf, int num); +__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); + +# define SSL_READ_EARLY_DATA_ERROR 0 +# define SSL_READ_EARLY_DATA_SUCCESS 1 +# define SSL_READ_EARLY_DATA_FINISH 2 + +__owur int SSL_read_early_data(SSL *s, void *buf, size_t num, + size_t *readbytes); +__owur int SSL_peek(SSL *ssl, void *buf, int num); +__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); +__owur int SSL_write(SSL *ssl, const void *buf, int num); +__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); +__owur int SSL_write_early_data(SSL *s, const void *buf, size_t num, + size_t *written); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +# define SSL_EARLY_DATA_NOT_SENT 0 +# define SSL_EARLY_DATA_REJECTED 1 +# define SSL_EARLY_DATA_ACCEPTED 2 + +__owur int SSL_get_early_data_status(const SSL *s); + +__owur int SSL_get_error(const SSL *s, int ret_code); +__owur const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL3_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_client_method(void)) +# endif + +#define SSLv23_method TLS_method +#define SSLv23_server_method TLS_server_method +#define SSLv23_client_method TLS_client_method + +/* Negotiate highest available SSL/TLS version */ +__owur const SSL_METHOD *TLS_method(void); +__owur const SSL_METHOD *TLS_server_method(void); +__owur const SSL_METHOD *TLS_client_method(void); + +# ifndef OPENSSL_NO_TLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_2_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_2_METHOD +/* DTLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) +# endif + +__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +__owur size_t DTLS_get_data_mtu(const SSL *s); + +__owur STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); +__owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s); + +__owur int SSL_do_handshake(SSL *s); +int SSL_key_update(SSL *s, int updatetype); +int SSL_get_key_update_type(const SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +__owur int SSL_renegotiate_pending(const SSL *s); +int SSL_shutdown(SSL *s); +__owur int SSL_verify_client_post_handshake(SSL *s); +void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val); +void SSL_set_post_handshake_auth(SSL *s, int val); + +__owur const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx); +__owur const SSL_METHOD *SSL_get_ssl_method(const SSL *s); +__owur int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +__owur const char *SSL_alert_type_string_long(int value); +__owur const char *SSL_alert_type_string(int value); +__owur const char *SSL_alert_desc_string_long(int value); +__owur const char *SSL_alert_desc_string(int value); + +void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s); +__owur const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx); +__owur int SSL_add1_to_CA_list(SSL *ssl, const X509 *x); +__owur int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x); +__owur const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +__owur STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +__owur int SSL_add_client_CA(SSL *ssl, X509 *x); +__owur int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +__owur long SSL_get_default_timeout(const SSL *s); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_library_init() OPENSSL_init_ssl(0, NULL) +# endif + +__owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk); + +__owur SSL *SSL_dup(SSL *ssl); + +__owur X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ +struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +__owur X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +__owur EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +__owur int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +__owur int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +__owur int SSL_get_shutdown(const SSL *ssl); +__owur int SSL_version(const SSL *ssl); +__owur int SSL_client_version(const SSL *s); +__owur int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); +__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +__owur SSL_SESSION *SSL_get_session(const SSL *ssl); +__owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +__owur SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +__owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +void SSL_set_verify_result(SSL *ssl, long v); +__owur long SSL_get_verify_result(const SSL *ssl); +__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s); + +__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_SESSION_get_master_key(const SSL_SESSION *sess, + unsigned char *out, size_t outlen); +__owur int SSL_SESSION_set1_master_key(SSL_SESSION *sess, + const unsigned char *in, size_t len); +uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *sess); + +#define SSL_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef) +__owur int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +#define SSL_SESSION_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, l, p, newf, dupf, freef) +__owur int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +#define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) +__owur int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); + +__owur int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_split_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_set_split_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_max_pipelines(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) +# define SSL_set_max_pipelines(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) + +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); +void SSL_set_default_read_buffer_len(SSL *s, size_t len); + +# ifndef OPENSSL_NO_DH +/* NB: the |keylength| is only applicable when is_export is true */ +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif + +__owur const COMP_METHOD *SSL_get_current_compression(const SSL *s); +__owur const COMP_METHOD *SSL_get_current_expansion(const SSL *s); +__owur const char *SSL_COMP_get_name(const COMP_METHOD *comp); +__owur const char *SSL_COMP_get0_name(const SSL_COMP *comp); +__owur int SSL_COMP_get_id(const SSL_COMP *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +__owur STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_COMP_free_compression_methods() while(0) continue +# endif +__owur int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); +int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, + int isv2format, STACK_OF(SSL_CIPHER) **sk, + STACK_OF(SSL_CIPHER) **scsvs); + +/* TLS extensions functions */ +__owur int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +__owur int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +__owur int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn session_secret_cb, + void *arg); + +void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + int + is_forward_secure)); + +void SSL_set_not_resumable_session_callback(SSL *ssl, + int (*cb) (SSL *ssl, + int is_forward_secure)); + +void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); +void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); +int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); + +void SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); +void *SSL_get_record_padding_callback_arg(const SSL *ssl); +int SSL_set_block_padding(SSL *ssl, size_t block_size); + +int SSL_set_num_tickets(SSL *s, size_t num_tickets); +size_t SSL_get_num_tickets(const SSL *s); +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_cache_hit(s) SSL_session_reused(s) +# endif + +__owur int SSL_session_reused(const SSL *s); +__owur int SSL_is_server(const SSL *s); + +__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +__owur unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, + unsigned int flags); +__owur int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +__owur int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +__owur int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +__owur int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +void SSL_add_ssl_module(void); +int SSL_config(SSL *s, const char *name); +int SSL_CTX_config(SSL_CTX *ctx, const char *name); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +# endif + +# ifndef OPENSSL_NO_SOCK +int DTLSv1_listen(SSL *s, BIO_ADDR *client); +# endif + +# ifndef OPENSSL_NO_CT + +/* + * A callback for verifying that the received SCTs are sufficient. + * Expected to return 1 if they are sufficient, otherwise 0. + * May return a negative integer if an error occurs. + * A connection should be aborted if the SCTs are deemed insufficient. + */ +typedef int (*ssl_ct_validation_cb)(const CT_POLICY_EVAL_CTX *ctx, + const STACK_OF(SCT) *scts, void *arg); + +/* + * Sets a |callback| that is invoked upon receipt of ServerHelloDone to validate + * the received SCTs. + * If the callback returns a non-positive result, the connection is terminated. + * Call this function before beginning a handshake. + * If a NULL |callback| is provided, SCT validation is disabled. + * |arg| is arbitrary userdata that will be passed to the callback whenever it + * is invoked. Ownership of |arg| remains with the caller. + * + * NOTE: A side-effect of setting a CT callback is that an OCSP stapled response + * will be requested. + */ +int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, + void *arg); +int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, + ssl_ct_validation_cb callback, + void *arg); +#define SSL_disable_ct(s) \ + ((void) SSL_set_validation_callback((s), NULL, NULL)) +#define SSL_CTX_disable_ct(ctx) \ + ((void) SSL_CTX_set_validation_callback((ctx), NULL, NULL)) + +/* + * The validation type enumerates the available behaviours of the built-in SSL + * CT validation callback selected via SSL_enable_ct() and SSL_CTX_enable_ct(). + * The underlying callback is a static function in libssl. + */ +enum { + SSL_CT_VALIDATION_PERMISSIVE = 0, + SSL_CT_VALIDATION_STRICT +}; + +/* + * Enable CT by setting up a callback that implements one of the built-in + * validation variants. The SSL_CT_VALIDATION_PERMISSIVE variant always + * continues the handshake, the application can make appropriate decisions at + * handshake completion. The SSL_CT_VALIDATION_STRICT variant requires at + * least one valid SCT, or else handshake termination will be requested. The + * handshake may continue anyway if SSL_VERIFY_NONE is in effect. + */ +int SSL_enable_ct(SSL *s, int validation_mode); +int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode); + +/* + * Report whether a non-NULL callback is enabled. + */ +int SSL_ct_is_enabled(const SSL *s); +int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx); + +/* Gets the SCTs received from a connection */ +const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s); + +/* + * Loads the CT log list from the default location. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx); + +/* + * Loads the CT log list from the specified file path. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path); + +/* + * Sets the CT log list used by all SSL connections created from this SSL_CTX. + * Ownership of the CTLOG_STORE is transferred to the SSL_CTX. + */ +void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs); + +/* + * Gets the CT log list used by all SSL connections created from this SSL_CTX. + * This will be NULL unless one of the following functions has been called: + * - SSL_CTX_set_default_ctlog_list_file + * - SSL_CTX_set_ctlog_list_file + * - SSL_CTX_set_ctlog_store + */ +const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx); + +# endif /* OPENSSL_NO_CT */ + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +# define SSL_SECOP_OTHER_TYPE 0xffff0000 +# define SSL_SECOP_OTHER_NONE 0 +# define SSL_SECOP_OTHER_CIPHER (1 << 16) +# define SSL_SECOP_OTHER_CURVE (2 << 16) +# define SSL_SECOP_OTHER_DH (3 << 16) +# define SSL_SECOP_OTHER_PKEY (4 << 16) +# define SSL_SECOP_OTHER_SIGALG (5 << 16) +# define SSL_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +# define SSL_SECOP_PEER 0x1000 + +/* Values for "op" parameter in security callback */ + +/* Called to filter ciphers */ +/* Ciphers client supports */ +# define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +# define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +# define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +# define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +# define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +# define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE) +/* Temporary DH key */ +# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_PKEY) +/* SSL/TLS version */ +# define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE) +/* Session tickets */ +# define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +# define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +# define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +# define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +# define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +# define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE) +/* EE key in certificate */ +# define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT) +/* CA key in certificate */ +# define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +# define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +# define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER) +/* Peer CA key in certificate */ +# define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +# define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER) + +void SSL_set_security_level(SSL *s, int level); +__owur int SSL_get_security_level(const SSL *s); +void SSL_set_security_callback(SSL *s, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, + const SSL_CTX *ctx, int op, + int bits, int nid, void *other, + void *ex); +void SSL_set0_security_ex_data(SSL *s, void *ex); +__owur void *SSL_get0_security_ex_data(const SSL *s); + +void SSL_CTX_set_security_level(SSL_CTX *ctx, int level); +__owur int SSL_CTX_get_security_level(const SSL_CTX *ctx); +void SSL_CTX_set_security_callback(SSL_CTX *ctx, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s, + const SSL_CTX *ctx, + int op, int bits, + int nid, + void *other, + void *ex); +void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex); +__owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx); + +/* OPENSSL_INIT flag 0x010000 reserved for internal use */ +# define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L +# define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L + +# define OPENSSL_INIT_SSL_DEFAULT \ + (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS) + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + +# ifndef OPENSSL_NO_UNIT_TEST +__owur const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +__owur int SSL_free_buffers(SSL *ssl); +__owur int SSL_alloc_buffers(SSL *ssl); + +/* Status codes passed to the decrypt session ticket callback. Some of these + * are for internal use only and are never passed to the callback. */ +typedef int SSL_TICKET_STATUS; + +/* Support for ticket appdata */ +/* fatal error, malloc failure */ +# define SSL_TICKET_FATAL_ERR_MALLOC 0 +/* fatal error, either from parsing or decrypting the ticket */ +# define SSL_TICKET_FATAL_ERR_OTHER 1 +/* No ticket present */ +# define SSL_TICKET_NONE 2 +/* Empty ticket present */ +# define SSL_TICKET_EMPTY 3 +/* the ticket couldn't be decrypted */ +# define SSL_TICKET_NO_DECRYPT 4 +/* a ticket was successfully decrypted */ +# define SSL_TICKET_SUCCESS 5 +/* same as above but the ticket needs to be renewed */ +# define SSL_TICKET_SUCCESS_RENEW 6 + +/* Return codes for the decrypt session ticket callback */ +typedef int SSL_TICKET_RETURN; + +/* An error occurred */ +#define SSL_TICKET_RETURN_ABORT 0 +/* Do not use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE 1 +/* Do not use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE_RENEW 2 +/* Use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE 3 +/* Use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE_RENEW 4 + +typedef int (*SSL_CTX_generate_session_ticket_fn)(SSL *s, void *arg); +typedef SSL_TICKET_RETURN (*SSL_CTX_decrypt_session_ticket_fn)(SSL *s, SSL_SESSION *ss, + const unsigned char *keyname, + size_t keyname_length, + SSL_TICKET_STATUS status, + void *arg); +int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx, + SSL_CTX_generate_session_ticket_fn gen_cb, + SSL_CTX_decrypt_session_ticket_fn dec_cb, + void *arg); +int SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len); +int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len); + +extern const char SSL_version_str[]; + +typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us); + +void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb); + + +typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg); +void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx, + SSL_allow_early_data_cb_fn cb, + void *arg); +void SSL_set_allow_early_data_cb(SSL *s, + SSL_allow_early_data_cb_fn cb, + void *arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl2.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl2.h new file mode 100644 index 00000000..5321bd27 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl2.h @@ -0,0 +1,24 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL2_VERSION 0x0002 + +# define SSL2_MT_CLIENT_HELLO 1 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl3.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl3.h new file mode 100644 index 00000000..8d01fcc4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ssl3.h @@ -0,0 +1,339 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA SSL3_CK_DHE_DSS_DES_40_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA SSL3_CK_DHE_DSS_DES_64_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA SSL3_CK_DHE_DSS_DES_192_CBC3_SHA +# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA SSL3_CK_DHE_RSA_DES_40_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA SSL3_CK_DHE_RSA_DES_64_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA 0x03000016 +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA SSL3_CK_DHE_RSA_DES_192_CBC3_SHA + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define SSL3_RFC_RSA_NULL_MD5 "TLS_RSA_WITH_NULL_MD5" +# define SSL3_RFC_RSA_NULL_SHA "TLS_RSA_WITH_NULL_SHA" +# define SSL3_RFC_RSA_DES_192_CBC3_SHA "TLS_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_DSS_DES_192_CBC3_SHA "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_RSA_DES_192_CBC3_SHA "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_ADH_DES_192_CBC_SHA "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_RSA_IDEA_128_SHA "TLS_RSA_WITH_IDEA_CBC_SHA" +# define SSL3_RFC_RSA_RC4_128_MD5 "TLS_RSA_WITH_RC4_128_MD5" +# define SSL3_RFC_RSA_RC4_128_SHA "TLS_RSA_WITH_RC4_128_SHA" +# define SSL3_RFC_ADH_RC4_128_MD5 "TLS_DH_anon_WITH_RC4_128_MD5" + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" + +/* + * This next block of six "EDH" labels is for backward compatibility with + * older versions of OpenSSL. New code should use the six "DHE" labels above + * instead: + */ +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD 256 + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define DTLS1_RT_HEARTBEAT 24 + +/* Pseudo content types to indicate additional parameters */ +# define TLS1_RT_CRYPTO 0x1000 +# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) +# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) +# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) +# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) + +# define TLS1_RT_CRYPTO_READ 0x0000 +# define TLS1_RT_CRYPTO_WRITE 0x0100 +# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) +# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) +# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) +# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) + +/* Pseudo content types for SSL/TLS header info */ +# define SSL3_RT_HEADER 0x100 +# define SSL3_RT_INNER_CONTENT_TYPE 0x101 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined for *either* SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 10 + +# if defined(TLS_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +/* No longer used as of OpenSSL 1.1.1 */ +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 + +/* Removed from OpenSSL 1.1.0 */ +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0 + +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 + +/* Set if we encrypt then mac instead of usual mac then encrypt */ +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_READ 0x0100 +# define TLS1_FLAGS_ENCRYPT_THEN_MAC TLS1_FLAGS_ENCRYPT_THEN_MAC_READ + +/* Set if extended master secret extension received from peer */ +# define TLS1_FLAGS_RECEIVED_EXTMS 0x0200 + +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE 0x0400 + +# define TLS1_FLAGS_STATELESS 0x0800 + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_END_OF_EARLY_DATA 5 +# define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_URL 21 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# define SSL3_MT_SUPPLEMENTAL_DATA 23 +# define SSL3_MT_KEY_UPDATE 24 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define SSL3_MT_MESSAGE_HASH 254 +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +/* Dummy message type for handling CCS like a normal handshake message */ +# define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x001 +# define SSL3_CC_WRITE 0x002 +# define SSL3_CC_CLIENT 0x010 +# define SSL3_CC_SERVER 0x020 +# define SSL3_CC_EARLY 0x040 +# define SSL3_CC_HANDSHAKE 0x080 +# define SSL3_CC_APPLICATION 0x100 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sslerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sslerr.h new file mode 100644 index 00000000..82983d3c --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/sslerr.h @@ -0,0 +1,773 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSLERR_H +# define HEADER_SSLERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_SSL_strings(void); + +/* + * SSL function codes. + */ +# define SSL_F_ADD_CLIENT_KEY_SHARE_EXT 438 +# define SSL_F_ADD_KEY_SHARE 512 +# define SSL_F_BYTES_TO_CIPHER_LIST 519 +# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 +# define SSL_F_CIPHERSUITE_CB 622 +# define SSL_F_CONSTRUCT_CA_NAMES 552 +# define SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS 553 +# define SSL_F_CONSTRUCT_STATEFUL_TICKET 636 +# define SSL_F_CONSTRUCT_STATELESS_TICKET 637 +# define SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH 539 +# define SSL_F_CREATE_TICKET_PREQUEL 638 +# define SSL_F_CT_MOVE_SCTS 345 +# define SSL_F_CT_STRICT 349 +# define SSL_F_CUSTOM_EXT_ADD 554 +# define SSL_F_CUSTOM_EXT_PARSE 555 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DANE_CTX_ENABLE 347 +# define SSL_F_DANE_MTYPE_SET 393 +# define SSL_F_DANE_TLSA_ADD 394 +# define SSL_F_DERIVE_SECRET_KEY_AND_IV 514 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 318 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_HM_FRAGMENT_NEW 623 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 339 +# define SSL_F_DTLS1_RETRANSMIT_MESSAGE 390 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_DTLS1_WRITE_BYTES 545 +# define SSL_F_DTLSV1_LISTEN 350 +# define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC 371 +# define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385 +# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370 +# define SSL_F_DTLS_PROCESS_HELLO_VERIFY 386 +# define SSL_F_DTLS_RECORD_LAYER_NEW 635 +# define SSL_F_DTLS_WAIT_FOR_DRY 592 +# define SSL_F_EARLY_DATA_COUNT_OK 532 +# define SSL_F_FINAL_EARLY_DATA 556 +# define SSL_F_FINAL_EC_PT_FORMATS 485 +# define SSL_F_FINAL_EMS 486 +# define SSL_F_FINAL_KEY_SHARE 503 +# define SSL_F_FINAL_MAXFRAGMENTLEN 557 +# define SSL_F_FINAL_RENEGOTIATE 483 +# define SSL_F_FINAL_SERVER_NAME 558 +# define SSL_F_FINAL_SIG_ALGS 497 +# define SSL_F_GET_CERT_VERIFY_TBS_DATA 588 +# define SSL_F_NSS_KEYLOG_INT 500 +# define SSL_F_OPENSSL_INIT_SSL 342 +# define SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION 436 +# define SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION 598 +# define SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE 430 +# define SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE 593 +# define SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE 594 +# define SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION 417 +# define SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION 599 +# define SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION 437 +# define SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION 600 +# define SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE 431 +# define SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE 601 +# define SSL_F_OSSL_STATEM_SERVER_POST_WORK 602 +# define SSL_F_OSSL_STATEM_SERVER_PRE_WORK 640 +# define SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE 603 +# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION 418 +# define SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION 604 +# define SSL_F_PARSE_CA_NAMES 541 +# define SSL_F_PITEM_NEW 624 +# define SSL_F_PQUEUE_NEW 625 +# define SSL_F_PROCESS_KEY_SHARE_EXT 439 +# define SSL_F_READ_STATE_MACHINE 352 +# define SSL_F_SET_CLIENT_CIPHERSUITE 540 +# define SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET 595 +# define SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET 589 +# define SSL_F_SRP_VERIFY_SERVER_PARAM 596 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 608 +# define SSL_F_SSL3_FINAL_FINISH_MAC 285 +# define SSL_F_SSL3_FINISH_MAC 587 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_INIT_FINISHED_MAC 397 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CERT_CHAIN 316 +# define SSL_F_SSL_ADD_CERT_TO_BUF 319 +# define SSL_F_SSL_ADD_CERT_TO_WPACKET 493 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BUILD_CERT_CHAIN 332 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CACHE_CIPHERLIST 520 +# define SSL_F_SSL_CERT_ADD0_CHAIN_CERT 346 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CERT_SET0_CHAIN 340 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO 606 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CHOOSE_CLIENT_VERSION 607 +# define SSL_F_SSL_CIPHER_DESCRIPTION 626 +# define SSL_F_SSL_CIPHER_LIST_TO_BYTES 425 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT 627 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CONF_CMD 334 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_ENABLE_CT 398 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_ALPN_PROTOS 343 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK 396 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH 551 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_CTX_USE_SERVERINFO 336 +# define SSL_F_SSL_CTX_USE_SERVERINFO_EX 543 +# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 +# define SSL_F_SSL_DANE_DUP 403 +# define SSL_F_SSL_DANE_ENABLE 395 +# define SSL_F_SSL_DERIVE 590 +# define SSL_F_SSL_DO_CONFIG 391 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_DUP_CA_LIST 408 +# define SSL_F_SSL_ENABLE_CT 402 +# define SSL_F_SSL_GENERATE_PKEY_GROUP 559 +# define SSL_F_SSL_GENERATE_SESSION_ID 547 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_HANDSHAKE_HASH 560 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_KEY_UPDATE 515 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_LOG_MASTER_SECRET 498 +# define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499 +# define SSL_F_SSL_MODULE_INIT 392 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_NEXT_PROTO_VALIDATE 565 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PEEK_EX 432 +# define SSL_F_SSL_PEEK_INTERNAL 522 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_READ_EARLY_DATA 529 +# define SSL_F_SSL_READ_EX 434 +# define SSL_F_SSL_READ_INTERNAL 523 +# define SSL_F_SSL_RENEGOTIATE 516 +# define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 +# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 +# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID 423 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SET_ALPN_PROTOS 344 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CERT_AND_KEY 621 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK 399 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH 550 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_START_ASYNC_JOB 389 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VALIDATE_CT 400 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE 616 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_SSL_WRITE_EARLY_DATA 526 +# define SSL_F_SSL_WRITE_EARLY_FINISH 527 +# define SSL_F_SSL_WRITE_EX 433 +# define SSL_F_SSL_WRITE_INTERNAL 524 +# define SSL_F_STATE_MACHINE 353 +# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 +# define SSL_F_TLS12_COPY_SIGALGS 533 +# define SSL_F_TLS13_CHANGE_CIPHER_STATE 440 +# define SSL_F_TLS13_ENC 609 +# define SSL_F_TLS13_FINAL_FINISH_MAC 605 +# define SSL_F_TLS13_GENERATE_SECRET 591 +# define SSL_F_TLS13_HKDF_EXPAND 561 +# define SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA 617 +# define SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA 618 +# define SSL_F_TLS13_SETUP_KEY_BLOCK 441 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS 341 +# define SSL_F_TLS1_ENC 401 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_GET_CURVELIST 338 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SAVE_U16 628 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_TLS1_SET_GROUPS 629 +# define SSL_F_TLS1_SET_RAW_SIGALGS 630 +# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 +# define SSL_F_TLS1_SET_SHARED_SIGALGS 631 +# define SSL_F_TLS1_SET_SIGALGS 632 +# define SSL_F_TLS_CHOOSE_SIGALG 513 +# define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK 354 +# define SSL_F_TLS_COLLECT_EXTENSIONS 435 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES 542 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST 372 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS 429 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY 494 +# define SSL_F_TLS_CONSTRUCT_CERT_VERIFY 496 +# define SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC 427 +# define SSL_F_TLS_CONSTRUCT_CKE_DHE 404 +# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405 +# define SSL_F_TLS_CONSTRUCT_CKE_GOST 406 +# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407 +# define SSL_F_TLS_CONSTRUCT_CKE_RSA 409 +# define SSL_F_TLS_CONSTRUCT_CKE_SRP 410 +# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE 484 +# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO 487 +# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE 488 +# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489 +# define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466 +# define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355 +# define SSL_F_TLS_CONSTRUCT_CTOS_COOKIE 535 +# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530 +# define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467 +# define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468 +# define SSL_F_TLS_CONSTRUCT_CTOS_ETM 469 +# define SSL_F_TLS_CONSTRUCT_CTOS_HELLO 356 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE 357 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE 470 +# define SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN 549 +# define SSL_F_TLS_CONSTRUCT_CTOS_NPN 471 +# define SSL_F_TLS_CONSTRUCT_CTOS_PADDING 472 +# define SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH 619 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK 501 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 509 +# define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 473 +# define SSL_F_TLS_CONSTRUCT_CTOS_SCT 474 +# define SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME 475 +# define SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET 476 +# define SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS 477 +# define SSL_F_TLS_CONSTRUCT_CTOS_SRP 478 +# define SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST 479 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS 480 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS 481 +# define SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP 482 +# define SSL_F_TLS_CONSTRUCT_CTOS_VERIFY 358 +# define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS 443 +# define SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA 536 +# define SSL_F_TLS_CONSTRUCT_EXTENSIONS 447 +# define SSL_F_TLS_CONSTRUCT_FINISHED 359 +# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST 373 +# define SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST 510 +# define SSL_F_TLS_CONSTRUCT_KEY_UPDATE 517 +# define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET 428 +# define SSL_F_TLS_CONSTRUCT_NEXT_PROTO 426 +# define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE 490 +# define SSL_F_TLS_CONSTRUCT_SERVER_HELLO 491 +# define SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE 492 +# define SSL_F_TLS_CONSTRUCT_STOC_ALPN 451 +# define SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE 374 +# define SSL_F_TLS_CONSTRUCT_STOC_COOKIE 613 +# define SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG 452 +# define SSL_F_TLS_CONSTRUCT_STOC_DONE 375 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA 531 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO 525 +# define SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS 453 +# define SSL_F_TLS_CONSTRUCT_STOC_EMS 454 +# define SSL_F_TLS_CONSTRUCT_STOC_ETM 455 +# define SSL_F_TLS_CONSTRUCT_STOC_HELLO 376 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE 377 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE 456 +# define SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN 548 +# define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG 457 +# define SSL_F_TLS_CONSTRUCT_STOC_PSK 504 +# define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE 458 +# define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME 459 +# define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET 460 +# define SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST 461 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS 544 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS 611 +# define SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP 462 +# define SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO 521 +# define SSL_F_TLS_FINISH_HANDSHAKE 597 +# define SSL_F_TLS_GET_MESSAGE_BODY 351 +# define SSL_F_TLS_GET_MESSAGE_HEADER 387 +# define SSL_F_TLS_HANDLE_ALPN 562 +# define SSL_F_TLS_HANDLE_STATUS_REQUEST 563 +# define SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES 566 +# define SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT 449 +# define SSL_F_TLS_PARSE_CTOS_ALPN 567 +# define SSL_F_TLS_PARSE_CTOS_COOKIE 614 +# define SSL_F_TLS_PARSE_CTOS_EARLY_DATA 568 +# define SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS 569 +# define SSL_F_TLS_PARSE_CTOS_EMS 570 +# define SSL_F_TLS_PARSE_CTOS_KEY_SHARE 463 +# define SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN 571 +# define SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH 620 +# define SSL_F_TLS_PARSE_CTOS_PSK 505 +# define SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES 572 +# define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464 +# define SSL_F_TLS_PARSE_CTOS_SERVER_NAME 573 +# define SSL_F_TLS_PARSE_CTOS_SESSION_TICKET 574 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS 575 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT 615 +# define SSL_F_TLS_PARSE_CTOS_SRP 576 +# define SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST 577 +# define SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS 578 +# define SSL_F_TLS_PARSE_CTOS_USE_SRTP 465 +# define SSL_F_TLS_PARSE_STOC_ALPN 579 +# define SSL_F_TLS_PARSE_STOC_COOKIE 534 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA 538 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 528 +# define SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS 580 +# define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445 +# define SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN 581 +# define SSL_F_TLS_PARSE_STOC_NPN 582 +# define SSL_F_TLS_PARSE_STOC_PSK 502 +# define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 448 +# define SSL_F_TLS_PARSE_STOC_SCT 564 +# define SSL_F_TLS_PARSE_STOC_SERVER_NAME 583 +# define SSL_F_TLS_PARSE_STOC_SESSION_TICKET 584 +# define SSL_F_TLS_PARSE_STOC_STATUS_REQUEST 585 +# define SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS 612 +# define SSL_F_TLS_PARSE_STOC_USE_SRTP 446 +# define SSL_F_TLS_POST_PROCESS_CLIENT_HELLO 378 +# define SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE 384 +# define SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE 360 +# define SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST 610 +# define SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST 361 +# define SSL_F_TLS_PROCESS_CERT_STATUS 362 +# define SSL_F_TLS_PROCESS_CERT_STATUS_BODY 495 +# define SSL_F_TLS_PROCESS_CERT_VERIFY 379 +# define SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC 363 +# define SSL_F_TLS_PROCESS_CKE_DHE 411 +# define SSL_F_TLS_PROCESS_CKE_ECDHE 412 +# define SSL_F_TLS_PROCESS_CKE_GOST 413 +# define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 414 +# define SSL_F_TLS_PROCESS_CKE_RSA 415 +# define SSL_F_TLS_PROCESS_CKE_SRP 416 +# define SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE 380 +# define SSL_F_TLS_PROCESS_CLIENT_HELLO 381 +# define SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE 382 +# define SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS 444 +# define SSL_F_TLS_PROCESS_END_OF_EARLY_DATA 537 +# define SSL_F_TLS_PROCESS_FINISHED 364 +# define SSL_F_TLS_PROCESS_HELLO_REQ 507 +# define SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST 511 +# define SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT 442 +# define SSL_F_TLS_PROCESS_KEY_EXCHANGE 365 +# define SSL_F_TLS_PROCESS_KEY_UPDATE 518 +# define SSL_F_TLS_PROCESS_NEW_SESSION_TICKET 366 +# define SSL_F_TLS_PROCESS_NEXT_PROTO 383 +# define SSL_F_TLS_PROCESS_SERVER_CERTIFICATE 367 +# define SSL_F_TLS_PROCESS_SERVER_DONE 368 +# define SSL_F_TLS_PROCESS_SERVER_HELLO 369 +# define SSL_F_TLS_PROCESS_SKE_DHE 419 +# define SSL_F_TLS_PROCESS_SKE_ECDHE 420 +# define SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE 421 +# define SSL_F_TLS_PROCESS_SKE_SRP 422 +# define SSL_F_TLS_PSK_DO_BINDER 506 +# define SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT 450 +# define SSL_F_TLS_SETUP_HANDSHAKE 508 +# define SSL_F_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_WPACKET_INTERN_INIT_LEN 633 +# define SSL_F_WPACKET_START_SUB_PACKET_LEN__ 634 +# define SSL_F_WRITE_STATE_MACHINE 586 + +/* + * SSL reason codes. + */ +# define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE 143 +# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CIPHER 186 +# define SSL_R_BAD_DATA 390 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_VALUE 102 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_EARLY_DATA 233 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_EXTENSION 110 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HANDSHAKE_STATE 236 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_HRR_VERSION 263 +# define SSL_R_BAD_KEY_SHARE 108 +# define SSL_R_BAD_KEY_UPDATE 122 +# define SSL_R_BAD_LEGACY_VERSION 292 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_PACKET 240 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK 219 +# define SSL_R_BAD_PSK_IDENTITY 114 +# define SSL_R_BAD_RECORD_TYPE 443 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_VALUE 384 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BINDER_DOES_NOT_VERIFY 253 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CALLBACK_FAILED 234 +# define SSL_R_CANNOT_CHANGE_CIPHER 109 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_KEY_TOO_SMALL 397 +# define SSL_R_CA_MD_TOO_WEAK 398 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_CB_ERROR 377 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED 218 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_CONTEXT_NOT_DANE_ENABLED 167 +# define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED 206 +# define SSL_R_DANE_ALREADY_ENABLED 172 +# define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL 173 +# define SSL_R_DANE_NOT_ENABLED 175 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE 180 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE 184 +# define SSL_R_DANE_TLSA_BAD_DATA_LENGTH 189 +# define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH 192 +# define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE 200 +# define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY 201 +# define SSL_R_DANE_TLSA_BAD_SELECTOR 202 +# define SSL_R_DANE_TLSA_NULL_DATA 203 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 394 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 +# define SSL_R_EE_KEY_TOO_SMALL 399 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204 +# define SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE 194 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTENSION_NOT_RECEIVED 279 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_EXT_LENGTH_MISMATCH 163 +# define SSL_R_FAILED_TO_INIT_ASYNC 405 +# define SSL_R_FRAGMENTED_CLIENT_HELLO 401 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_POINT_COMPRESSION 162 +# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INCONSISTENT_EARLY_DATA_ALPN 222 +# define SSL_R_INCONSISTENT_EARLY_DATA_SNI 231 +# define SSL_R_INCONSISTENT_EXTMS 104 +# define SSL_R_INSUFFICIENT_SECURITY 241 +# define SSL_R_INVALID_ALERT 205 +# define SSL_R_INVALID_CCS_MESSAGE 260 +# define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_CONFIG 283 +# define SSL_R_INVALID_CONFIGURATION_NAME 113 +# define SSL_R_INVALID_CONTEXT 282 +# define SSL_R_INVALID_CT_VALIDATION_TYPE 212 +# define SSL_R_INVALID_KEY_UPDATE_TYPE 120 +# define SSL_R_INVALID_MAX_EARLY_DATA 174 +# define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_SEQUENCE_NUMBER 402 +# define SSL_R_INVALID_SERVERINFO_DATA 388 +# define SSL_R_INVALID_SESSION_ID 999 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_LONG 404 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 +# define SSL_R_MISSING_FATAL 256 +# define SSL_R_MISSING_PARAMETERS 290 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SIGALGS_EXTENSION 112 +# define SSL_R_MISSING_SIGNING_CERT 221 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION 209 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 +# define SSL_R_NOT_ON_RECORD_BOUNDARY 182 +# define SSL_R_NOT_REPLACING_CERTIFICATE 289 +# define SSL_R_NOT_SERVER 284 +# define SSL_R_NO_APPLICATION_PROTOCOL 235 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CHANGE_FOLLOWING_HRR 214 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_COOKIE_CALLBACK_SET 287 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PEM_EXTENSIONS 389 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SHARED_GROUPS 410 +# define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_SUITABLE_KEY_SHARE 101 +# define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 +# define SSL_R_NO_VALID_SCTS 216 +# define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_OVERFLOW_ERROR 237 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEM_NAME_BAD_PREFIX 391 +# define SSL_R_PEM_NAME_TOO_SHORT 392 +# define SSL_R_PIPELINE_FAILURE 406 +# define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278 +# define SSL_R_PRIVATE_KEY_MISMATCH 288 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUEST_PENDING 285 +# define SSL_R_REQUEST_SENT 286 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SCT_VERIFICATION_FAILED 208 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH 232 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_COMMAND_SECTION_EMPTY 117 +# define SSL_R_SSL_COMMAND_SECTION_NOT_FOUND 125 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_NEGATIVE_LENGTH 372 +# define SSL_R_SSL_SECTION_EMPTY 126 +# define SSL_R_SSL_SECTION_NOT_FOUND 136 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_TOO_LONG 408 +# define SSL_R_SSL_SESSION_VERSION_MISMATCH 210 +# define SSL_R_STILL_IN_INIT 121 +# define SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 +# define SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TOO_MANY_KEY_UPDATES 132 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 +# define SSL_R_TOO_MUCH_EARLY_DATA 164 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_CCS_MESSAGE 262 +# define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_CMD_NAME 386 +# define SSL_R_UNKNOWN_COMMAND 139 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSOLICITED_EXTENSION 217 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_VERSION_TOO_HIGH 166 +# define SSL_R_VERSION_TOO_LOW 396 +# define SSL_R_WRONG_CERTIFICATE_TYPE 383 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/stack.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/stack.h new file mode 100644 index 00000000..cfc07505 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/stack.h @@ -0,0 +1,83 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */ + +typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); +typedef void (*OPENSSL_sk_freefunc)(void *); +typedef void *(*OPENSSL_sk_copyfunc)(const void *); + +int OPENSSL_sk_num(const OPENSSL_STACK *); +void *OPENSSL_sk_value(const OPENSSL_STACK *, int); + +void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data); + +OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n); +int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n); +void OPENSSL_sk_free(OPENSSL_STACK *); +void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *)); +OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *, + OPENSSL_sk_copyfunc c, + OPENSSL_sk_freefunc f); +int OPENSSL_sk_insert(OPENSSL_STACK *sk, const void *data, int where); +void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc); +void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p); +int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data); +void *OPENSSL_sk_shift(OPENSSL_STACK *st); +void *OPENSSL_sk_pop(OPENSSL_STACK *st); +void OPENSSL_sk_zero(OPENSSL_STACK *st); +OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *st); +void OPENSSL_sk_sort(OPENSSL_STACK *st); +int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _STACK OPENSSL_STACK +# define sk_num OPENSSL_sk_num +# define sk_value OPENSSL_sk_value +# define sk_set OPENSSL_sk_set +# define sk_new OPENSSL_sk_new +# define sk_new_null OPENSSL_sk_new_null +# define sk_free OPENSSL_sk_free +# define sk_pop_free OPENSSL_sk_pop_free +# define sk_deep_copy OPENSSL_sk_deep_copy +# define sk_insert OPENSSL_sk_insert +# define sk_delete OPENSSL_sk_delete +# define sk_delete_ptr OPENSSL_sk_delete_ptr +# define sk_find OPENSSL_sk_find +# define sk_find_ex OPENSSL_sk_find_ex +# define sk_push OPENSSL_sk_push +# define sk_unshift OPENSSL_sk_unshift +# define sk_shift OPENSSL_sk_shift +# define sk_pop OPENSSL_sk_pop +# define sk_zero OPENSSL_sk_zero +# define sk_set_cmp_func OPENSSL_sk_set_cmp_func +# define sk_dup OPENSSL_sk_dup +# define sk_sort OPENSSL_sk_sort +# define sk_is_sorted OPENSSL_sk_is_sorted +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/store.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/store.h new file mode 100644 index 00000000..a40a7339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/store.h @@ -0,0 +1,266 @@ +/* + * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STORE_H +# define HEADER_OSSL_STORE_H + +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * The main OSSL_STORE functions. + * ------------------------------ + * + * These allow applications to open a channel to a resource with supported + * data (keys, certs, crls, ...), read the data a piece at a time and decide + * what to do with it, and finally close. + */ + +typedef struct ossl_store_ctx_st OSSL_STORE_CTX; + +/* + * Typedef for the OSSL_STORE_INFO post processing callback. This can be used + * to massage the given OSSL_STORE_INFO, or to drop it entirely (by returning + * NULL). + */ +typedef OSSL_STORE_INFO *(*OSSL_STORE_post_process_info_fn)(OSSL_STORE_INFO *, + void *); + +/* + * Open a channel given a URI. The given UI method will be used any time the + * loader needs extra input, for example when a password or pin is needed, and + * will be passed the same user data every time it's needed in this context. + * + * Returns a context reference which represents the channel to communicate + * through. + */ +OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, + void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data); + +/* + * Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be + * done, and depends on the underlying loader (use OSSL_STORE_get0_scheme to + * determine which loader is used), except for common commands (see below). + * Each command takes different arguments. + */ +int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */); +int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); + +/* + * Common ctrl commands that different loaders may choose to support. + */ +/* int on = 0 or 1; STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on); */ +# define OSSL_STORE_C_USE_SECMEM 1 +/* Where custom commands start */ +# define OSSL_STORE_C_CUSTOM_START 100 + +/* + * Read one data item (a key, a cert, a CRL) that is supported by the OSSL_STORE + * functionality, given a context. + * Returns a OSSL_STORE_INFO pointer, from which OpenSSL typed data can be + * extracted with OSSL_STORE_INFO_get0_PKEY(), OSSL_STORE_INFO_get0_CERT(), ... + * NULL is returned on error, which may include that the data found at the URI + * can't be figured out for certain or is ambiguous. + */ +OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); + +/* + * Check if end of data (end of file) is reached + * Returns 1 on end, 0 otherwise. + */ +int OSSL_STORE_eof(OSSL_STORE_CTX *ctx); + +/* + * Check if an error occurred + * Returns 1 if it did, 0 otherwise. + */ +int OSSL_STORE_error(OSSL_STORE_CTX *ctx); + +/* + * Close the channel + * Returns 1 on success, 0 on error. + */ +int OSSL_STORE_close(OSSL_STORE_CTX *ctx); + + +/*- + * Extracting OpenSSL types from and creating new OSSL_STORE_INFOs + * --------------------------------------------------------------- + */ + +/* + * Types of data that can be ossl_stored in a OSSL_STORE_INFO. + * OSSL_STORE_INFO_NAME is typically found when getting a listing of + * available "files" / "tokens" / what have you. + */ +# define OSSL_STORE_INFO_NAME 1 /* char * */ +# define OSSL_STORE_INFO_PARAMS 2 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_PKEY 3 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_CERT 4 /* X509 * */ +# define OSSL_STORE_INFO_CRL 5 /* X509_CRL * */ + +/* + * Functions to generate OSSL_STORE_INFOs, one function for each type we + * support having in them, as well as a generic constructor. + * + * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO + * and will therefore be freed when the OSSL_STORE_INFO is freed. + */ +OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name); +int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); + +/* + * Functions to try to extract data from a OSSL_STORE_INFO. + */ +int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info); + +const char *OSSL_STORE_INFO_type_string(int type); + +/* + * Free the OSSL_STORE_INFO + */ +void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info); + + +/*- + * Functions to construct a search URI from a base URI and search criteria + * ----------------------------------------------------------------------- + */ + +/* OSSL_STORE search types */ +# define OSSL_STORE_SEARCH_BY_NAME 1 /* subject in certs, issuer in CRLs */ +# define OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 2 +# define OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 3 +# define OSSL_STORE_SEARCH_BY_ALIAS 4 + +/* To check what search types the scheme handler supports */ +int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type); + +/* Search term constructors */ +/* + * The input is considered to be owned by the caller, and must therefore + * remain present throughout the lifetime of the returned OSSL_STORE_SEARCH + */ +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, + const ASN1_INTEGER + *serial); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, + const unsigned char + *bytes, size_t len); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias); + +/* Search term destructor */ +void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search); + +/* Search term accessors */ +int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion); +X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion); +const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH + *criterion); +const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH + *criterion, size_t *length); +const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion); +const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion); + +/* + * Add search criterion and expected return type (which can be unspecified) + * to the loading channel. This MUST happen before the first OSSL_STORE_load(). + */ +int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type); +int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search); + + +/*- + * Function to register a loader for the given URI scheme. + * ------------------------------------------------------- + * + * The loader receives all the main components of an URI except for the + * scheme. + */ + +typedef struct ossl_store_loader_st OSSL_STORE_LOADER; +OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme); +const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); +const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); +/* struct ossl_store_loader_ctx_st is defined differently by each loader */ +typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; +typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER + *loader, + const char *uri, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, + OSSL_STORE_open_fn open_function); +typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd, + va_list args); +int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, + OSSL_STORE_ctrl_fn ctrl_function); +typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected); +int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader, + OSSL_STORE_expect_fn expect_function); +typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx, + OSSL_STORE_SEARCH *criteria); +int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader, + OSSL_STORE_find_fn find_function); +typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader, + OSSL_STORE_load_fn load_function); +typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader, + OSSL_STORE_eof_fn eof_function); +typedef int (*OSSL_STORE_error_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, + OSSL_STORE_error_fn error_function); +typedef int (*OSSL_STORE_close_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, + OSSL_STORE_close_fn close_function); +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); + +int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); +OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme); + +/*- + * Functions to list STORE loaders + * ------------------------------- + */ +int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER + *loader, void *do_arg), + void *do_arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/storeerr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/storeerr.h new file mode 100644 index 00000000..190eab07 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/storeerr.h @@ -0,0 +1,91 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STOREERR_H +# define HEADER_OSSL_STOREERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OSSL_STORE_strings(void); + +/* + * OSSL_STORE function codes. + */ +# define OSSL_STORE_F_FILE_CTRL 129 +# define OSSL_STORE_F_FILE_FIND 138 +# define OSSL_STORE_F_FILE_GET_PASS 118 +# define OSSL_STORE_F_FILE_LOAD 119 +# define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 124 +# define OSSL_STORE_F_FILE_NAME_TO_URI 126 +# define OSSL_STORE_F_FILE_OPEN 120 +# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 127 +# define OSSL_STORE_F_OSSL_STORE_EXPECT 130 +# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 128 +# define OSSL_STORE_F_OSSL_STORE_FIND 131 +# define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 100 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 101 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL 102 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME 103 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION 135 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS 104 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY 105 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT 106 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL 107 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED 123 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME 109 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS 110 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY 111 +# define OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION 134 +# define OSSL_STORE_F_OSSL_STORE_INIT_ONCE 112 +# define OSSL_STORE_F_OSSL_STORE_LOADER_NEW 113 +# define OSSL_STORE_F_OSSL_STORE_OPEN 114 +# define OSSL_STORE_F_OSSL_STORE_OPEN_INT 115 +# define OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT 117 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS 132 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 133 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 136 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME 137 +# define OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT 116 +# define OSSL_STORE_F_TRY_DECODE_PARAMS 121 +# define OSSL_STORE_F_TRY_DECODE_PKCS12 122 +# define OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED 125 + +/* + * OSSL_STORE reason codes. + */ +# define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107 +# define OSSL_STORE_R_BAD_PASSWORD_READ 115 +# define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113 +# define OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST 121 +# define OSSL_STORE_R_INVALID_SCHEME 106 +# define OSSL_STORE_R_IS_NOT_A 112 +# define OSSL_STORE_R_LOADER_INCOMPLETE 116 +# define OSSL_STORE_R_LOADING_STARTED 117 +# define OSSL_STORE_R_NOT_A_CERTIFICATE 100 +# define OSSL_STORE_R_NOT_A_CRL 101 +# define OSSL_STORE_R_NOT_A_KEY 102 +# define OSSL_STORE_R_NOT_A_NAME 103 +# define OSSL_STORE_R_NOT_PARAMETERS 104 +# define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114 +# define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108 +# define OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 119 +# define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109 +# define OSSL_STORE_R_UNREGISTERED_SCHEME 105 +# define OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE 110 +# define OSSL_STORE_R_UNSUPPORTED_OPERATION 118 +# define OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE 120 +# define OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED 111 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/symhacks.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/symhacks.h new file mode 100644 index 00000000..156ea6e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/symhacks.h @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tls1.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tls1.h new file mode 100644 index 00000000..76d9fda4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tls1.h @@ -0,0 +1,1237 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Default security level if not overridden at config time */ +# ifndef OPENSSL_TLS_SECURITY_LEVEL +# define OPENSSL_TLS_SECURITY_LEVEL 1 +# endif + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS1_3_VERSION 0x0304 +# define TLS_MAX_VERSION TLS1_3_VERSION + +/* Special value for method supporting multiple versions */ +# define TLS_ANY_VERSION 0x10000 + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((SSL_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_version(s) : 0) + +# define TLS1_get_client_version(s) \ + ((SSL_client_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_client_version(s) : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* TLSv1.3 alerts */ +# define TLS13_AD_MISSING_EXTENSION 109 /* fatal */ +# define TLS13_AD_CERTIFICATE_REQUIRED 116 /* fatal */ +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ +# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +/* + * Prior to TLSv1.3 the supported_groups extension was known as + * elliptic_curves + */ +# define TLSEXT_TYPE_supported_groups 10 +# define TLSEXT_TYPE_elliptic_curves TLSEXT_TYPE_supported_groups +# define TLSEXT_TYPE_ec_point_formats 11 + + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC7301 */ +# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* + * Extension type for Certificate Transparency + * https://tools.ietf.org/html/rfc6962#section-3.3.1 + */ +# define TLSEXT_TYPE_signed_certificate_timestamp 18 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC7366 */ +# define TLSEXT_TYPE_encrypt_then_mac 22 + +/* ExtensionType value from RFC7627 */ +# define TLSEXT_TYPE_extended_master_secret 23 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* As defined for TLS1.3 */ +# define TLSEXT_TYPE_psk 41 +# define TLSEXT_TYPE_early_data 42 +# define TLSEXT_TYPE_supported_versions 43 +# define TLSEXT_TYPE_cookie 44 +# define TLSEXT_TYPE_psk_kex_modes 45 +# define TLSEXT_TYPE_certificate_authorities 47 +# define TLSEXT_TYPE_post_handshake_auth 49 +# define TLSEXT_TYPE_signature_algorithms_cert 50 +# define TLSEXT_TYPE_key_share 51 + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 +# define TLSEXT_signature_gostr34102001 237 +# define TLSEXT_signature_gostr34102012_256 238 +# define TLSEXT_signature_gostr34102012_512 239 + +/* Total number of different signature algorithms */ +# define TLSEXT_signature_num 7 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 +# define TLSEXT_hash_gostr3411 237 +# define TLSEXT_hash_gostr34112012_256 238 +# define TLSEXT_hash_gostr34112012_512 239 + +/* Total number of different digest algorithms */ + +# define TLSEXT_hash_num 10 + +/* Flag set for unrecognised algorithms */ +# define TLSEXT_nid_unknown 0x1000000 + +/* ECC curves */ + +# define TLSEXT_curve_P_256 23 +# define TLSEXT_curve_P_384 24 + +/* OpenSSL value to disable maximum fragment length extension */ +# define TLSEXT_max_fragment_length_DISABLED 0 +/* Allowed values for max fragment length extension */ +# define TLSEXT_max_fragment_length_512 1 +# define TLSEXT_max_fragment_length_1024 2 +# define TLSEXT_max_fragment_length_2048 3 +# define TLSEXT_max_fragment_length_4096 4 + +int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode); +int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode); + +# define TLSEXT_MAXLEN_host_name 255 + +__owur const char *SSL_get_servername(const SSL *s, const int type); +__owur int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * 0 or -1 otherwise. + */ +__owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context); + +/* + * SSL_export_keying_material_early exports a value derived from the + * early exporter master secret, as specified in + * https://tools.ietf.org/html/draft-ietf-tls-tls13-23. It writes + * |olen| bytes to |out| given a label and optional context. It + * returns 1 on success and 0 otherwise. + */ +__owur int SSL_export_keying_material_early(SSL *s, unsigned char *out, + size_t olen, const char *label, + size_t llen, + const unsigned char *context, + size_t contextlen); + +int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid); +int SSL_get_signature_type_nid(const SSL *s, int *pnid); + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +__owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); + +# define SSL_set_tlsext_host_name(s,name) \ + SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,\ + (void *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ + SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,\ + (void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0,arg) + +# define SSL_get_tlsext_status_type(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_set_tlsext_status_type(ssl, type) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0,arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen,arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ + SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,\ + (void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0,arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_TLSEXT_TICKET_KEYS,keylen,keys) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_TICKET_KEYS,keylen,keys) + +# define SSL_CTX_get_tlsext_status_cb(ssl, cb) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB,0,(void *)cb) +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,\ + (void (*)(void))cb) + +# define SSL_CTX_get_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) + +# define SSL_CTX_set_tlsext_status_type(ssl, type) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_CTX_get_tlsext_status_type(ssl) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,\ + (void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_DTLSEXT_HB_ENABLED 0x01 +# define SSL_DTLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_DTLSEXT_HB_DONT_RECV_REQUESTS 0x04 +# define SSL_get_dtlsext_heartbeat_pending(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_dtlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT \ + SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING \ + SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS \ + SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS +# define SSL_TLSEXT_HB_ENABLED \ + SSL_DTLSEXT_HB_ENABLED +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS \ + SSL_DTLSEXT_HB_DONT_SEND_REQUESTS +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS \ + SSL_DTLSEXT_HB_DONT_RECV_REQUESTS +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_get_dtlsext_heartbeat_pending(ssl) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_set_dtlsext_heartbeat_no_requests(ssl,arg) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D +# define TLS1_CK_DHE_PSK_WITH_RC4_128_SHA 0x0300008E +# define TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008F +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA 0x03000090 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA 0x03000091 +# define TLS1_CK_RSA_PSK_WITH_RC4_128_SHA 0x03000092 +# define TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x03000093 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA 0x03000094 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA 0x03000095 + +/* PSK ciphersuites from 5487 */ +# define TLS1_CK_PSK_WITH_AES_128_GCM_SHA256 0x030000A8 +# define TLS1_CK_PSK_WITH_AES_256_GCM_SHA384 0x030000A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256 0x030000AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384 0x030000AB +# define TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256 0x030000AC +# define TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384 0x030000AD +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA256 0x030000AE +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA384 0x030000AF +# define TLS1_CK_PSK_WITH_NULL_SHA256 0x030000B0 +# define TLS1_CK_PSK_WITH_NULL_SHA384 0x030000B1 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256 0x030000B2 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384 0x030000B3 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA256 0x030000B4 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA384 0x030000B5 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256 0x030000B6 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384 0x030000B7 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA256 0x030000B8 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA384 0x030000B9 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_PSK_WITH_NULL_SHA 0x0300002C +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA 0x0300002D +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA 0x0300002E + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_CK_RSA_WITH_AES_128_CCM 0x0300C09C +# define TLS1_CK_RSA_WITH_AES_256_CCM 0x0300C09D +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM 0x0300C09E +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM 0x0300C09F +# define TLS1_CK_RSA_WITH_AES_128_CCM_8 0x0300C0A0 +# define TLS1_CK_RSA_WITH_AES_256_CCM_8 0x0300C0A1 +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8 0x0300C0A2 +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8 0x0300C0A3 +# define TLS1_CK_PSK_WITH_AES_128_CCM 0x0300C0A4 +# define TLS1_CK_PSK_WITH_AES_256_CCM 0x0300C0A5 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM 0x0300C0A6 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM 0x0300C0A7 +# define TLS1_CK_PSK_WITH_AES_128_CCM_8 0x0300C0A8 +# define TLS1_CK_PSK_WITH_AES_256_CCM_8 0x0300C0A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8 0x0300C0AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8 0x0300C0AB + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM 0x0300C0AC +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM 0x0300C0AD +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8 0x0300C0AE +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8 0x0300C0AF + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BA +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BB +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BC +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BD +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BE +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 0x030000BF + +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C0 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C1 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C2 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C3 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C4 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 0x030000C5 + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* ECDHE PSK ciphersuites from RFC5489 */ +# define TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA 0x0300C033 +# define TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300C034 +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0x0300C037 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0x0300C038 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA 0x0300C039 +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256 0x0300C03A +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384 0x0300C03B + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C072 +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C073 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C074 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C075 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C076 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C077 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C078 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C079 + +# define TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C094 +# define TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C095 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C096 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C097 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C098 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C099 +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C09A +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C09B + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCA8 +# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0x0300CCA9 +# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCAA +# define TLS1_CK_PSK_WITH_CHACHA20_POLY1305 0x0300CCAB +# define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAC +# define TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAD +# define TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305 0x0300CCAE + +/* TLS v1.3 ciphersuites */ +# define TLS1_3_CK_AES_128_GCM_SHA256 0x03001301 +# define TLS1_3_CK_AES_256_GCM_SHA384 0x03001302 +# define TLS1_3_CK_CHACHA20_POLY1305_SHA256 0x03001303 +# define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 +# define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 +# define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 +# define TLS1_CK_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C052 +# define TLS1_CK_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C053 +# define TLS1_CK_DH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C054 +# define TLS1_CK_DH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C055 +# define TLS1_CK_DHE_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C056 +# define TLS1_CK_DHE_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C057 +# define TLS1_CK_DH_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C058 +# define TLS1_CK_DH_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C059 +# define TLS1_CK_DH_anon_WITH_ARIA_128_GCM_SHA256 0x0300C05A +# define TLS1_CK_DH_anon_WITH_ARIA_256_GCM_SHA384 0x0300C05B +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05C +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05D +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05E +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05F +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C060 +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C061 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C062 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C063 +# define TLS1_CK_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06A +# define TLS1_CK_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06B +# define TLS1_CK_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06C +# define TLS1_CK_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06D +# define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E +# define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_128_SHA "TLS_DH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_WITH_AES_256_SHA "TLS_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_256_SHA "TLS_DH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_NULL_SHA256 "TLS_RSA_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_SHA256 "TLS_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_SHA256 "TLS_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA256 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA256 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA256 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA256 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_128_SHA256 "TLS_DH_anon_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_SHA256 "TLS_DH_anon_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_GCM_SHA256 "TLS_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_GCM_SHA384 "TLS_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_GCM_SHA256 "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_GCM_SHA384 "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ADH_WITH_AES_128_GCM_SHA256 "TLS_DH_anon_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_GCM_SHA384 "TLS_DH_anon_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_WITH_AES_128_CCM "TLS_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_RSA_WITH_AES_256_CCM "TLS_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM "TLS_DHE_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM "TLS_DHE_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_RSA_WITH_AES_128_CCM_8 "TLS_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_RSA_WITH_AES_256_CCM_8 "TLS_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM_8 "TLS_DHE_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM_8 "TLS_DHE_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_128_CCM "TLS_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_PSK_WITH_AES_256_CCM "TLS_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM "TLS_DHE_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM "TLS_DHE_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_PSK_WITH_AES_128_CCM_8 "TLS_PSK_WITH_AES_128_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_256_CCM_8 "TLS_PSK_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM_8 "TLS_PSK_DHE_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM_8 "TLS_PSK_DHE_WITH_AES_256_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM "TLS_ECDHE_ECDSA_WITH_AES_128_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM "TLS_ECDHE_ECDSA_WITH_AES_256_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8" +# define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +# define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +# define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +# define TLS1_3_RFC_AES_128_CCM_SHA256 "TLS_AES_128_CCM_SHA256" +# define TLS1_3_RFC_AES_128_CCM_8_SHA256 "TLS_AES_128_CCM_8_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_NULL_SHA "TLS_ECDHE_ECDSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_NULL_SHA "TLS_ECDHE_RSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_NULL_SHA "TLS_ECDH_anon_WITH_NULL_SHA" +# define TLS1_RFC_ECDH_anon_WITH_DES_192_CBC3_SHA "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_128_CBC_SHA "TLS_ECDH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_256_CBC_SHA "TLS_ECDH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA "TLS_PSK_WITH_NULL_SHA" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA "TLS_DHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA "TLS_RSA_PSK_WITH_NULL_SHA" +# define TLS1_RFC_PSK_WITH_3DES_EDE_CBC_SHA "TLS_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA "TLS_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA "TLS_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_3DES_EDE_CBC_SHA "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA "TLS_RSA_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA "TLS_RSA_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_GCM_SHA256 "TLS_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_GCM_SHA384 "TLS_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_GCM_SHA256 "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_GCM_SHA384 "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_GCM_SHA256 "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_GCM_SHA384 "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA256 "TLS_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA384 "TLS_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA256 "TLS_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_PSK_WITH_NULL_SHA384 "TLS_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA256 "TLS_DHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA384 "TLS_DHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA256 "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA384 "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA256 "TLS_RSA_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA384 "TLS_RSA_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA "TLS_ECDHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA256 "TLS_ECDHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA384 "TLS_ECDHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_SRP_SHA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CHACHA20_POLY1305 "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_WITH_SEED_SHA "TLS_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_SEED_SHA "TLS_DHE_DSS_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_SEED_SHA "TLS_DHE_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ADH_WITH_SEED_SHA "TLS_DH_anon_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_RC4_128_SHA "TLS_ECDHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDH_anon_WITH_RC4_128_SHA "TLS_ECDH_anon_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_RC4_128_SHA "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_RC4_128_SHA "TLS_ECDHE_RSA_WITH_RC4_128_SHA" +# define TLS1_RFC_PSK_WITH_RC4_128_SHA "TLS_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_PSK_WITH_RC4_128_SHA "TLS_RSA_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_DHE_PSK_WITH_RC4_128_SHA "TLS_DHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_anon_WITH_ARIA_128_GCM_SHA256 "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_anon_WITH_ARIA_256_GCM_SHA384 "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" + + +/* + * XXX Backward compatibility alert: Older versions of OpenSSL gave some DHE + * ciphers names with "EDH" instead of "DHE". Going forward, we should be + * using DHE everywhere, though we may indefinitely maintain aliases for + * users or configurations that used "EDH" + */ +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +# define TLS1_TXT_PSK_WITH_NULL_SHA "PSK-NULL-SHA" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA "DHE-PSK-NULL-SHA" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA "RSA-PSK-NULL-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +# define TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA "DHE-PSK-RC4-SHA" +# define TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA "DHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA "DHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA "DHE-PSK-AES256-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA "RSA-PSK-RC4-SHA" +# define TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA "RSA-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA "RSA-PSK-AES128-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA "RSA-PSK-AES256-CBC-SHA" + +/* PSK ciphersuites from RFC 5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256 "DHE-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384 "DHE-PSK-AES256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256 "RSA-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384 "RSA-PSK-AES256-GCM-SHA384" + +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256 "PSK-AES128-CBC-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384 "PSK-AES256-CBC-SHA384" +# define TLS1_TXT_PSK_WITH_NULL_SHA256 "PSK-NULL-SHA256" +# define TLS1_TXT_PSK_WITH_NULL_SHA384 "PSK-NULL-SHA384" + +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256 "DHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384 "DHE-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA256 "DHE-PSK-NULL-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA384 "DHE-PSK-NULL-SHA384" + +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256 "RSA-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384 "RSA-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA256 "RSA-PSK-NULL-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA384 "RSA-PSK-NULL-SHA384" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 "CAMELLIA128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DH-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DHE-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 "ADH-CAMELLIA128-SHA256" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 "CAMELLIA256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DH-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DH-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DHE-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DHE-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 "ADH-CAMELLIA256-SHA256" + +# define TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256 "PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384 "PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "DHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "DHE-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "RSA-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "RSA-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-PSK-CAMELLIA256-SHA384" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_TXT_RSA_WITH_AES_128_CCM "AES128-CCM" +# define TLS1_TXT_RSA_WITH_AES_256_CCM "AES256-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM "DHE-RSA-AES128-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM "DHE-RSA-AES256-CCM" + +# define TLS1_TXT_RSA_WITH_AES_128_CCM_8 "AES128-CCM8" +# define TLS1_TXT_RSA_WITH_AES_256_CCM_8 "AES256-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8 "DHE-RSA-AES128-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8 "DHE-RSA-AES256-CCM8" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM "PSK-AES128-CCM" +# define TLS1_TXT_PSK_WITH_AES_256_CCM "PSK-AES256-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM "DHE-PSK-AES128-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM "DHE-PSK-AES256-CCM" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM_8 "PSK-AES128-CCM8" +# define TLS1_TXT_PSK_WITH_AES_256_CCM_8 "PSK-AES256-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8 "DHE-PSK-AES128-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8 "DHE-PSK-AES256-CCM8" + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM "ECDHE-ECDSA-AES128-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM "ECDHE-ECDSA-AES256-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8 "ECDHE-ECDSA-AES128-CCM8" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8 "ECDHE-ECDSA-AES256-CCM8" + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +/* TLS v1.2 PSK GCM ciphersuites from RFC5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" + +/* ECDHE PSK ciphersuites from RFC 5489 */ +# define TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA "ECDHE-PSK-RC4-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "ECDHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-PSK-AES256-CBC-SHA" + +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "ECDHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "ECDHE-PSK-AES256-CBC-SHA384" + +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA "ECDHE-PSK-NULL-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256 "ECDHE-PSK-NULL-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384 "ECDHE-PSK-NULL-SHA384" + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-RSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-RSA-CAMELLIA256-SHA384" + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_PSK_WITH_CHACHA20_POLY1305 "PSK-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305 "ECDHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305 "DHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305 "RSA-PSK-CHACHA20-POLY1305" + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_TXT_RSA_WITH_ARIA_128_GCM_SHA256 "ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_ARIA_256_GCM_SHA384 "ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "DHE-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "DHE-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_ARIA_128_GCM_SHA256 "DH-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_ARIA_256_GCM_SHA384 "DH-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "DHE-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "DHE-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_ARIA_128_GCM_SHA256 "DH-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_ARIA_256_GCM_SHA384 "DH-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_anon_WITH_ARIA_128_GCM_SHA256 "ADH-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_anon_WITH_ARIA_256_GCM_SHA384 "ADH-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ARIA256-GCM-SHA384" +# define TLS1_TXT_PSK_WITH_ARIA_128_GCM_SHA256 "PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_ARIA_256_GCM_SHA384 "PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "DHE-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "DHE-PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "RSA-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "RSA-PSK-ARIA256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST01_SIGN 22 +# define TLS_CT_GOST12_SIGN 238 +# define TLS_CT_GOST12_512_SIGN 239 + +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 10 + +# if defined(SSL3_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 22 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "extended master secret" +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE 22 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# undef TLS_MD_EXTENDED_MASTER_SECRET_CONST +/* + * extended master secret + */ +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x6e\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ts.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ts.h new file mode 100644 index 00000000..3b58aa52 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ts.h @@ -0,0 +1,559 @@ +/* + * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include + +# ifndef OPENSSL_NO_TS +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# include +# include + +typedef struct TS_msg_imprint_st TS_MSG_IMPRINT; +typedef struct TS_req_st TS_REQ; +typedef struct TS_accuracy_st TS_ACCURACY; +typedef struct TS_tst_info_st TS_TST_INFO; + +/* Possible values for status. */ +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. */ +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + + +typedef struct TS_status_info_st TS_STATUS_INFO; +typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; +typedef struct ESS_cert_id ESS_CERT_ID; +typedef struct ESS_signing_cert ESS_SIGNING_CERT; + +DEFINE_STACK_OF(ESS_CERT_ID) + +typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2; +typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2; + +DEFINE_STACK_OF(ESS_CERT_ID_V2) + +typedef struct TS_resp_st TS_RESP; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +#ifndef OPENSSL_NO_STDIO +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +#endif +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +#ifndef OPENSSL_NO_STDIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +#endif +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +#ifndef OPENSSL_NO_STDIO +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +#endif +TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +#ifndef OPENSSL_NO_STDIO +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +#endif +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void); +void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a); +int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp); +ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a, + const unsigned char **pp, long length); +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a); + +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void); +void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a); +int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **pp); +ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a, + const unsigned char **pp, + long length); +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i); +const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a); + +const STACK_OF(ASN1_UTF8STRING) * +TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a); + +const ASN1_BIT_STRING * +TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, + int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx TS_RESP_CTX; + +DEFINE_STACK_OF_CONST(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, + const EVP_MD *signer_digest); +int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* Maximum status message length */ +# define TS_MAX_STATUS_LENGTH (1024 * 1024) + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); +int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f); +int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f); +BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b); +unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, + unsigned char *hexstr, long len); +X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s); +STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +#ifndef OPENSSL_NO_ENGINE +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +#endif +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_digest(CONF *conf, const char *section, + const char *md, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tserr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tserr.h new file mode 100644 index 00000000..07f23339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/tserr.h @@ -0,0 +1,132 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TSERR_H +# define HEADER_TSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_TS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_TS_strings(void); + +/* + * TS function codes. + */ +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_ADD_SIGNING_CERT_V2 147 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_CERT_ID_V2_NEW_INIT 156 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_ESS_SIGNING_CERT_V2_NEW_INIT 157 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_INVALID 151 +# define TS_F_TS_CONF_LOAD_CERT 153 +# define TS_F_TS_CONF_LOAD_CERTS 154 +# define TS_F_TS_CONF_LOAD_KEY 155 +# define TS_F_TS_CONF_LOOKUP_FAIL 152 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* + * TS reason codes. + */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CANNOT_LOAD_CERT 137 +# define TS_R_CANNOT_LOAD_KEY 138 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR 139 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_VAR_BAD_VALUE 135 +# define TS_R_VAR_LOOKUP_FAILURE 136 +# define TS_R_WRONG_CONTENT_TYPE 114 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/txt_db.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/txt_db.h new file mode 100644 index 00000000..ec981a43 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/txt_db.h @@ -0,0 +1,57 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include +# include +# include +# include + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 +# define DB_ERROR_WRONG_NUM_FIELDS 6 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DEFINE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ui.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ui.h new file mode 100644 index 00000000..7c721ec8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/ui.h @@ -0,0 +1,368 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# include +# include +# include + +/* For compatibility reasons, the macro OPENSSL_NO_UI is currently retained */ +# if OPENSSL_API_COMPAT < 0x10200000L +# ifdef OPENSSL_NO_UI_CONSOLE +# define OPENSSL_NO_UI +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is useful when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* + * Alternatively, this function is used to duplicate the user data. + * This uses the duplicator method function. The destroy function will + * be used to free the user data in this case. + */ +int UI_dup_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); +int UI_get_result_length(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parameterised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) + +# define UI_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, l, p, newf, dupf, freef) +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +# ifndef OPENSSL_NO_UI_CONSOLE + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +# endif + +/* + * NULL method. Literally does nothing, but may serve as a placeholder + * to avoid internal default. + */ +const UI_METHOD *UI_null(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called with all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DEFINE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(const char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_data_duplicator(UI_METHOD *method, + void *(*duplicator) (UI *ui, void *ui_data), + void (*destructor)(UI *ui, void *ui_data)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data); +int (*UI_method_get_opener(const UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(const UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(const UI_METHOD *method)) + (UI *, const char *, const char *); +void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *); +void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *); +const void *UI_method_get_ex_data(const UI_METHOD *method, int idx); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean prompt + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +int UI_get_result_string_length(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); +int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); +UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/uierr.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/uierr.h new file mode 100644 index 00000000..bd68864d --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/uierr.h @@ -0,0 +1,65 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UIERR_H +# define HEADER_UIERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_UI_strings(void); + +/* + * UI function codes. + */ +# define UI_F_CLOSE_CONSOLE 115 +# define UI_F_ECHO_CONSOLE 116 +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_NOECHO_CONSOLE 117 +# define UI_F_OPEN_CONSOLE 114 +# define UI_F_UI_CONSTRUCT_PROMPT 121 +# define UI_F_UI_CREATE_METHOD 112 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_USER_DATA 118 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_GET_RESULT_LENGTH 119 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_PROCESS 113 +# define UI_F_UI_SET_RESULT 105 +# define UI_F_UI_SET_RESULT_EX 120 + +/* + * UI reason codes. + */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_PROCESSING_ERROR 107 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_SYSASSIGN_ERROR 109 +# define UI_R_SYSDASSGN_ERROR 110 +# define UI_R_SYSQIOW_ERROR 111 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 +# define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE 108 +# define UI_R_USER_DATA_DUPLICATION_UNSUPPORTED 112 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/whrlpool.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/whrlpool.h new file mode 100644 index 00000000..20ea3503 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/whrlpool.h @@ -0,0 +1,48 @@ +/* + * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +#include + +# ifndef OPENSSL_NO_WHIRLPOOL +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509.h new file mode 100644 index 00000000..39ca0ba5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509.h @@ -0,0 +1,1047 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Flags for X509_get_signature_info() */ +/* Signature info is valid */ +# define X509_SIG_INFO_VALID 0x1 +/* Signature is suitable for TLS use */ +# define X509_SIG_INFO_TLS 0x2 + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +typedef struct X509_sig_st X509_SIG; + +typedef struct X509_name_entry_st X509_NAME_ENTRY; + +DEFINE_STACK_OF(X509_NAME_ENTRY) + +DEFINE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) + +typedef struct x509_attributes_st X509_ATTRIBUTE; + +DEFINE_STACK_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st X509_REQ_INFO; + +typedef struct X509_req_st X509_REQ; + +typedef struct x509_cert_aux_st X509_CERT_AUX; + +typedef struct x509_cinf_st X509_CINF; + +DEFINE_STACK_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DEFINE_STACK_OF(X509_TRUST) + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT 0 /* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC (1U << 0) +# define X509_TRUST_DYNAMIC_NAME (1U << 1) +/* No compat trust if self-signed, preempts "DO_SS" */ +# define X509_TRUST_NO_SS_COMPAT (1U << 2) +/* Compat trust if no explicit accepted trust EKUs */ +# define X509_TRUST_DO_SS_COMPAT (1U << 3) +/* Accept "anyEKU" as a wildcard trust OID */ +# define X509_TRUST_OK_ANY_EKU (1U << 4) + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional; use old X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +DEFINE_STACK_OF(X509_REVOKED) + +typedef struct X509_crl_info_st X509_CRL_INFO; + +DEFINE_STACK_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; +} X509_PKEY; + +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; +} X509_INFO; + +DEFINE_STACK_OF(X509_INFO) + +/* + * The next 2 structures and their 8 routines are used to manipulate Netscape's + * spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +#ifndef OPENSSL_NO_SCRYPT +typedef struct SCRYPT_PARAMS_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; + ASN1_INTEGER *blockSize; + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; +} SCRYPT_PARAMS; +#endif + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +const char *X509_verify_cert_error_string(long n); + +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +# endif +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +# endif +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + +# ifndef OPENSSL_NO_STDIO +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, const X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +long X509_get_pathlen(X509 *x); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, + const ASN1_OCTET_STRING **pdigest); +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, + ASN1_OCTET_STRING **pdigest); + +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +#define X509_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef) +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid, + int *secbits, uint32_t *flags); +void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, + int secbits, uint32_t flags); + +int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, + uint32_t *flags); + +void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_trusted(const X509 *x); +int X509_alias_set1(X509 *x, const unsigned char *name, int len); +int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x); +STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); + +long X509_get_version(const X509 *x); +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(const X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(const X509 *a); +const ASN1_TIME * X509_get0_notBefore(const X509 *x); +ASN1_TIME *X509_getm_notBefore(const X509 *x); +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); +const ASN1_TIME *X509_get0_notAfter(const X509 *x); +ASN1_TIME *X509_getm_notAfter(const X509 *x); +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +int X509_up_ref(X509 *x); +int X509_get_signature_type(const X509 *x); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_get_notBefore X509_getm_notBefore +# define X509_get_notAfter X509_getm_notAfter +# define X509_set_notBefore X509_set1_notBefore +# define X509_set_notAfter X509_set1_notAfter +#endif + + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf) + */ +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); +void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid); +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); + +EVP_PKEY *X509_get0_pubkey(const X509 *x); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); + +long X509_REQ_get_version(const X509_REQ *req); +int X509_REQ_set_version(X509_REQ *x, long version); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_REQ_get_signature_nid(const X509_REQ *req); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); +int X509_CRL_up_ref(X509_CRL *crl); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +# define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate +#endif + +long X509_CRL_get_version(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)) +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)) +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_CRL_get_signature_nid(const X509_CRL *crl); +int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); + +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); +const STACK_OF(X509_EXTENSION) * +X509_REVOKED_get0_extensions(const X509_REVOKED *r); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_aux_print(BIO *out, X509 *x, int indent); +# ifndef OPENSSL_NO_STDIO +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags); +# endif + +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); + +int X509_NAME_entry_count(const X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, + const unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(const X509 *x); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(const X509_CRL *x); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, + int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, + int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + const ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) +#ifndef OPENSSL_NO_SCRYPT +DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS) +#endif + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +#ifndef OPENSSL_NO_SCRYPT +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p); +#endif + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); + +const STACK_OF(X509_ATTRIBUTE) * +PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(const X509_TRUST *xp); +char *X509_TRUST_get0_name(const X509_TRUST *xp); +int X509_TRUST_get_trust(const X509_TRUST *xp); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509_vfy.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509_vfy.h new file mode 100644 index 00000000..adb8bce7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509_vfy.h @@ -0,0 +1,628 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +/* + * Protect against recursion, x509.h and x509_vfy.h each include the other. + */ +# ifndef HEADER_X509_H +# include +# endif + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +typedef enum { + X509_LU_NONE = 0, + X509_LU_X509, X509_LU_CRL +} X509_LOOKUP_TYPE; + +#if OPENSSL_API_COMPAT < 0x10100000L +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#endif + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_STACK_OF(X509_OBJECT) +DEFINE_STACK_OF(X509_VERIFY_PARAM) + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, + X509_STORE_CTX *ctx, X509 *x); +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, + X509 *x, X509 *issuer); +typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL **crl, X509 *x); +typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); +typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL *crl, X509 *x); +typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); +typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); + + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +# define X509_V_ERR_UNNESTED_RESOURCE 46 +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +# define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +# define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +# define X509_V_ERR_EE_KEY_TOO_SMALL 66 +# define X509_V_ERR_CA_KEY_TOO_SMALL 67 +# define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +# define X509_V_ERR_NO_VALID_SCTS 71 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +/* OCSP status errors */ +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ + +/* Certificate verify flags */ + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */ +# endif +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check self-signed CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.1.0. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +/* Do not check certificate/CRL validity against current time */ +# define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +int X509_OBJECT_up_ref_count(X509_OBJECT *a); +X509_OBJECT *X509_OBJECT_new(void); +void X509_OBJECT_free(X509_OBJECT *a); +X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); +X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a); +int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); +int X509_STORE_lock(X509_STORE *ctx); +int X509_STORE_unlock(X509_STORE *ctx); +int X509_STORE_up_ref(X509_STORE *v); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx),(func)) +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_fn verify); +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); +void X509_STORE_set_verify_cb(X509_STORE *ctx, + X509_STORE_CTX_verify_cb verify_cb); +# define X509_STORE_set_verify_cb_func(ctx,func) \ + X509_STORE_set_verify_cb((ctx),(func)) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx); +void X509_STORE_set_get_issuer(X509_STORE *ctx, + X509_STORE_CTX_get_issuer_fn get_issuer); +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx); +void X509_STORE_set_check_issued(X509_STORE *ctx, + X509_STORE_CTX_check_issued_fn check_issued); +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx); +void X509_STORE_set_check_revocation(X509_STORE *ctx, + X509_STORE_CTX_check_revocation_fn check_revocation); +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx); +void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl); +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx); +void X509_STORE_set_check_crl(X509_STORE *ctx, + X509_STORE_CTX_check_crl_fn check_crl); +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx); +void X509_STORE_set_cert_crl(X509_STORE *ctx, + X509_STORE_CTX_cert_crl_fn cert_crl); +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx); +void X509_STORE_set_check_policy(X509_STORE *ctx, + X509_STORE_CTX_check_policy_fn check_policy); +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx); +void X509_STORE_set_lookup_certs(X509_STORE *ctx, + X509_STORE_CTX_lookup_certs_fn lookup_certs); +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx); +void X509_STORE_set_lookup_crls(X509_STORE *ctx, + X509_STORE_CTX_lookup_crls_fn lookup_crls); +#define X509_STORE_set_lookup_crls_cb(ctx, func) \ + X509_STORE_set_lookup_crls((ctx), (func)) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx); +void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn cleanup); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx); + +#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) +int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); +void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_cb verify); +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx); +X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define X509_STORE_CTX_get_chain X509_STORE_CTX_get0_chain +# define X509_STORE_CTX_set_chain X509_STORE_CTX_set0_untrusted +# define X509_STORE_CTX_trusted_stack X509_STORE_CTX_set0_trusted_stack +# define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject +# define X509_STORE_get1_certs X509_STORE_CTX_get1_certs +# define X509_STORE_get1_crls X509_STORE_CTX_get1_crls +/* the following macro is misspelled; use X509_STORE_get1_certs instead */ +# define X509_STORE_get1_cert X509_STORE_CTX_get1_certs +/* the following macro is misspelled; use X509_STORE_get1_crls instead */ +# define X509_STORE_get1_crl X509_STORE_CTX_get1_crls +#endif + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + ASN1_INTEGER *serial, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_fingerprint_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const unsigned char* bytes, + int len, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_alias_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const char *str, + int len, + X509_OBJECT *ret); + +X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name); +void X509_LOOKUP_meth_free(X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_new_item(X509_LOOKUP_METHOD *method, + int (*new_item) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_new_item(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_free(X509_LOOKUP_METHOD *method, + void (*free_fn) (X509_LOOKUP *ctx)); +void (*X509_LOOKUP_meth_get_free(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_init(X509_LOOKUP_METHOD *method, + int (*init) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_init(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_shutdown(X509_LOOKUP_METHOD *method, + int (*shutdown) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_shutdown(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_ctrl(X509_LOOKUP_METHOD *method, + X509_LOOKUP_ctrl_fn ctrl_fn); +X509_LOOKUP_ctrl_fn X509_LOOKUP_meth_get_ctrl(const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_subject(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_subject_fn fn); +X509_LOOKUP_get_by_subject_fn X509_LOOKUP_meth_get_get_by_subject( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_issuer_serial(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_issuer_serial_fn fn); +X509_LOOKUP_get_by_issuer_serial_fn X509_LOOKUP_meth_get_get_by_issuer_serial( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_fingerprint(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_fingerprint_fn fn); +X509_LOOKUP_get_by_fingerprint_fn X509_LOOKUP_meth_get_get_by_fingerprint( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_alias(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_alias_fn fn); +X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( + const X509_LOOKUP_METHOD *method); + + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + X509_NAME *name); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, ASN1_INTEGER *serial, + X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const char *str, int len, X509_OBJECT *ret); +int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data); +void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); +X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane); +#define DANE_FLAG_NO_DANE_EE_NAMECHECKS (1L << 0) + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); +time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, + uint32_t flags); +uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +/* Non positive return values are errors */ +#define X509_PCY_TREE_FAILURE -2 /* Failure to satisfy explicit policy */ +#define X509_PCY_TREE_INVALID -1 /* Inconsistent or invalid extensions */ +#define X509_PCY_TREE_INTERNAL 0 /* Internal error, most likely malloc */ + +/* + * Positive return values form a bit mask, all but the first are internal to + * the library and don't appear in results from X509_policy_check(). + */ +#define X509_PCY_TREE_VALID 1 /* The policy tree is valid */ +#define X509_PCY_TREE_EMPTY 2 /* The policy tree is empty */ +#define X509_PCY_TREE_EXPLICIT 4 /* Explicit policy required */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509err.h new file mode 100644 index 00000000..02738531 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509err.h @@ -0,0 +1,130 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509ERR_H +# define HEADER_X509ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509_strings(void); + +/* + * X509 function codes. + */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BUILD_CHAIN 106 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_NAME_CONSTRAINTS 149 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DANE_I2D 107 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_I2D_X509_AUX 151 +# define X509_F_LOOKUP_CERTS_SK 152 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_NEW_DIR 153 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_DIFF 105 +# define X509_F_X509_CRL_METHOD_NEW 154 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_LOOKUP_METH_NEW 160 +# define X509_F_X509_LOOKUP_NEW 155 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_CANON 156 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_OBJECT_NEW 150 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_DECODE 148 +# define X509_F_X509_PUBKEY_GET0 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_ADD_LOOKUP 157 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_STORE_NEW 158 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 +# define X509_F_X509_VERIFY_PARAM_NEW 159 + +/* + * X509 reason codes. + */ +# define X509_R_AKID_MISMATCH 110 +# define X509_R_BAD_SELECTOR 133 +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_CRL_ALREADY_DELTA 127 +# define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_IDP_MISMATCH 128 +# define X509_R_INVALID_ATTRIBUTES 138 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_ISSUER_MISMATCH 129 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NEWER_CRL_NOT_NEWER 132 +# define X509_R_NO_CERTIFICATE_FOUND 135 +# define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_NO_CRL_FOUND 137 +# define X509_R_NO_CRL_NUMBER 130 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3.h new file mode 100644 index 00000000..6c6eca38 --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3.h @@ -0,0 +1,937 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, const char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 +# define X509V3_CTX_REPLACE 0x2 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; + +DEFINE_STACK_OF(GENERAL_NAME) +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; +DEFINE_STACK_OF(GENERAL_NAMES) + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DEFINE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DEFINE_STACK_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DEFINE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DEFINE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DEFINE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, \ + "section:", (val)->section, \ + ",name:", (val)->name, ",value:", (val)->value) + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +/* EXFLAG_SET is set to indicate that some values have been precomputed */ +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +/* Self signed */ +# define EXFLAG_SS 0x2000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DEFINE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, const char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); +char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); +int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *name, const char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* The new declarations are in crypto.h, but the old ones were here. */ +# define hex_to_string OPENSSL_buf2hexstr +# define string_to_hex OPENSSL_hexstr2buf +#endif + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +#ifndef OPENSSL_NO_STDIO +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); +#endif +int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +void X509_set_proxy_flag(X509 *x); +void X509_set_proxy_pathlen(X509 *x, long l); +long X509_get_proxy_pathlen(X509 *x); + +uint32_t X509_get_extension_flags(X509 *x); +uint32_t X509_get_key_usage(X509 *x); +uint32_t X509_get_extended_key_usage(X509 *x); +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x); +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x); +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x); +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x); + +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(const char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg); +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(const X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* Never check the subject CN */ +# define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +#ifndef OPENSSL_NO_RFC3779 +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DEFINE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DEFINE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DEFINE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); +int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int X509v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int X509v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int X509v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned X509v3_addr_get_afi(const IPAddressFamily *f); +int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int X509v3_asid_is_canonical(ASIdentifiers *asid); +int X509v3_addr_is_canonical(IPAddrBlocks *addr); +int X509v3_asid_canonize(ASIdentifiers *asid); +int X509v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int X509v3_asid_inherits(ASIdentifiers *asid); +int X509v3_addr_inherits(IPAddrBlocks *addr); +int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int X509v3_asid_validate_path(X509_STORE_CTX *); +int X509v3_addr_validate_path(X509_STORE_CTX *); +int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, + int allow_inheritance); +int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +#endif /* OPENSSL_NO_RFC3779 */ + +DEFINE_STACK_OF(ASN1_STRING) + +/* + * Admission Syntax + */ +typedef struct NamingAuthority_st NAMING_AUTHORITY; +typedef struct ProfessionInfo_st PROFESSION_INFO; +typedef struct Admissions_st ADMISSIONS; +typedef struct AdmissionSyntax_st ADMISSION_SYNTAX; +DECLARE_ASN1_FUNCTIONS(NAMING_AUTHORITY) +DECLARE_ASN1_FUNCTIONS(PROFESSION_INFO) +DECLARE_ASN1_FUNCTIONS(ADMISSIONS) +DECLARE_ASN1_FUNCTIONS(ADMISSION_SYNTAX) +DEFINE_STACK_OF(ADMISSIONS) +DEFINE_STACK_OF(PROFESSION_INFO) +typedef STACK_OF(PROFESSION_INFO) PROFESSION_INFOS; + +const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId( + const NAMING_AUTHORITY *n); +const ASN1_IA5STRING *NAMING_AUTHORITY_get0_authorityURL( + const NAMING_AUTHORITY *n); +const ASN1_STRING *NAMING_AUTHORITY_get0_authorityText( + const NAMING_AUTHORITY *n); +void NAMING_AUTHORITY_set0_authorityId(NAMING_AUTHORITY *n, + ASN1_OBJECT* namingAuthorityId); +void NAMING_AUTHORITY_set0_authorityURL(NAMING_AUTHORITY *n, + ASN1_IA5STRING* namingAuthorityUrl); +void NAMING_AUTHORITY_set0_authorityText(NAMING_AUTHORITY *n, + ASN1_STRING* namingAuthorityText); + +const GENERAL_NAME *ADMISSION_SYNTAX_get0_admissionAuthority( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_admissionAuthority( + ADMISSION_SYNTAX *as, GENERAL_NAME *aa); +const STACK_OF(ADMISSIONS) *ADMISSION_SYNTAX_get0_contentsOfAdmissions( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_contentsOfAdmissions( + ADMISSION_SYNTAX *as, STACK_OF(ADMISSIONS) *a); +const GENERAL_NAME *ADMISSIONS_get0_admissionAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_admissionAuthority(ADMISSIONS *a, GENERAL_NAME *aa); +const NAMING_AUTHORITY *ADMISSIONS_get0_namingAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_namingAuthority(ADMISSIONS *a, NAMING_AUTHORITY *na); +const PROFESSION_INFOS *ADMISSIONS_get0_professionInfos(const ADMISSIONS *a); +void ADMISSIONS_set0_professionInfos(ADMISSIONS *a, PROFESSION_INFOS *pi); +const ASN1_OCTET_STRING *PROFESSION_INFO_get0_addProfessionInfo( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_addProfessionInfo( + PROFESSION_INFO *pi, ASN1_OCTET_STRING *aos); +const NAMING_AUTHORITY *PROFESSION_INFO_get0_namingAuthority( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_namingAuthority( + PROFESSION_INFO *pi, NAMING_AUTHORITY *na); +const STACK_OF(ASN1_STRING) *PROFESSION_INFO_get0_professionItems( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionItems( + PROFESSION_INFO *pi, STACK_OF(ASN1_STRING) *as); +const STACK_OF(ASN1_OBJECT) *PROFESSION_INFO_get0_professionOIDs( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionOIDs( + PROFESSION_INFO *pi, STACK_OF(ASN1_OBJECT) *po); +const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_registrationNumber( + PROFESSION_INFO *pi, ASN1_PRINTABLESTRING *rn); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3err.h b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3err.h new file mode 100644 index 00000000..5f25442f --- /dev/null +++ b/Hin2n/src/main/jniLibs/armeabi-v7a/include/openssl/x509v3err.h @@ -0,0 +1,162 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3ERR_H +# define HEADER_X509V3ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509V3_strings(void); + +/* + * X509V3 function codes. + */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ADDR_VALIDATE_PATH_INTERNAL 166 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_BIGNUM_TO_STRING 167 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_LEVEL_ADD_NODE 168 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_CACHE_CREATE 169 +# define X509V3_F_POLICY_CACHE_NEW 170 +# define X509V3_F_POLICY_DATA_NEW 171 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_TREE_INIT 172 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V2I_TLS_FEATURE 165 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* + * X509V3 reason codes. + */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#endif diff --git a/Hin2n/src/main/jniLibs/armeabi-v7a/libcrypto.so b/Hin2n/src/main/jniLibs/armeabi-v7a/libcrypto.so new file mode 100644 index 0000000000000000000000000000000000000000..56aa5d215fbd10a2db6221c6ad05de04ebd560fd GIT binary patch literal 2698244 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%0D0hM_ri^LSS#8Q7jrEzUDJP{gQx0k1yKTU> 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%0De%a2WQ3~T8#YVKKTu(3&^@yo#ZqP?F0Bu03Z3j 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

2;Z$#=OOybo&aA&D{aXRLsUC@LJLG#3 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

pBRhSc$~sxO?pQoElQ9CRJuEgF+N;_L ze4I+J`3?Jel3}G6_<0)uQdV9kA~*EDQa01vnltr84pR&Eo3OSKGF~m$^c=(~o>0(WvHy&SmSBI1yYLoiruF@H4wC$&Ctnv5=o6?KM1pae@*$c`3-J zKB7)g1C)A{w<}?lJziiOXi`o zL{yPa>x1kBbA_>}L~^HhuMFT)Wd!Fc?hGJvS1*mrYvPl!ZmcF8>OEqe{V)QAndpi=ZI(PAp8;z2J`&X#>;n{Sf40P}n)U%#>h-RgZFs{me zD>9;q>3&%u)tSc-sBe{xgtX6L=UfT%yzBN1gc^+#_(>w`303b_5+TcBhrjPbTY{*< zqF$|3n#`4=0R^(VCaC>uW|f=^dm}Rc-E0^hcL6+ts+TAalcj8h<&;3+qXAb|LqOfB zuOWF5i~mbeYEtB#N|d(wKD!mJEAAxAz~-s2@bJ?c5H_l%Tj`XWS&-p6Q9rl6;XB z|GoY0_$k-<=uzj$A;lo%xTf3t31u8Ro;gI%^}>7e6n$y((3fNJr-4@c-%W#6Pu@^{ z{;M^F#215pWo?BfX2A5N9B#TY`aydu zWSCft&M)&;@MrIHdBnm8*M%K*I35*(o%7u~a-$;-N*X$s$no)5T_3J($OGVe5A|;~ zL5A)~x&<4K3tvSrH z?2yd8e6?2~G%ozk|Kr)LxMFKXA~fHQOYwjxjStm3VLp+ev4tmih`hwHp}tSU{U5n7 zF)zWLqqZreV1jd#bn2I9@}rkfFQ0oO7`C+T6`-UC8tJxUeuzL!%Q5&z=67xGdlKZHod-s#6$?DR$1Ua7B~0pJ+!(T*u$up)Un{FpeH+80 zL62G~y~I{jLoHzk?a_fn+hGsd>ZTs~oWP94j>pP4;zi!v#m2Bh7mKl2(GZTM7dM5< zVP{;>aw2QfJ5#*-;U1(L)5D5T13C3J-%&0FN~qhBhpzrVTs2<#k3*i4HjyWg=zPq? zoD;iYKnm?I>C^m17*Euf0 zH~XzuY=Rob*9Vw$h#6FI?sbc9*&&PK4L%fZpux zQCbdPw>R3Qlq+p>w`?MnI;vc6iID8GF#tCx7`vDw{5~Okszg+K=Aai??-4&pxTqCM zlBqf3rZ@wp(|La^8bNYVg#S zbMcd-Et|BIQ4DU5@Ls=|zX%W5Y-LWhN9%kWbKvGI1JWuo|EB|OI7e1XB?~!ohfAdr zd3p1QH{wsYzi+t(9-Qf`lp&K>4UY1^KHP zRnCBrWl25ZR4f|X^QtfF^$;J7HAZN$Oj76RSa>u2#uE-{uJjs;caO}Nbci5?TZ2@o z?!pg>MzP2H{qiiY`f@aSc~B6>1pNvgO11UpO_+dP3xOlUZokOQHI`af?C)xgNZLrd zkIWy2|9U6y=C{WxM~!Ss#tJfL9WR4DMnOg#b$cm^qGg*?J=u_h&Z`HzMq#m3y~&vO zmUaW&9~<&q2i+u;avqei6bnFi-aS7Y@Q z8W4NeSltWr7UyCtGLjB(Z+CPJ|H6$sKPf1Wh`0hCKx^(-rT8Y64S`na1*7oCE*I`_D)uU7u>v-FIfYd^uuP-kd+T&a#G1`v_hF-1DG@MswU@jvhu9Lc9hr??R}9*)pHUjM#+1Y9T5=3G zcD6hK0%@&|W{X@CNVlHFe&96+(gd6}m5Wt}12Q)25r|ZcK8Qxb{v@PJk{Lv7$!Rho zm0Q|aqyRI6Eue>?zSLI;Rs?W-O!=ce?qwr67TyHqVa{QRv2t>dQDPx&Z+GR%vJCK znMCQtbTcZ>Q}a)c9A`Nz4o2ch22#JoKa+$;3Y*IvrDmKyJ<*cd;t^Ykdc-rjsTut| z_NsKtrPS9g4wi2?AOVi`uAOM;129v)h zLW|>#OgjZ)WFfKs&Ir;YX%TcWI*pLYSdJ@ zJk?Gd5)T=Ymmy_?Ga!-n00ZnvyGb8KgbyBctH}od1aRrSVX>0#XPRD++~=7#&{!4a6`~zs7&%{T$G*@b z9zn>ej=#9ukc?ml9_ei4-t2QUlvJc^NzaG1h?wRq&bM}@De);##hw%7VQN&eCi?nH zK|2cdnqa&99$g`Rkx|xOlKCNks5QX5dh2zxqtlJA2UBG>5&5=hDIQ&qS6%Hw`PKHr z9x2301myd_n@W4#S5f}N(b?&blz6;c>$bd6u!4t2wDx!XyF zcao;%BtuONXOsac)-LYZE|(4K0jA2 z{6raKi|Lxe^7bt-3=hM@{=(6`;J>fyKx8Q5**tzEl#l3CizaK~PDEOLdlEJ*60Ih@ zr=u$+x!&evEvtVOB2gwB6&Q=;lpn>j{Z&gF8ZilI>ed(d2W9J)drYz-3vL16@ zwXTEaR13vxw#0K{8owH4qFy>h*}7Zr_Y(|!XrY*Kw>f;gY1`DSKZ0YMaV0tib6|19 zFw>R-OGdraZpJCh(BTVaV(KZ!&o!PeAE5kJ- zIWRx1sSlI5$n6C33!1Uf$(}$@aUo+W1twFYKSSjBd@rL~ZoxpPO}qoH={B}E++Xjo zH8bBcaj$^#Y1y^>|I%A(>)hZbLpXaRvUyWdSHvG}$x!lRoxvhs5rR0|)3hBBa-K~C zFuGppj3E-{I@U}Wq$kPsP`$qJhS&gB@DPFQ>-<|Oi2rk7YxRr^Fa%SDVGR8Lk0H{b z%lD8|JM{1@eYS+>Oo-}F-~SI?57RAAe%#R_aSg7h&jow@{)a%N=>0$2F90FAZ~`or zB(F8%hs#jUe)_LDf(+HBKb&`97QaHwm(dvwicpw+8GAq+BHmDtGMYUHHNZ$r3eAzL z_wxpKfR=k%Gv>dOxLMFTAI#?+)U{ad=au?(+c$KueNFD~AQR<+2aerWbu(7PfUpLi zYjQEqtY4NB>-03XYgO-6CQjRIFJvi^JZ&k`l)WsOxtDhCef_eH6i*3(vuHkfC{|EE zhD?=gt@g!3CF;E5x_21Hf@O0!ke$g_&7yqMCRs$;d9K}W>D(4`x&?|rpXbjhq~A$@ z9dpNvjjgpk8)UJMcm}?zEC_SQEZo>XpBvKQPo0Ojsod|pF`xH@3Fo}*D$6@MFydRh z&8XW(fb6OUj@WE9Wm34q`Il%0Ek2QPL~a355Ls)C4nV zavVe{&Y0lGI-Weav?=db?u?Io=HWwbMGoCg5lbj(-njZQzQ#`xndRf+9|OKhtzc-# z6M#;(z{SUxTni3lLwInNk&ZTNtyjk$oK(q)@Dtt&zQCz9cM1W2m{Ed~6yTZ&qYP|k z@&&4?PR={Awv2*Z5%T5N+B#*R}z9I^TC$S&!I(hF8JS`{$-0ZhXJaV1I;+o)u^JO@7`(*>7I zlES3uZ2O>{i%rWqmgfWyNQW%lQS(NAVTr!Du%4X6H&y0Ocz&>1Ldv>IvQWJiXqiH^ zi(oxeK^GA@LR~@Z!c&5LGRe_2N!U**A?ufzOzR=eP}Wn~@opyiSoe}kZ;YsK%5g87oXfoQJI1w@ z>n>>I9cvh?h_IGXjJ`o*)|w$;=q5L_5Ozi}kg%T@s}GaR5_s+x9N5Qp3R<*_v1bw9 zNEC`H$8koK6)8lXH3Ja$QHrXZN}5E~$2Xm{twGS*(i-`b?kF;43!D<;t)GJHKLh7# zSc5;lpC{AS;zhrZ;u2vCSJwt|IV?V9vh?>G%OOvD^?G|>If~z6^q(9lcoG%$d zyt7Y4^PbS>$$l}ayi2-s;lsaOqS&{#{0cI;|A4kCi|T=(>mHtI-M+z!UHfJsm|Snz zw9kqfOWvX&=vrFt6bZ{?929+zV}M8k+>0tHth`n1G3mTki^Kankci!NG^K7)yczhp_Q>OFpfYQL$vP z16$G%drs5{`2Fhe#}-3|rrXVR&Z+&Vd{OtMDQ^w#W{<|ro<9I2AH>=NJqA%6v9ua)ejJMIU{r~r!r{h)g$Q1yafdwtW`z(LN52pU=4QMT@I-8hThLPG{te z+UQWoIWVh=;RvbYy^XztJiKg@?eVG8Q1U5@IYzGtegI@Is2Hn$2h(FJ)6={8-7D;H zH5!y_hvXUxL`Ddv&KvjFAcq>3Y`))fJISw!94|-d*aM~mY;&n)AU5i6=azf{hp-{K zwCx{(WtTSEXnx@8~vZ)uXEE%dxBKc0ZM_?DKXhrf1_@XEHM}|R^ zKa#@&tAHyGJkS$a2>cT>QoAi{BBG0*e2zdhq{l_K_z)tM#Yn+WO-eT5>>daAXk*J0 z18`%poAY1+Zev_cEL>bzi@R>oY26wA`_|lOmz+io-A%nxCUVx9851EEBpjXmSE>@wMA zu*Y=~s;jqz9a~Q&TvP44Z3Z6_U%=~CKG0iD2ls>$yvWq_Y1?s%09f^e|HHf!ZeOg{ zavLqXC;g4gS$Vl*=nC_Hq@PSRn%w^pLh~Gk&?0_;c?6SO@~hvs9fZB!`_gqoxEW)Y z{tl6yI8eoU)=|{_jqKIp2hJe_0-<4z@%10Gub&gxfztQs;$lh492EyS<^k+%eLL|| z+VYoG?{A2L4(9YeGxlL^@4u*;kuS5-J*s+6fZ+tb$N0m^*rEYlFs^MmQed42)uM** zhyd&u5iMzksakW|PE6al02&+sSGwtb8yUm3c2fb4Dl zufaOPJrq2k#dq|UR#A(5e&r)wMjI|Dz<_INg>28NDD#6YLT~e4U7~xsToSO_pzGhQ z9ZXcutpaGx{#;vSZKcf9?J{(1Sc5vjalf^qy%6O_#Q=h_>u+=U5+mf=|D(j5@yrey zdJtldrLr|qXSJ2SOo3DU-6tlOLILauk+|@$S5$LSkKW4d8_JEB9^B{pXsSWObJkZMi(;1y8r5yi0uIc*{18vW|UnkBQxxg`q zZZ5AiU+~V7_;1!{9L8MkS*q5Is1xS*;({-N9!w3ZKHE*jkTT@(bitAv-SemRYXO~& zcs*K1bQY6D%Dyq`v}Mia-Bz7rNbvI&k!&aV_dA~iZA~5Ve9?gh?*vDfT_N<~pcAhh zu+>Fml17>Tw7)h1EhB2gYd?_?1Fvp*hT9e1`VDae77{U=X}RF%PW=wmaiGW7M%&uG z&D?k8ah;*`0uaV0c21@>=APQV*uWtb)XddO-#En;OZrZO^e5Yju?`=}JRCMPREt#j zF&+*aPDCk?ttf@GaxEK+CNH+a6b^yVHz`~X+#zBRdh4TZ)LXO@F4m9PR}Gu}9%i?0 ztcbaFU}A%Emc}mJ{)p}enqnE=@umCB+e+&eU^GVj@@?+?pgOS;1B}%bN+zsfF&lvwi9oZ?aGlTw(=5V`rNUG+%QKuyV z&xpi}{IPKX$NbioW9}^k9e^azfCJeWmh5Vn?QWXjLRy{d?M6Jc@YaZui8x=@y8SXS zf$8y9iKAAg0{~#*s9D>-aye`WO(s{S_7i9R8 z741)Hrtd90ReIrP(F%#+Edn)H$eK&UMyFQ;iG4qCM*{}gfgg>2Hk1*W zqDnf-2XaO?`~qF{m&%UD#ADiAiNkEM8uco?F5}HF;*l2llnxu_0drv<&t4&L%Ug%R zMmbrgbb^1PY)VjHy&M{4fB{4q&&}^WUK??OPm95zns@H32Ha|(G*G1A+C8B6nz+?j z;C}@K)iR7p^$HG|gY`!%e0yaj0>p^BYEOwVV8Ta>BK%6;v$^fK-`CX%n9N_Vy8^>v zV(ytj8@^kpTtEYcDJcdEQ${HRI}v2@3Cd|{`pktR6dV0zx%F$iDxGd*8sRrN)P+E! z`2_5qJ9L+%WQs_#V!<5kXKy2}4`eRolD4&RB*0*r5F=|!BIydM31T_mK<*PK6m#o! zdrIL#WjC&X2qyVcm{{HQ?It%jg|uX=o)ux!R4ogf^c6qIW#TL5QAYV)!X`tZg zytrHtN($3boGu$|_d|nksmuWF7EHq=d0A-t`S!510m9w)$akpt1BceCD@&6rp7rwA*KRv4}jvUJmLq7024-nnd1VkUN(VTWzJ9FB^;3 z-E-u_8C_`44&-U2>riib|B=R(gXnT<0ZA**kCPtnF&B@hD_=`_i{)&$Vbz}C)Fs1{ zF^^_!NHAse*WP6Ay}hk6{PWm+g?uDHw$$KDz^lybcYL=qJdgyhg{riwkY_2`g=#eP z#B98@hE#*qUh~}=R$isp2EeB$)D2q*^t2WEv{oE|n90rXI2gW}?0yVA!I&nUP~-s5 z4-0pOF;zIEF;G!th=Bz%nK;p6Adc`UG4*-79uK-vl&MtBL(b(aDWy>(mt8jhQCw!X zVjExAFBu2_3jFqNwf(7*K-1=#6>lDqtshMs;@QsuaqJqSx=29%7_lTP(l@nq-G25M zw0jPHWk!4BQ3I~w&~(Ph+75Yd^!ZMN zp#Jc$G2ElnAxbhGR3$sek7&)A&UQIM*vj%oa{f}nkb~`@Z5#Em39c(NPt$lAf31yB zCY&~-wLJ@_hh?DKh#>#A{l&csD9D^be8dI@178 zOaG4^kDqnr>YcgmkEttgsLKe2(~n)pNoLHbZM^}L)#i0BB?noCKSYZQwK&zi&q#{* zan@@tlRXQ-b?&HLoIR!6#f_}m^vz!+{)QApWj~33(_u)kL+~Enyth#g{4(+c;!DfB zV|`niv5{Aa-0j|xE!{%MJh0cLyr(l1GOzdPCDIyX_ZzDYyimM_MBt|JN-{4nCrD5H ziduN*7FEy66{x79@0u0@^sq$z#8ClH9i0hcLg|Ybq-F1m{&Am6M@T_)TntiudAyS< zs)3myrJk(KS5Z*B$(FC*8jtQa1t2o$QIv8LqZcKA3O>vt&jqq8sx|@N)K1|7Lr$zv zWX&(asj%|$Oy3r!RQJCcY3rd{$InJB!a9FS6e1NyMlHdZ_Y3nU{CH;t*x>fKwhP-$ zYkr%*Toso|pKlRtZXF(FTe)D5qp6t}lDK6h#P8~+z*nhEc;nXc8JvcmMLzu@Oe$7< zBl04lf!pT#g&8{?VY4B%WE}@)(&e16cAd!rYK_%|)u()LWJcEi$Dc3l!CK2!5;2|s zW}5g=##H@{NivMxjJ_~=uNu`T9Rr6FV0z5v=uRPBqXzrm_A%BFKI|iD$9wj8rqPN> z+1xcB)YbCgq7#bj5~uN9vcqd~)ap+m|7cNB+1D>9*WbJ~Pf32~A%fQoeDsEfV$Jm< zcfk~j#43Vx4v>@8TEJJ68sQuh7jnahn_00r@Jk$z&Mx4ZMb`N#qxP# z++Z-1pj6(m?^i6gEO;UiyZ%derCRN~ z_?MO-sf>8FxmC%pxuG8uQu({8m;qO&h^k!hVp~4pU-X!ji;qaw)r-O%MSbD}W`z8` zj+LKSnR`sO<>L7+l32>AB%FLk-|Dn(4yBwFza?8aO0O}h(JbZ$J;Y$g%}I^nP*vn| zXzfF|g`>mq_0iAESF8jUBINu^6JS3Hr1G0I>kJTA!#@?Z8)~zCHv&u#Z;MS`SAD+# zigdJ0Uyvtu35*y&COQcQ-HZPYq^|D_f%5Yo;4?Ef#>4v*-JuqQfXg@Mmu(@ZaTzNu zF!hNoBbfYPWJ)GwO79X`qm0?T+_z`RjZtz|YUNp?Q%|;2|FF~se|aPM%fFhF-iR|; zaHq@%u|&C<9}T(57~DQkBKuB;4Z!Dr#-UOTjW_16;}gE7`B^y+7iP|}eSaAm_%J%9 zaxRK#MqWfUP*vR3F!_|`UrKVq zcUfqYNw~VSXV@p&YL|;Qe(70>$6nbo;;PZ1=nL23i-}h<+oOfL`Mgq+AP{C$f#FF%;fyW|JLgHXU|JwE#7=?lmfCZWE3}58 zT+N`z^9BtnT0xfeKpP4=w>aUu<3jmT<(T3Z)UXM2b-@4_52p)Q!FXH@1=#z={aj|g zRA|u_RQtu3*8_q_yGQDti;xGh(gqZH>$c$#RjCu|WqQ!%W?kod5MO*HeNK0?83M6I z92!w1a@48=3^yuxfd$HQxwY8!B`Yvl0A{^xIHJS*LxpXt%Gh(LcG_+L8PK^Nn=|BB zX!N)>MCNqTGi0GbrdsxnDYd2{j>HTM7J&%w3PA`o$KlwhXtDE}da97XcQSBLT$21a zF|R(@*h`R^#24PCwJE@YMIZ|2HPvU zi=}cL1jTO)zV1u!cA+ z$agHYwOrY|>3y=dYtbCj&}LC%jPnz%&+CE`8g2D;W};OvWF2TmP+F7m!V_qfRZ-wp zI+lix`(HaBNt`|9@{B*$Z5PKFSsIFRsIxiR#QMd`-$+Q&(z+B~C_7BE%Z(e6Mr$o0 zA(@zM%xjL39YVr#8phJE?GXPSrLGph1>ZN~9xfFj3^Q;2?LU6kY5R70W$D?C_P}iS z6@LWRam=cPb0hJ{V$hBOHUCdf6Xq!K!FmM1dv&ZFRkVBnx!@FMw#8{;3+A;(hHnYq zge<5qiCZK``a>ku2lu+G8~tFdiCujS@F;>wPF~72ebPKv#1r|noOl6%|~hZ_u8rd;o?K%Y4Ikk#zOKk zLi>E8l*X#r1u4coMMND^en>}?Gzg%R!d{yq!78f$q9y>SyUBJ@wBNP+hi@>(%(5e2*hFIWWlfbO*#t&*9rXp9=j*o>t_iqXz~UyHIsA zNV%a-V`bCyK*KFknyprU|FA|Rp?F`msB$Q?Y+-Jo{LAS62Pl^u+IGj7F903#7rsb8 z)5pGviQ$%Y9`5;gXTK62;uOEs{Yk37#<)*}&0Rc2v#=CzEpIjYV1Hyl$ljhFVNTsv9 zvgEA!NxL*F#7zd|)(hQLHs-Hn>V)#8XyZ;ycSdX%ZU~u{8?{6`lr0a%a+#ky`dgt4zEtctQ=z8ebI1tKL@zI8`g&x|g!!(Rr0WjT25G21UO*5#|s{m z5I461l)T>Cv*RAs;;8LL=+ugAlTNpDrXYsWf-iW0G(>rXE>zGks0Iwrc(m8z$!_~M zM~~&7_{vzEwu`>>I{tO+8zTLak_QRR<}c<^4;e$8YBD%|@CZb>5yaikldM0b1@3Gdzryu?qz|vW2U!N1_9^yV~{0z79?Jgyj3wR77&+Fju3t zM~~Ao!h;7-7a)kC3$yP_Ct%>6?84u#E_AM>D_N9vzEt%XV%g#~?l&&qNcey<%khJF z184@yI9pY>XaOthD7 zbz#7#lBhVD2mum;cYq+BVn&kPIZe;Nias!!`Y7nw_y-NEOwv`@b{s_zvB~nDV_cnFEei!Gv9=*CFyl`#be&bs+l)duA0!F}AjP z$>#Oe3KX+w3NjP5=2pF>B;uocJpm)_2nn^@e5p$#+oB~5#-t6q8eJPg3x;yT%3Bl! zqt^lF7kJQA-qdzI;e94Pv~fa&HduHfGA0hlnFZrYrdk>X3W!HhT&Qwz3}RpN9s*Dx z##~S^A5L020?Eohr1542^BLu;+jUXFxRm-Wwu?gCnxhlzm5uOahsmKswElMV$h#Sq zgq<&v=pvf%)%3)T8CfB}75%2f-gj88le7OsNp3fk1k#r2fY{@c*tCCN&*hy_lB`{y zBRW3cmS~zrn;Hg0RKzYB4^ZxN+Btsg%N;rQpS<90Nmlr$Byg+Y!-AO#O=LkgtCDu> zYAU6xb=Tu+a!M;#0>{49HO}Ae@y6z9w|1E#u({zFk(xExIvK}z@-40eF1Iz8rN);| zUB0O`D^nV4PN=3LNGyRRtT2gtvp6(D3#DHI=PlE!r)QE|MC<)=!p{N%~&so`$|x3P2X>1oMe+piM9<8 zKNFprHSxgb@SEs4(=xInXLsAY4Hc^5b^}Ijt$t$$iW>Bht zxvyOUoOj>A$Kt&DoB$U}p_#kxH7n*`_D1|mL%BMhnK&C|pu zj81jrV72MRx3M~eXh1$T8=7QLMQ_Gfa7G%+_JIPZ7fq54u811FQou5?EiDq9Df*^x zU*`+eU8PB$o?BJC&RewaKjeH+?^yNz%=XanIt%hX9L^$sh#ZfaX?Cgb7^rrC45s~O zL&rmBm~J=Jf+=FA&ntZH6iqD}{Kl_a>WZkEJF9(m6;SAvG00tA8E6Ofuqj`8PYo-& z9n$iHP>Bnc7T$aW>YR0#e%CDSf_%RVaRph|5pa${Vv#sHX+J&Qjsptn`|39ET(;ku zW}ak2ueXEI?|inKK-dos3#ZVS%8onjx1|}%XE28s4#eTAZrf+Q_3aR7u|spJnHqx) z8d{6U|LNcy722?wkj@|d7t;EVI_MkImMRUYO>K8m=#R&1v^#AKjx}cqZbLRwJ`VOz z7C=RRt2y!``%da^&!D#KZIc^spVrRJ9*|spVZ^QivU;*5S*!}n#wenkdrJjcBUQ+n za^^dcqMH&NA4`Qoopbq6J`%)HwBafU{Q1aQQ+dqMBuv5f=MbId&dkRI_FoIz!DGqqdyN0CuMR#d8v zr61c+q?dZ?hA#cxWFu}wDEqGH!Z?;zF4%rL$i{yl6|JB8Tvheqng@hifjLWX!~HA8 zw?{T~T7{}bl#afCY(@0~PG1%Te)_nnIKV8=9?Yct?g!iPqOzntUuA&O|2K_^0{)z)3izmkKqp3Q88O0JMr4<*ds^V`CtbzEIaU-;FA*kdR(y50!>9IC*r&U5wWWg|WqzlHbfg3h zCIN`Niy$QNoqo^lZ6ZCj4)Y(f-TvJ^^7^3_01(BbkA0z6+ot_{M?0}tJaiV)^i8#dv+0L z^-`=FX&*|Ws!b8##7u6UjuS=;l|WN9Q&@k2Ul-S2Q-<>!aPgIo_SA1xlA<`%Lu`Jc zAzK&`-2+nQ<-o;Gj@sLi&-Zo0GilM$DVpqfrS?=7K0@=vABdFvYg4h+7v`&X zGm6lYbOPXkUcN6)%_R%a2H45@&yM)R;xl07`iW@xx9^?&opuu~ofv%uw5Owrk>GP> ziL}8}eBAP@Ih4me_#BT(H}1h1gcUnBvclmO;``no4y5W?XD#YSgTn zPb+K0i`%=)hBP&xTqzoh&fM2VDxR=SBaYzl2pK%ZKS_iwNs}|Y1sGYOu%-wHQnd3*&NmPIWj~@ z0)=S;t>*l@2cCcKZ3hw|>t{`LkdJv$or+^5t8b5U(~)QuscM9h!qiQu;ZLF-G^3gX z^8Cc-&{D)nQI378bgBrx2=?T`VgD|i7h$#mL>TB^srv#Uy9iw1(+rr!lPVl(^XQ8< zpq(Dt7!(G7bv;6oTDiBtz_7)svS%d1C@IT$j`PtsW6H>y8#tw(4h<$-{x9E8xgm_m z;Gc21!)(~oFXTLDHAQrP%M;pUNB?gH@P~~J9}q_l_MM4sc?5TgZ0miS*JXmJm7uqnT~|Wb}=2f%ZEQ-IqT@2UY4FhWb^L; zA1Z7ZXT9C|Wf2>k*YiEHZ;1EOCI;`wBR@u6@RmTa-L2&Aw!&u^MrXvOem>4}N6N#e zlvd&+1JBSHRWRce0NM|#e;}_rBtv?t)Dl7vp@pPTwC}7Ur1eODU%c`lh$F#f0 znv>Z7JC7f?&h5P3pPp8hWxD5y1G2sTrvmFUnu}XDWEY>(VZSdtX?y%0q=ARSvm1np@|rQ9l5x&R&poIJl}cF_^w6(X=I zQ!)>32u>%$aTFl#unS=CRIV)G9Wbm7I+GO&=M?iAXR$+ty#`aOZC&T%g19*~5QpcG zO`LCot)fGEUBQYuqo&$OT$|wyY5a#6-87oCoCFO?7(O`I0cWv)YqkDZ9Aps?Yr)D^ z;}VRttOLElRK8qrZ{2gFgv|>ZzXhx(5$IpTxoE=aKU$k8%4J?=PEe_Vu@J#5rDDiZ z2c@Bz7JCS!9`sO;vO=X9qBN1ur(Sbw!lO;yd?rRT=3P`$;~v2fHhjs_9?I*0#XJP| zw+YlfXT$bu)L;O~XcsxW%@i{HGo-L@5^G=L6&#usPYZoapou`U4up`i#y+JBfo2q6 zjo`ocoup1_)vOO}DU^>pOYK{3;aFWV8RotF)wd6F4qFt{^9iWx_n0q22aa+lQ;iGi zbU3`PxOQci+NTCLDG9!+=J&R-UvVE@6i446qm+|ko&8ugwl%;6P z<56(H#6h3R1<6q=j#G(0Qfnz>sJPz(u|ZBYLNchpk??70RhhSVPkCF#tH$jWh-;Jz z-RejA4!DUGXgL83Ot%1sJ?`eL}r2A z5~xNM82qkYn)BJYYP*meVSiyPrxG3o?hIz0!pOPc$;7$tI&YUMUd!44(KlY818~7F z75Vp&z9Z*+kW1uR0c9sGOVg-~9W7l*tZP}xc(U%=Zm4JonIa|r!nlK|2)k}%t}eTi zuiWdS5vN^0BJq_c_SUAuRtnG;Lp9Rpq>pSI#7(C=xPJ_w)>eY_7M9J=Z+PsxvfF3R zcnl&Pav_dDg{22O4*Eo}{=Za!LENXu+o}XY4MGDK$XC}0G&l8{kT643TUby|#8y}T z@CAa(E+DYI&;Wg4KiixLej#JLiNDLtHnlcEw47X>rgWrFYRh9$v67$zn}`F|f-w7O zNg%K{P~-xh5eXm~L5B#IA=3|5nPraP4cGsdFpIN}r zb}1VYDVyYdMH94F@(a*zbd!rLQVatsV}w%Tj=-K5Jz!V zx)BjF#3J+(Z^Q3_#e%dOnY$WeYdUaG>@4}-8ZKfd9DyM)2r%~b!EFocG}$_$qQ)0s zg=It5J#nnUuPdHn@(4$7LZ~6FLYScM-`Ls^t@q{mB8f!5hK4Hw(VmaD5M!~-Kx?Cp z3Ap2TJl-~Xw|GyPU7DU5Ew$O4l^>zZVKE$*<;v?OG^Ar(d=Deh;R*Ds_H!?aV(`<9 zMCIw7SaJIGIi+v+1VajVRQso9S07>4+W${7oq%h1?b@%rp6Yi5^GBA^M2^b-u%o6O zjij}VH7N6{t0*4HloAKV>LdAS!xSgXRVNE4WFt5Q*|hfn^8&8OTD>nI)kUTWZyE`= z=Wq6=Z^r{pqjI(U7tbDKi^QV3gAOVYx^dtfpKxyU*+((=ulE|~!RcnCNYo{Z_irULq!)8%h z{1JnmXqDUSbnu2skR)dEVL&cBQ|iG!9BHp#1hu_AL>$IRW%hXeX-Soqp`fXF8ukzA zQj?sPY+h$$Ef^vy%zrP_a)Owyuq&pPK_y2#lEn`!)I$jilyh?_!iuBJjqN~fKp1>7 z9^ppz^;fukhUVotp7#E`pypnoxrj# z+a7GCzO}Qe)hz~1DWkq6Um-$`C#r8*h+$1~pJe<8uj>L{xgY)-XAm{%pI@AfO0y7| zja!_HiVOmaL>j8+6a_t=V*GYVRz|MO4o6r`lrv2uBt%j!823|aBxksYMsUc>V61S3 z-2kCoyOakCwj79Ar-*(Y$sK&49IfP~Hl;P_+9wsfdmf52bW6dZZQp1s1xjb$O(~)1BZYVe5tD;K~{)7N1E+R%Ia%uv0>HA{;W=HqFUNxXQR#zd`ZP!l%vmRwyMary7DX;P{$QNk%K%zI#DF}V6$ScUH)M&NEx7l*HH=CA3PT!MuO3hc z4=uP|V}F%u=Bj>=sJTIqkkG zCYz%s#)p-Ql!W&%lJ%EZENU zXV@LLcWsvRD0(vkmvT4RHP0X@!o=$NnTg=cJ?t#M26&MhRU1*8zV}M_pGK?hT}~-B z^SP&moA;rfD!a1^VYLr=^y1Pi757idsYWFn-1-lm`t`U}dgGWpJB9eOd~iU9DrV75 zgE+z@jxfNUR7`qenpKVw0`D*gT=Q3_zA^->u{u$1&2Pcj(0xxEsU8xNl-EG1nQ#Wn zMy23)zHLaWXHKUM{vT5$yot+jtOcU7Pv4@- zj3ZIg$8wvHaw!bThX2Fao`>X(#;m&gbE(Z;7W@+GFx7o~7N#ugJU&Kz?gQ3(=!hH_ zsR-%SI9XH+uy-4F2~)~A64A9RggI$&Nu5v;#PiC=~3G3)#kxzZcIIr+@Mk7E4Y@n&fhiL(9}ZXl!*x& zwBnEZBVsjH$CNph9-Vb_2aSK9! zQVc$fV}C)@FjI9o{~|BU+15pqN(JOziHS|A>N1xW(_3 z;%G=CqR8aiGx_dw!sel5`Szz1NV-)se% z74N@3HEoSZq%*?kJBj2BvYN(;Qo6?~rTgXH2ED^i=&7AHrOc4cXh~9TnuXLGq87H99dgYf7KIIH$*otc^n@YS7596%w5&pX{&$7oqyMA+%!FIEFQRY z@9Y$Vm>`9Um6ImzyM6v+svx^Sdo>*ZML@d0kMc(58a~NswVY&Kx&Zq2rTH2j=}P4hwFL* zo+dtPxp6LUCLpQ6eC2Fw)WmyKj!Js(`~w0VY8II_5=pv-H+ry*SZ^G4r=aFH1UO$F3;Q?*x#9&9 z5~3*o60Stp4J=xZ`yH5Rg=v|l0*J1RUrk+aY=lQ=M34*>h zpxu#2JG@fz!UUFuwv()xl)nAuQ=fIKINgE3c_qzra$8Nnx~Ukdc2O1Yxgy4KU%`~ zCY$B|q|1gfvpm)1e7j!$JeC?wEqKmMVDtFv*%^tjgTUlM z2wWN*Q}Z5LD3T2_zDk;Kc$2|qf!gOi1;wh|QERVfO&I;nkr z%QacjNYwgjMQdgsxE@7??-V68NKjexb_p`|32$p0xBo`*!ora4WPfS*Jwqq+OxHt+N7V}f8y9STV;F~vk01@C9;G|+T;<3k z)b4pc(Y%8&17v`H+7o`0S7Obs7`Fj#EzM?>Ek&RLact0Vyhv036=UUL*^plnjciR33mT4TLyM z7wUuuoV|tE8&_)HvxcMiZ38~>H?DmGGsS!MWZOQlNZLv4iL`_N;cuFL3fgY$a0^ka zf~>gC7UxH+=*L#kt8;Q(=bpHCr@=>@P8Mj+AtNnp&w19=-*hmz4`AxQId?_euO+?3 zjSEB}!ND$6Dl%;9QQ&>336w8R{wL^T`*F$veaUdxSSK2gdHsXihVP4T!Oxy zM*KNmI4U67sUSup!HWu3G_xC?+eRJa-nFN1Na4L*LfTPeQb=bDZkfJ8; zy2TpYAAx05##e5l12Xj#vfWJ~s=0VicB{VrUB<8NZ~3Y*Aqb>y`*_^#3#_C8JXRq8@M84lXiB8cKC2A=91CzgLYiYPCAqGdO(wrW{H z8FP_jcTQRwg`dT+g~66bX`D82Hlr>YeGyqz>`Y0ahCDqaxO#-jOh0~sl{rEF#B}9} ze%yxA+l#oOyA@=K`2c-Z?2E_+&30_duYS_qXS10WWAbfDed}i=nDHp1vK0K4_En&@ zj3zI}2uW8=AiPMcB=6~~Yj;gMVT5RBa>CE6j;uNCLj$`{GJSnfX)x|j(7B}|-A4wk ztYRSldyJ5gv)GB#>Ve$KF~eobOi&7i_pjq;S5qBMLKiI*fGG(pNJT@rtsl27tNLmi zJbiZ8HXyLmz+T571`MfcvS+Q4N&HQ+6=7leGi;QSSno!HoCH!KCQ4QWu&-}uXF=+wf!3nKvFDGCaX8SJSP@3r2~K8Gi+_p zQ>yP&!D67+I%kLDb{9pye^tnf=p3l#rn0}~MZkz6HlXYw+&*j4$KP9|GAPO;;ZRj_ zStuO$laU8JPJtj;n+G^IXe=qZAQ7pcDP>o&u6PTrhhp{lPr^#1GwDJ{xjzrsE$iQQ~1e zpkTslL64M!DWkTh#}SVlwHana#|2n}C}|9~W#y9`vG)1u+Jq*KqPv?_)4W1fkIrs% zK=J~nA|h@e4oiy_r3CQcdnXDwM#+o?<9bCnS0^anAVlsdMpOY~PgFS;W(G*V*sWXDJA zL9GY-J_vM@SPygJQ#IPIWIRWSug+ODb&F8$zrNA*FA<~u&ixe)G8X{*tpadd>skAU z01J5#o##-%?SvpB#n8i3%WU`dSQBVSqlDi7#Puh%xm zB_XXrR40`cLcFtgPM7pNRLmJ;VrQ3H&{_M=&EY(@$w|cj-ua1#oZn82o#nj^3~rPC z>X7n)egK*V0*9{3^hUe2QtlYA@nOs1Wt;8X`dpnWT;ZUVKg(s;kqBnSZ)# z?B_bxRYo8i5IF|SkilxDCw$7KSO?dyZ4#zv#|{}&L?VT|a-2>3>y$d6Wc4NJ?s_|M z4!c02v&m}|55sk=8(i@;QOoOJKo5fH(ruN9gzD+zpy}^BGyXDClg^b(WIUI4k=V|) z!rE9PC*nQ6_Az;L4l&oGs;tj39(7n0AyOPZPbw>#BD_LqTZ6)k)acm)4HGX2(-F5z zgl9wAAlr%6o)lC)N!qMGkM$S+xL?B{I42=8zw?_c3!Cd?hxeWB6$K$_&n@`-@_|tZ z#~6X%?WAzC2l@cjWw}~{XKxVvMg^LMWE5azO&=3iyL?Izgp5}<6CwZvEzc)C^d~+t zvxnM(s;$?j#XLpqD1v#Fk5*7$!WF9+SWjt2&M7lOQ|apEs9TW4^uLNAVy&g>YEHBu zEy|GJy{lWpGkjAY^)A4_8R4N?WAhVDZtqVzlo-Bw+rPprvo=|)Asv`taNU(r83)#A z4l2}4Fc=)<;fWO`>L<@pR>`TSF$fp?{Pql8@q9MRt?w!IE+YxgF>iDd(!$3XrEVYz zXWT()z7^K%d%9z;W!PuzZpX0A9bX<%958az3`k%-Qm*EBL~Xc02)BBv{Gf*a zGS*r#PU2;&u!OdBKBi}Uq7Ne?t8#wpMX4&Z)66Ga65AALa}PGZpA-`5?*uAiK}!Ui zOvJLe9Kg8DBVoktCmtP_JwQw!>u$vRTrKtSy9Gz08k{SS&X@^nh9dYnuJg2JFWVrc z#DuCX%y#RUhpah$_F6ZEFf(O8+13~M@P_VOFR-&ugKSEV{D6_K zOCg+_L_F`)N^vV!7-Lcj+u^P8vVzeFHG9yt{1jIU!JJ)%-7XGGl*AXo8E$P zX#TG$Y{4uq0z%iNCzjHc6m9|BjM+}8D$!@yIRjfa3&frVR&^2u!!YK zMhg7PMi{V-o9p%Ag9L<6)}T+aOhgFY)`GQ~MHRRq$Mxd<0w)*~Bp3nFD*t2hq?gD` zJFZDbROof*7Iz{Ldpz*lNp99vokMSKEtl#RE)0cZrOu&FJL$zRex=9avvE5mxnJd+ z_(mheqQM_OL#C?nHYdiY?F~?I@i-^97DIf0cUvV{w+Ic$gyg~lmF4paoFCqpe5vAa zp5FF=(D;T*dJPt;-ns%Xisl0kq4DU}_|AK}bf_h;Ng}3!esRT@o~TBr>5F`POvOBt z2)TISt1b2#Zo_bZ~)?>_jY1(28+8^4~%CoQa?M~6?s*O zY+)nJYe9GA#E?X1gyk_359l6P zP0$;+&vn%-$}<<0oG{0K>E5mxasVpz-jhG|MCJI$>l$5K5ikk$NoH^w)#m)>Sv?nQ zwG7`LoJi5$64uB_$a8J{><7*Q<+B*MRZV0E^Qt`YaUwChbS$5HXq|vbGDw?L^K>_? zPO_HYo$Ev3(4gaYy^E5SonwutBL}d{osB=@)q!f|!v5MEB_&&^tp@B3OK8JIfjF=t zailBrrUkAHNR$mdNKtm*d1ekMz`<|GkN15y2BL~OYpdW@j_irz%ESQ!U7>^_M7wJ? zV^>d9h=IQNQ}+RZ61$z@V8mMxGHr=e zvHmu`vS6B#bDT0^t(x~%Us_bJvJ6`q=9rZ2X$y@8hshw^k}Y1kyA|)j2N*;@^hiE? zq@EOOm)&SH7~Mw*raO&!Sd!V=f;6X@yhEc3euWFG4#JcoEd`mKT*tC|7(TMyN3++@ z8OK##WY~MO_7QUJz5LkepUs-_d zule0QEDj9JYpt_w(mrL5f^b3Bs+X%cc;sSyUm~L(@@)P*skK+lmJ!g4&us?JeA*r4 zB3xacs3cWIlg8`(wQ*V{M7Twe|zfSVB?qzI4{2()uDa=t@PaFFMK-TkNP6WLv^lO!u1$Mk`_U$D94 zH97Q}NwvU77{koICN@MZWhA2s-f26y+)|h>IA8a%gx%`m<1^#Jb5~M5yd(J;J#7G+EWJ`*_Xx&s5(5>S;m z?A697l&XVfJL6HuYIQ1`xv-+){jXTkOY|b|cOIYs*Pb9_haH%!4p%Wt+K@WtZeG+E z27^zKGaTjW_l=dJ9(^YjNoYD$;~rpgLZ*ycV;z05;(m)6^d)R}WEEaa`ZZ|MR1sRN zg|M^esBku@#YAG^pu=!$RLIl-o5UFg4Tvl01hunNY1G9WJj8YE4 z)!&T`8bFQ4c@zJ{De@UC0v*LYy7;O!f<4`E_ ze0p&wGd$DlJz9CSY3)EbzR9f-d!6QS$ca=@@Q>WBmcs;KUu~c_x*TcBLMH1mG>xt$ z;wg<8pZax?OHs{s){mkfS%hS) z_nf0hF-k7#`1lU+*-Zvu5lV7zlaqz;AXSSu@hOrmAE9h~kWbrq%xtn0g$Fdqm>5zm zYZGI|F(8hqh-c4;YgaHhG0i}hA?WnzG|B^^imG4f4$)JU;VsS0+nyAcrK?# z94(kYxB9gR?zJURsu~nQNZ^m>FZ}&S5LJ)@>wgVEs7r#}t3x$np&eSVz>{@7XxaEN zBKgs$j_-}Pz2RZ&}lXD`Xa_u=U09?ZqhLGCH2}6K|BABpF1xJs^x-LwQSBmMd zmpf4s%ZUA6f2PI&&^kJBo>nNJ2zFRkN)P`rLEW4}mNN$Gs7~I&9R6&|tZl?PebPbovwa*WlXCb7!Etg-L1;LDE=#7x$Fw9V(9W_w z#9&+NEr1j5l|lYVZHd5oVNpN3Bz$CEpZ8#hmFQr__QS)}L(ch5HS+qfE93sSh#B&U zz_kEj$mOcu7_`(OzRY3A$^IhDW%haKO&l;Wdepp_EplF5PkvIIl^`jk3-_{p%)^Y7 zunF{US!0nZ27n0xJadCWpXaSC4F+i-(w~SgcAhdDbQfFDO4Tcdh^7ov8QVc4kNbQs|npM_vkthOhR0 zMtEju_h<}nT-OP}*N~XvTnFjVSV&i&NSTM<2EjEC*s!Vk+%b01tw(_5bl}=ccZ+eW znvU0Nk+Iu&(uVh88{9NkGEwf+|FUdqd61kRYv)5C1y5#!&{p9gWAxURk;_p$6Nr~4 zh}wMA4a?ucea$QmC?g?XzFlHiY^O!8AFMS~+bpJWrZ*gkTwApW!bNKDaj%@gnFK-mrU9b2R(R*YuL7+PP3 zLoB2o06z)8j$y4TM3*(P^H5*<0d&7`MmX^mss#S&KSM85%j#SNj^;z_z}de_!Mynq z)ic~dj{aWrjDSZ*0iLNWEz*#G&U{&Ts=Jm_3iB8r3qirv5)>NYPOSJUR{mx*A>SWr z0)^5zz&Tu}Kg=s{Y3HX3Hu0%>GUGDvnA9!U`9M&E*)txiB7*VFY}yd{*; zXs;>7%^QYGh#_w41{Adw=OzIKPC6N=Pq`LdVf0JiOC#CDG!O~@|vRM`pF%b<}S zT3}PWJ~e5k%Ja@agmLckb<}!sHe%xlu0RFe0W^|daj6KiL(S(eLVlbc{+d9USTWg+ zUD|aNKdwb5g-3ls4wNA75zrpZ09LnI=2)vNrbHBs|4Do0_mkCl8sHY#BnTdG&KiV= zYvuAoU$Zo-g+87xh9Y$08i)HEYzT})w1ssn6T%pj=nVpQ;^LhEtCizn5~*|zBE#(DoZh=+3WaY{s051fI(aE zT+P{}KUSGFl5FVmSr5o+A+n#M_VXL;IF;@100|au_xKv`4J+@1iozm2P@`~C=&cb% zgMj{sen0|`N?p?^W_4QfIJMkVsI#he+jHR2*HIvhI2cAHE)82@oi>^j`^ZjOx}lgf z{RJ$CSdHUdd0IvPbtRa+w&2)Haj6m0>whFDcX<=bCM@7V3%J0u+Bv2)SRDVE-j^Bs+KSJRsK z{~AmTM}mWMG(%PT^3*u(-fbjRkOtNRQYgnbN*0w(^hQ?qV;|(HQN{~}LO_m59>S~Z z+L-`pdwsA`|L`9TL>EzgDhoJKIY6w2Z-5(bC}1uU9NQkbck z*UGgXU_{wm8A86L1pRvax!=~~Z35$#_OA1I9guB?7x%Yo9a1t|z%j20kY0gx7e{Me znn0zfgkap;(uvKoa`bfCT{QT{8zw%B$8-4%lk`9W;O*t0u8{+Us4wDj{ug~Kra2IR zOjxSeB7HBv3_wWwzCcVemT9G{3m!9@&*n}mL0Tarp}W)8(fz$u{F0K(OL94j>vG-q zcSBMynG|k8&K*}Q3DOws8;PLl{vJWv4|W1L?3ysQT2yen==uiGfcq!X*Z_cKog@9N zCb--QPy15M!vbsun4xFK6L)D)SaGeP?n0`*6H3XrtqI<08k2y<-#}2 z@Kft@@`rcsfatQJ6H;*Ik8l@|V9Ttsa_`x-!)RCEEz4Rp`7ZnKZg*WFH%m5~KLcgS zgs~Et(Q5#4H^*0kM1SFdByg71C%QKGCB__l8{4C5KDlXl_fbaTbkqFrSYuNi*U*Y; z)3CX_x@{@AaIa4W(UmI-j+au?zM+1hU{huw@Us_l8Fc2HNF>)Y%YHnj z(l}If!+iL0w@2yVLjyZOSHs$&%Ve=J4H88!*R&g-?}AoL#ib$I%o%BD%QvzNbFmX)Ys%XE z_Z+;@a#px~q3^^pIHTK(Eeg)dhEZVBNAQe5i%LjXirM~^tNz9UJ%y=HJ?up1z z2$&QgB3o!LFC%~CmOEhzz9LKkWoptJED zmYfj@i@~1he;AI+>LeS^5?38GzF=T1*q~u^*7&a#CWP1Qz`lN=sJbi6AZKpsNO>db z6gGtlRyxgFQKa>fNy1fP?TFsc3;{N|E|h?EiXjRIMQGTaNqeWVg!(+h)miz&|Ig%K z>bnoFeU{VdIMJ~J_DhvR9BHPR_1i{b>ScE#)6mLs|4 z{PH~EXI~o-IY(!UNHWm8pr}5>Fd-OJN&boydgX4uaP0P%prrKOukzkd8fdv1OE>r_ z7Eg?&p3-uE_G^8te~K`93hiZm3%G!Rt4QxH}X^*;%vaGacA9gLl-`F+hDY2 zV#jm{kssAesn9et>aZ*dh}!qck@jDna`qVc8J&dqOyTQADXQ|O{bczI{s|ny-WlBw z0v2U(Gt@F?d&IjDU{AwMDIkRL*3Rjyt5O``JVWySRVf)54<9 zTB4`BwFu&8-wsa3&kA`SrC=I?v5p%je~l&}0hv-9G4<6-~=~B~y$OvA?&< zEzWUB?przmTm2&XZx_o_%nB>JZO$zK^_~q_@${sh6ZvQr*8)Lo8Ea;mbndjX$LwGk zy}Oqpd`{-Z00X5qQtTnm$l5Fvsn~U^>IIA>C}X`?HP@BP6o~|xerF8_HQN__axJ`x zo3s`oFOcYu>%)zP4U+atfHszE*p+*&=)ZTK^pnk{2D~`(S0z;Xjv0<6jyx!;@&Yi_ zM~ODMw*g-a(T$US@bLdHkF}Sl0_dCaQRY!%r6(rFdO3QjuO0){CB8cuM#SCLUTPS? zL0?me(-!+W5Y7#Z1WeDXxeaVZY$@$`Hy_v#iv9<^e%GdJfZjeVsIfTAs}O0ASUnQQ zoWTm~Jznu;#tF+y2_&ah9UV;92EF2PaISvos+Vo-%T)_qMLH!tQV&Qk^+5Pr5D#6<|f@%Nx>Qn#CAuJ|&){J!Lo`o6&_3eok z_1E!<@v~b;Ld%jaaP~g@Act`5Fc!>+WD{8N4HuBa+XwaIG%*mIq-sj$Y=B7zBO%uD z%SzF;w_}t{3eJ%7V=+&bY+XL85FpmJzWP6dyr>8`>^S7<^|OvLG0l7knD!5fkHOfU z1-5h%l6HR%U2$HaL5@BA>+TU3Qnnqqzo#Pavy(&V6`U#UFEl_HDGx5XDX7 zfv>zbLMUHR9;(NIAj63@@pL-q1SIc^aN%^{ht)hXGJONr+HH#^jS-{5C)}g_-*BWs zt=i5KMHHcy7T8pYo_K#F644b1f4%UU@mmMgysN7fuG;Y?5>D1^HNkEtO{j5E9I;6G^6C$Jc|55$u<6N zJ}JBeVXp)OLwU7#Cndgx$yTHn#3wyd8%c(;wo+meUFk<}WqA0NW4v>1rn$`*IaaW% zIu&1 zjfOTerdbwvt{)vI3n@YtlRM`7jnzm(VL4m(>dXpxjFt=HvcfWn@gL zTv9f(Whg%72T<+oFUkK$C-(lhU|>?^>^x6tpQ;9mnV+ou3U7*}4qRBY3A&S&loFdG zPm?HZ(02XFhdc3%eO8281PCzq_EHtP)_OUNTEFW8Z80#Cyy6ET7M5^k0N@10sN@K3 z2x&Fqv4aCQ%Krv8fYlnsG5ngaic47Y08XU-p5S1|JuFhSIq;;2IX9&yilgQ+&hw#E zbLVL|@1m!Zm>f2rKzg+H}!&6S^o&v9W?% zPI);Z`IeCfPxmS57t?zT57>>c2uXWRrbHh5a{{Jw6#7{Rj zBbFEOqMKE2*0aQzqcXPthKG0btrkA;BmuOJ9uE+tF64RUi027dUYD&6as|IHKbh`| zgu`M(Qf;ed&!0~64HFefgkEfoE$>qnpkuxTxSJ!&%DCOUmS{CYV=#`dQ<&m*=!pO+ z5pdO%y?Fojh)O+~*?!-sGm@gfGD33*)Ky&=lgfTG<59=ABw}gwt2W~z5S!q=NM$gb z{_8(~B4^BpT5+(^8G;T(E-}lvOzYk10S%NBsE_bcP7P1dB5`} zDS>4~o;N4mFEd&9suwhj9H)*3M)5<3skepfk`3K>Rhj!7W`zw|F#x>To4fn`vNk+4 zk4m<5oHB1|Y(8jy?CV%+^`g53XxohN1iJV4P|#qyMRN}!I$dQ zN%cTr!@CWF6{Yw7p&%2UyF*yI(&&k*{NP7xtdWcBPxadM$Pr|GjYE?1gzNiU8*6Be zJZ7@dj%P%_X*;<=c#X(=fnjiN;{4KCf^9tW-prBtgq6 zhAvE8 zR$h-dOVD9UO9V_zDM< z7C%43*Zj7E@Z}yXQAj6HKHKJoJE8gsIRtO9g}vHMFVR46E-UhyO^&j~ZXx;I$u5By zdx*J)Hs!M28MJ?0z#uf-V||Q(59WmwyN7H(Ia6Rg#YPdMmSAt`{#nfJP1~cP@o@{V zABjvdS*3mVK3mG9;log@-vF&eS)LN#EI`F*aYaruJrth>oKytX`or z7GwxV$h^Yo+jCb?)Fc5WCInB4zWU@HnCHD`|1$lGeG%cZk+q<9h4TOVfcCf0CPs+Mf{zAyQn$=TjXDK5(YIT>iDK28;m4dUNp|{_{W=-7< z+S`YDxhs7z*5 zQgv&;V|Gb9qq2{OowSb!JdUp64w{CLSaXWAsjKEE*Km|~65Mg$&$``({wS)=%;;a# z*hOz3s9r#kJJ(r~xP2>&IKBRRu3YX%n;^IIt#zs4mdLU&{tPyv0`xmD{gL`#))*Sg z(k8oSz8smQPgg*-?bd|-YXHdS7#g4VJJHM%>z!fnjbsRuVZ=V$+7+?ZEQBi9(xGNf z$=1Jqwj%m9UfjSj0=O4Oo@di)k28hC{x-aC7>e&l@$zmJY_Up96NJ?p`J!pf$4SmM zj^))g1$=+T6)7%crjecHosj1y>~$GfSMnKqBz+mva%rlfjN?5xx$s-*JF1rNEd2Eo zrm0tqsXD>%EmsBzLbVmmw(Fk_!0() zf$q26R-O+w(+Q|_O^c5)WWJqyXi&&xKsyWsxl5k^eqGpCpyh4CH|NpWmZ}y$qMb75 z9uaOq;-KMgGHum33@0b4!UV?WjeUDCzEo?1H#t*O$*jxKF?rN`g$MNXT{Fj#PURDL z2|_7IuY$3N)YDf`IHzVoV>Bu}UXR4V0HGqjUSzOfn?jw&SzOF1Z)96s53;Ty44P^g zxu!Ds+=A-5C(lCD-gy3;r8c%CwhdcnZ1onuXH-w*gDG`Fn!DBK0Uy198hWx8Xs(Mp9H_nD;7Nc;Bw#_C~r;#P;jHbk`J*V%188}xEM{-sCwKN@aB^=JN&mYY)E ztNTTLlj_4j;a|zfai3P?H(~9Z^AUzi5*# z+(9Gr6Xyx~Ic@GiNxOIi&&j(Hs#mo>OgeYB3pg}L(3v1r%|kC}X0YaULFBIemgoUY z3tYTUMQ{k7_h_EGLBY!;*}ZLrYc zhc5{%k4uRkt7h@dZfCCtnHU?|$Yp_}H;S#~9sPo!@!=kg3-_J9 z1BTcWNQzaZP47ZMyK0P*Mu&n4L-Uj!BR2kTxS#s@k|#XOM~Pg2fkJc=6#tlG!259j z$7Nc>xpW(GJS<0f2e~}LUr0~AuLA{Fsf07g4b`kd+e=qQLGa`V4f8`mr4+Z#WFyJ` z{}PwRFO8n^9Wy38R~O-Xl0UZe+4$f$<`{jaiXQ0LR;FX$qnQ?TNCB^vRY1pqOf8Ank zTIMHn&bBf)Uvm;GG=%?!Fda%w&oUml-;H7u}!Gf84`*c(KL7FVIyV541fM^%0j}%h2 zUEpb3F~#*V4gaKjC^(y8{LqrPZX=5G$AuBN&>64Fr?kxLUG||IR^NDf<7%V_anA9w z)i^x*_jCVpPQBg%giC#>4%+c5>5 z)Y>4&ZJI|EIK6!SzKueBx;El0CelWwYrSf9Yf_95#twF1M$D5`#BRrMTeN{uRs$k4 zA>=mh0mBU!BNeWByyg=R{CA=T?RHA{Et$w%{jAUt==xO`R%1TZBXRiYA7YiRd@aqm zZm|CI(7JMtsdRTUExEcPnJ@9t`YfOVSkmgq@ZYOrseVS_V z_8S^S_4X~eFf(OQHzvIIxA|5DYt+^N9TOErBn>EO#!%r%NHl3NJXmqoO4-^CD81=j zU5ajTz>9ji7mk9<>6OGoH_%w^>~|g_@bG+{>trx{vU`Tx?~-}hoE#eVm?jvagGC6` z9fZ^X)qab5oZ1dQ%3fVQL&O}hg^O56~iAk9<9r9E;3ChvLf1w@D zlxOjX1S!j1_xjCg78eD>lSRMNbYtA&gsUfDR$+2o-?XF;upxq*a|#h6EoGwrDT)~= zPfy)s3P?3@FrPt9411=_V}sFo`d`VLZV3{H%^o?{KnM^0dC1Fmk9tx0Hp6#Lg zAXi)^4n}pSPoAUz_j$Pr?@v&9_*nt+be|R{rNJ`HSf@atp(cO;wPXs|Qy+5oVD}2D z-!YZ{{Itrv_$o6X1Qr_S>mt!5rUS{Ip2~Vge9MYsO7I)dG{d`z&lWh#;LgDlt;#uYo)g2`>>1md6J|)}$`MrGlltvuAoZ@Lt&e3HGaNUF<8L^ybW)adOem zDG=u4Cmcb@A>UOergOJNp$TR$2qy7R;Ow392=hr+P~f_AI+OLQWVTTB`p%7c3$1hV zj2`6OBsd!0cbT}7%D}+9Jppf%I&Q@%ZX}%f*~?45p4tr%`<)g3DBRfza?_t}cNBz% zRuJ5dYNulG3uP>#(SNQo`kO`%5(pxUhZRf2ZH4=3{?7ZfK6}rIr%LQ2QY>Pi`0))&I_& zwSUyrk3l9Mp-eQ>mc44?|Dj@r8GGdjdgY$wM9L)I07J*k$Xg)* zxmG{A@6E*E*N~^-`GYJSjl&zFtId79(JS~cp0<_X(dL1Pr`qsT!OJ>@g|!2;jD46E zsDmlH93A0)4z&cjzlktBM54vN@o?Mo6ZAx^W5k@3sS_LV%ob+fRuG5`cB@0nb@)#N zCY4NWRmi>gln=@&E6vUY9_p?F0gGU2Y6BGIr{A8Rl#)R#@EWJW!Tb^P0O9<4m%!nH zkU#1kfB3N2OfB4l`X`I>?>jm~+@-12Bww-J9X|thJCY5wgrr;VpNXCC|IflGJDt)f zbw1n_d3+42Z1M%2Cjk{1U`Seh1Sc(ml0FM!*IN5>``ttO^lui@kB=eTfk=AjIo01( z58=LL$w`>8|BX^HYRz7Q7eSNFBX$_+f^ikM*xn6Si;(8@SHb-~4Qj5@)&f4cg0g~u zNTd`gfK?r@KKOn%Uw2G%Y&Ft+Hp(yT9zS&MrRROlf$`PBv#*dW##@0mg_w9ePbyXF z1~7MXmpOIMN}E-*CO(a5(s1b4nOAR?M{TDX4u#DCr9KhtcG5>CaoSw;vDG8t zVsS$-r&x#v$Q#oy&7<}VMCo>#4Mc;KI1#N*{{Ob+{CPjgt&JW4ml@SC-K%@sd zQj*}2+ub~$)1kNd>(*^#i0SoCn2vkX?7$-6@)YtQqNB47bsD?gN8-St?>$_@edMnWfd@Br_qnmPi^A+hYpWq5MNcWKlMM@@N?&nh(W8xC&` z(Yxo@wQpAe)Xi4D@Y&*y4!Awr_Ln&eKH{>YlM8g^Y9RzET0RGy5l;RAZk8U8-~d}d zq`&?oBz^=hW%S}7HdaGAZ0pw`6LCdq=*IfGCU1S3VsA*qs{#uMu!F$ZFr6hdk6*_*eE~T};1?b&hsja@U4hw0v zjneYob}}Z}1|32sjQ7e+;aP%g>XvXhxDE4XonDlgck&9F-lfvvs*#1q50W(m(|Qy7 z@`hSC(SH!wFb*^0po*zC?e>}($4#B%!pr(&R4xfhBvGFiC3 zgw$fU_BGV;9NT`Tyew2a^vV(Bt=FZta+sO!4og_ zYx;0dD}(NQ!Br=FPo@fTCW6gP;^;-@*ExReHQ%1GK~WWC$QcMtXVsyPXb$dK6!?a~2wGPDYPYO-jdwX-u>nmnfmYmG5ZX=B{rscj zszxaq>YPU#(58eRaT?P#S%2^MfjN4gN&!tq&!lRceg}(~7fD=3tjPTwuaPheHe>H; z(?|4n!S_G|n4ZgFWky9D8~qbD=^4K(SyAW&MB~CsW_W34qZ;KZt@yWv#ix$VH|$n3Fq5Av#aD$S^Hx7uJyvjLUJtZ{14NoOhq{8cyzH`yUK&Oxty zGu_SLk|#K0cj|@&nNDGgkN!@<7Ho;E9}8!7N%Y%o)3_a+vgVk9u0P=2+WJh3Fc^rT z9ibSwD8dA4fC5_P1cmxkI7MXPP)ayVh4%mq(-zD6IJ6sTl|92Gc@92-=EK?B1sQy_ zP496cQ)|Qy<6CY9@zq1|z577+v~|rzGz7 zbgLKBMlYi@d{O8S2ygbmMv27I038$siDXjEAD0Uql)jyyYXh5uhd2*q-D#K;S5x!FQqGS-4#p`O z{?>tP%oHf5pLABm_EEaXy)uAb+bBOuRRQ5S^_<$XLheHs!^ic}+R`po&vy>pa?jtqEzm4sQX5KA2$JD?@r)lI-yHqfMwxL1SaE_}1)#EOP||KS z^lbZ3nX|zw1+N0-82WSx%%vDSb&W zoi!bwH@z~lA*N4>*ye>q&l3_)Ur=!YIsa~;2mkP!1l@E)|ixK)GFIIvD1U{s-*z=2<9RO8ZqQ@>U&85+WQ_(qm`(>05L=IQF20V;n(hZE+p3IVgyho19RdS5Eb( z^cTj;LWG0Lq$qL-bYkJ~bH#>icAe9vxLtD_0^(_lS=MS(=@W=SmFbsX2V$immwsNt zEXS`3+n!HEOV&NWBsfqd=R(n-cm53D;YAl!6d?sbD zjnM^HvSZOA_kDL%Y=;9M4lAyvq_x(SG|*yB`^)YD!S^@miI#{mkS9pR zmhgUmX_?=9`zw1m5NpvI`|`~#i$@{Kl4K~+QyuN6eWZx1(Egh%_(+tE)%slT5<}m% zTZ2RM_Z@FOMCKsayh@twpm}DEBg!=uhY?VuKyLc?ucEg*n~Ovlkh4dU2rmrcm0f_f zlU^LP&Qc2!!E!EUjL{R6Huo3ft!c?EA!N;uEsqR^r6Y@M02B9Wv}hX4!~DieCMUH&AO(PdR&vxxgy z$tiI0MZLaF0Zv|DnNs*)IM1kEX;g=DLCVBq!BSXei`t7}(W`xp{!xwg&>>9=#p-m; zA(Kjxl_g;g=`y1%4voPFy{8*}PTxnfK?{{HjZ!*?-sw3M|8 zv9%LNE>Al+gZ2FB%th*3h#|UD#rD)=#Wx+HLN1(|P%Qr2_AxeJo$X^nAl)bBG&~Om zi;pt4N6rV!C&9P=vT1>NAlFB`t6^UWnctt@Su=If%>I&jA1zsk?@NFTIHR%eu2Y0B zz0(ZO)%Uk=ry?KmR(1?{Qlr4oFTCF=4X9KND`gvh>meeq5W&_ks4uZ4zufNWH9%>g zpeKbc7{N9q#g>|dKfC?)0-~XkJQhfw#Q=PJuQ9r44p@lv5V@w{Mk=_C$BwOh?9z0S z{u|J9c?(X=EnMe-Eg>A2{3^+u2M}b7_w^i9wrq18P}3SJW6QeJmExwu%0>NN8@p>w zv-ka~`E$5*O*Veasvh$oXr&AT()Tb0Ve*FTb^unw15Ws`-p@*2dX#Q1)1N2}hS9LhvwLJnUd+-(J$~ z533~+yZAI7y?@418TC^rMs<_U!VBO1rSY($3zxNaw2CW&RU;|F(=wDV@aA_cO>F$h zq>R!+X)hOs@E6dss{LZiwEem%_=QD;ov!$tk7U)jwy9+KIfiH{tTKm$Y_JK^-SX_A zI{gthRA(t-C1U7mOJ3fZ@RxIDX(}PUm4?ds7wJnQgC2}GN09?RpSWNw-GaR;!{;!M zkt?Jl0Rys&z0w^P_iBcynG(>?s7M}|ALpPU3YJ}!>4n)e=m9&GKW^8iL$gv zzAi9{3XgRqC0s`60!7OM(WC2daR?kn@hn5)L@;V$F-1PRM>8ZP6YKXRW))2H2QUBJ zHxF@z$X2H+B8Q8vH8Clc@PYd*zeH(ins@!cD?%1$*1gd2xj>K7nj0)+cx&1>Caz5G zHm`(X%+K@a1!TagcN61Pm=&u#GRV{nk$_kC9wg9Kcq!5Y=fu(p%I=$BU!nb~ zg-d8Pq&x2^xJiZXyE(wdnU}_fY$y2|8E$;8bwLdX9`Llop4&i%l%0?XKis+eSwY2H ziI+)A8U|>C*nSC7;fC0VzKS+Tvx9qA-H#Y&N_}Xnxdrg#Cr&d&rxOH}#aFL31Lz4h zTj-Ll3V8w~Lt@9J&U~zG3i5+91v_t@+LoV-c|L5`x_|0~*dw-*!<>H&%X^=_!u4-) zXI~4^bG3{{2hG^-D9?|MT;3FT$6(d;NtZ@nNlLVj$|ae|9NuSuRP=-i?EBW>HYl)4p*yw>7D#NH?Pq4q-NIuWa%^ z)>X5m;I9~J^?0>>$4De>>K=bmwCHk1(!Cs>=373TY;0>q3_7=GJdSsFzfiU?Zs8~m zDuqP&yYUo>s=_Drj-k^By66MXCmg24V{ky{${q!`x7@%7ObsCtU;^WYW#=41hTYqL zCSU5htj$>bsh4Y79_4-gu|j{D-C(adMmF8TaD!9P!)eHn4l6XW47qx^Ykb1< zu0bTYlwaM>+LhW#fwuUmjdjzi%`JNUh;0Vdk}|^>h-9bUIqM5toc8vUkR%MA3yB=d$d+;!u0~;L zZoX{sq@+-(Do59V&$X$(Mg}!_>-H6lm_nYxr zPH;#uTB?>F_;a)mvV!yzthzfAHXb9t35pz+M^-HsB*PE`J5MWSJs5T$;4Nb@75h`_|hJ6sI>;Phx@#-G_2 z%jLRCq~Is`D^6z}kd~hqE*i2;4yh(V=k`Liv5>Ap0ucRN~Dy3=0p^;qOxUTxexfn5lGH#bdD%x1h zo()&v<6nCO*vM%0qO1%l@P7X?`%@aiSV+ToA;`ueMZx{h)BUtKT%AT>svVpbH_- zD8%1qwZI@r41VVKL2Gr{9Xm<4PXW;&Vig{r7O=fA2?YQTC0aM>rpE8(IV;y|#g@{o zMz7Pr{p$ZrszgYd+nGc^O7K5{b@F*JJndG-@bQe>9c*mO`@%5xBot}HiA~TDcQ*j& z$?`JsLyO@F#90^lAS(fOAh-jB_SY`&Ag20@bbm?|Gp(#eW*94L(zqZR|H>t4{kltA zoH#X1Frp+qyVUb%B&Cza^|G|31XH%;$K3JdL$`CPt6b{K@#|XzdjAhzw9_g%P#aVq zGS__SKklW-Mo4~jV0uDA(-jA4MjYZHF_bYRo;j;}`N9h=YgMB*vSsoY2;LQg2R0H^ zj|(HHezjK|o+;PVo5A*!BlD8Ky2$l-K4(Z2JJjiqc)?4WSqQ37^qs`REWB1M6EJoA z?MSPT>|_|V)wO@Ye}nSduHN;vDFeQMv0azbdZf_c&IH=3f*HvIw;bVS**=DCwb3B+=oiMO1Wd@qP1SO#{7(1e& zN+^OicU#2M!SaU_D=NsWaN&YDoD!hKo@=Z#is>~u=&%Agdf@-k2NpaiWi;xL| zO?emS&)87I2nT^*nsUwx@ETsK{>E^b@l^qmpq&<(fsk#T|lRI+ybgmLWamZu^~^>lMPLb9VC0?EMe) zKSs%%bD<#!+%W*El?U)WQCIqF!;a~sW!(Q)xgSr)Z36(O8Mq|1J%`JLxAp!}7F);d zOaG&07n5LVgp8GRr!XxE_f8Hknc7A)50j9WOr|9jxNjZR;lVjj{ndF-1TS__KWA30 z0)j9as&3*1YLmCV-h|HBQ|+ylt3@A7J0dnGMH!@j5+H1y>(c(#eI@zhWOr7H5?6rL zK)Wi;tTc{?{aC}jl1SKp#5rnC98i<*u7Q(Km2O6S^(RDZAqGi_e)ReXrMwEgwtH2q zhZ!^atMe7f8-wye@g{HI6=2(@14BMEda1EESL6vAO4x2F?tOGr1G6b4v+%|sd`AIh zHhL5o3D&Bnf?MPY`9V@UR-*W#p)24GA6w)O;gp1L?Jg1eO1(k!JdA#nM(lZkur~di za}R_XSxy_((GCCoxBGK7ie~Ne?rrym3c0}Xqqj0i0qD*Cf_wHx*mFmVdu}n34@(vi zh8+T35_wtNjH(;Kbz`#DzZtNBa5NIq3BGNiF?Z6NS=`HKwG_=aF)XGRSSuv_DxQxx zIC_BEi&P!Sna3ZPdLJ?)9JOv!(_!a$8En-rh2GI;Yn!17hhB+Zi6J)fl)?RMPT6bH zu^UJ?ntRDo{o-v08S>gt z#ubl9)U0tq+?fk;D8-#(uxL2PGI=GJ((wfCqiZc zGU1-4-g^|JNoa7sq~Sy^&ZFradcE=FB@sv1sxmbA%02A!U5Zub)O`ET=cW^?7GJ6Y z8Qt;tT(TZ$njw?XI5E2>c0~AuJN400z8j8BptMR_eu?Eauy%LF!Xk6R84`croVdXC z4%MSou3`A`Yk9~nyru8dv4jj2#O<>fDb_KAc`zD}@H^?z@*V8U=*1kh%Z>rjvW7!5 zm2iG_siEh~+4R%l;^{^qAUo+u96ys+G3ynar>4ubx2Gh&W=xWN=#D>}sn@M@Xc-yQ zwO4}NXFTkz2JD8LW&gXwkVxB7%%t_-EX7*mFzu~3K#Zy~Pm~@MSx6nzuYl*zYo~DM zm?BF+0t_h$3RCyg>$`QdFdS#<(zQVTS1de4jg10$@OF=qtF+0$FZJH12^8_=H0y@? z&&-7!oTlM&p26gF#Fkz3OCwLEGXFRsk3;2_AUt@uw9P4Egjuz;R|lwhcOmqGr?EEf z7LK)=_XDhC10YBwyu0jB?V(q`LH|ZtB_Fhq zj)9RGV-VD--#f16V;bBEU#zOQYrSfaaLz1aZAf^^!C92z$B7qn`g1h5)0|G&tQdeL zzrJ+}ngw1|%et$|f0p+qjDp}JrG~ZNG0-pLW|o7}1Vf4_SxMXxIN4vqF{-E<|5x#Z z7%1oju9&13#5HyGH}xkzeln!X)I(VUV|#p^r(qKJ+!Ejitd{d}L*+2wOi?Ns^?6xZ z#dP{q7__nbOPl!Qq+=z+gzGM$`1pGzYJC(q2J5b$rGT1>wnmlTQW4ZJ%n^@DUREYx zJzon1l+DT=YlBgPjrcQ4kpQIiL|d((N^-B}N(~;L7;CiOg<&c?;Y_N-7w=J@uC>al zY}ujpqi-C_vp3o&>dUt_vJu*!2Y9M%tz(->YyKaTf^*5p_Gna4ce;4Tg6_SSX1O9s z4SF9BPUQlNrW+CbrZ*~FX0NQJpT8!UnhJ$fJ=#9+l$1ctlh3$TDfl2Dqh^D;$WP`XmbJ1(byb+{5ztsr zChUP&FuJeibT!EUwM7wvq9S z@{GmKK023L|KT?i_iG2Ts;XBQx3U>hzgY`!x>i&atRek<14|1zRJ!@PbIoTHFv=N# zPZ+dyD(rZt&|FjELo5hiT;^cj1om~xH9PibQ((aDuoa=Ci6b;gHPU!Xk9>_;BA=~t zM_b%q^5vPEh@<-X5%o|?w=Q7wfM-b&K>+1INS+{4Jkzk2NlcLK24tl*cggdqp=)D8H>x;3!6H#osT_+(TQJY88a;yWDYtLr0KNDkO^wb zT@8a11S#dE^Z-`$fR;0p^xQ@D(x1N6h~@T)UiZq2=O~zTiyDXYX7>AH zk`vFemhj1o5}EN9u3RT1sQt4{!sb8H#tiahPT%ncxS7N{HM;E>KKcVujYVh@d$z1& znMdw#i_5_Z`6KWJ;R8yw;AL^hWPS}f=a$Don96BArwA0HYo<%f8^k_;JlY<4uF|pB#}jmr|9w zBm@M?GHusO)SioTLi?Zmlj_1jR;lIP&^Lr;BzH2+dSizT^2M*@wZ=QGW?rt4 z!Xzhp3+)?*T>=?}c*wEN=gC~oLs+aFPR+PFxO($>OP9~Sh$PUOT2(^~NTPqQOV}0y z`{oR5g|xU{Kww>yQN}X4N+XtW>*(kK9)+++-i8%YI>*lU zrQ{~Nc?{b~)=OMl<21>Z@XKh5E$*W?G+#btK+fUFE)mK?QB!g~sc2NR*w=D|jm>Qz z4h#=6I(^;2)8{Q8Qj2qja4O4jH=(QJlv>xFXu)n>awUQ2MXhZ3+naDPx$sXT*8|9h zLs5EF{%+@_Qj zEFFcQ2aWjhl?gXo8zOrw2Z=~gFP|wJHwjQ03Yu@5jNtXbn#UC6& zX6I`lvL45?)Twp5gCx-3y}B$fqyrrn#dN}IAaNMc#jtq(+Evm+D%gm0b%qD&iwzIu zjp#k}lip01nBtov-V+#$#o=#lv>8VKy{0baNX=#Dw^5C7G5+ zI(VaYEuKOKiXLJ{q|hDWOgywqz|r>wTjbPnb20pwDpjy}l39x-mlg8)SBreq#78d> zJ9ge*vESUV71c`8RIOez^jaE?=%7kY1l--ySLGy2lTq)~x<7aP3S50|r-tQ-(X4bv znmM+ZJ+6sP>W$pTxeV8)22Cg{Q7hXpN|78uiR8L+)$JB$xbK14QTQAGtBX>&^AWS< z1X{3Qqcsw0pmkg!saojM*NPwDo3|c)zJaP%TG%aq3}CWoCT*&V%n?8(>dBP*JDaCE z-r4?ZOZ-2--BFvN$}jCR*gcY@9qzJ6&~j>)GY{Pg*}aC_B~uPOF|7r;BohGN!hAgg zoAzy!+23>c9GK#FMn>ER=DWeCw!R?;uG`9KEs85yC*XYW@ib|dM7q03pV`i(-D4cQEp^+}`d~{@MKTWo z`E#4tyzZ)fF8;rrMXurjGE>^iQ%ux47v5p&j;_1yYEvT;`^BB z1*=YeI94RpbR3l$4q}pk7Dae3vEhRxD;8V@QWxpyo?T;)cf^Szc0)1!3BXZsS1nPI z2tJ~xo%P8;(FWGziKWb+Kxcpv>|G-n^JcFG z%;dISAom&08n%WFIUUFf+fY(|JC>gX-Pqqi-{fW#O-{3)hI_)9!;iV=!%(EFxQ@jr z&WlmYt=JkPeGiiajSe1>N@`t-=E*hmOG`t>sx3=icN* zYX-F)ui6Mo`gIx$HRx_B(|H+yxnDNyLnS=C&u|RKEW9pqKy#Q8$#S3Bm7k4DQoD&T zTcUmpArab6p?tv)l^a_wy{?K@f{%nl-z2P=s*10IGxrL=Uj6cs@Znufr50|qIg6Px zYsePCgb>1XRQv*QMEp|v!aR-liyq8gLuM%{ljruIsG~K>-mtz+-;7~eYZizzWk;CO z_;CrJ0JfeXH!2IXbZZW7O%z3J8>mdD#=|ylo?}`zb_520-E<@w*tfiFQi5k|)ysk3 z*W}$4GjY#rf3IdIig36^u8bOG(-vF>WzhQv=wV!D}Jq&<(0yIjR{kG~0VKQeeYHQ2SrtWH!5dgSuCx~MAOnc!I;YY8QBs)fo z^u81AW#RHREu?K;rjz?*4!uy^DNm4&;eTF72%8+Y&IW)|z_o&RNj%_iAB1(D8M1@g zK={`u9=tiV9VK;ReT6Rx2kCQ;E4Z4z){v2I+kBmyLmeTAcCe~@Xym7oWaJRbn5vkrVxR~!j5wAekJ7w(27+-uEP zw-~*JISaYCH9Cg7h_zlz3VxgdwMFH}I949y=l6)Lb()u`6}BzUDp_R?0H2Pjlp`EK zNq4oH~EX5obQirkqF>uV}X`r=nB^NrwKmtQ`&uRRS421!v|70kOam&wzVpII0v4zrARjQ zUaY8>PB+5t5{M|!ebKJK$AoDmd76qANl!5M^Mv>g~tfbnoZzM`Wz%pn{va)ojVp$((lqV!~h zJVR~!MG^Tx+$Dv8L4>CUE_uHUr;iuvqQr05#-6L(MQ^Iw>E?v+Uy6{KGn>x?=FS-m ztuL*CxEKFx|Hu@k^fy)9y9qoz=P8vVTv(DWmFPQ*fi3-5iXY$cRHM)Vsy#Ac<&I*f z_B$;O|Mcky=kGdW5Hv{?;fT<(9k(&bq)4c*WGSm36ceYoxTGW<`L;e{rd|-sL|mOL zSUNVNfuE_Qp#~klmjj6M^npGbHR{l|mZA3^Nw?@DZv}jx#8a_j+y}eXSA|V?Gam$J^O} z(*AroP$AqMuABVSUskSa*)^dn)>Dw^j4^W$qn@EJcBpbqURcVXkKge5YE-dbIRkno z261$6LhfUB6S?hlt@+@mHJljW_rG{v=EKPTzN3wAf9{irE@q18xwf30xvQu2U(>2hzJb-LUL-bipf3O z1d!beygE+$)K}Oqd&}8s=lwDlnIL2yb_cnmSburi4B+fAzodl{gkOUyCRTlCKM)(uIa5$BF@@2q`jsJ*9Mp|I(z#nX!f4P<|! zxovGI_)9~0QS^lIJZIS5*9&LE*_C_zeZ(^bkn9SW`)dv9jC7PB_{+++atD0x`p`d7 z#cudNH{<@fnw+!tmQH1NA@!+oL_FQ zbd_aHw&2sZTgP_hhZ*(9ur1(=uWdXrZiL8&QU56_AL`UC8jl3Dz-p7i#pjre$N#^$ zj$0{PriaG@h*2qK*z;&O)TX_nTpPC&*JSNzA&4tkx|M|5&S5)I1U|yu>*1AAF1D&@SGLJ)qLQQ9Whtl#7f2+75V4CGU?4W)YiapFcOQ5xQT;IvPp56d`ro%)4Ce+>0Ta zk6)2$ngE~)8XOiTdI2OCV@oLxnt@#m=!_sp>l`JJ8CDJg{XVBCHd5Z zK4ucmB<>krK( z_!pc-cgF@mM3C%i+4Tj~h!;oeDTOk2d!*xKFi@JACXryUxaEyCo|+S7g0f5T?H{+a zzyszTE2~fErvnNU1&F+n59Y}ieFT&Pjk>B7>z5D z%e#Xf1e3_ai8cM&>rzvn+%xdtnHdr5Rnt6Q$|+LkYtgOi?T%=Ik%fV1aCl)J3<)}d z+}kE*9HW4lBZ@`WxDc0sa7lQnOz`Z?1<-108ld;yc*a7$y`Ur=Ki&J1!oAj9C3HP2 zxL{}7a31KN&9s7$o+^~3qSVqPr^>(Ki>vd}e5T0eukYiAu|gfjqBol+MhpG!h@|nT za)sVPnP=6w*+??@lq-90$bJ%`CuxL^M3fh@$gwF7D zWs_3KOSE#@ETKoW;{ap8PJ|W!<{!PfNz2oH((6jH)v{BT`vh~q2{H5Xz|*GT>fu;lss(Ufy;z?- zolmD)Wmf_PMBtU3qF@Hg{gIA;&Y^&myNL3p=Y#n;j|qqs^aI=fVcp#lqQ`SIAnb^r}PxgApF~WR3SbhCBpQUt-954jfOY<6P)u z_v2mawJqCw4%?A5)rU{!bM8HPd}m0tyF!)?oxNz7ruvshhaK(l|e@){WbPR^yxyz?>CpT3LVJb2PCl#2SaClfeBdM z_RsN0LcKhr*XVQkTmLN0=F#a#Z5f+tV`=nC-)XC2L{X_tpvkVe#|OK}r&K<I@MQi|@BmjmWyCqnOYu?t-HoG%0SxYdItmT!IBCEj= zHJqU!5nWGLT%5Q%+?S>E3-y-g?~rlWe)p@u#_nd_W{7%<#li?hV&38VHDxpao*gCMX}073yA!O_6S8Dl^GESE zRbLy2>Rnv@ifCzy0H1@td3^z%^0Hl4;O0r?;dWPgg{+ho<7fpGwKG&?TE3$MkX#)2 zmlih8cIWV~it1&k6lVgx~z zvLji>u*D+4`l`s3bCFwQ8+5+Qp@Ff%CZUv71hbrgw*YT8$A4{?>htwg#r|R0v2Bc@ z0tmA~=H^$%|87U5A}%cS%lq)53y zcG=5r8a19!pV4@-xDBZIZU?10-#jv=5WRCR2SsKNVa~z`8JIImS%I~9PezEYDfsom zDQ}PEkFZn7dPv%Deu`;mtGd}B50+^`rjnG74~E~3aIgOHAW#AS$}l8nN(7?b2HYkd z7rauMVsgRQ*Wm5XOA~;azj9CXBqq(^A(?wzPrqD22#XhKVqh$Euq`5fC6#J~4@Hlf zlA+C|Q1DWJVAzr27vW})(;q>9Z}D=Ywi04S7V0LR+F=t57x&@pz&QRuF>5#~OQnwc znPApRz58`5LDVx{HU2I98mt1d@S<({ixQdLRPr1((_mWLWv5shg0%KYck=3^saKS@ zZW-EsrEs|aIe~rp>ej{*gbIol-kGN7;CFVoqi_4PkHfu?*eV3=LXn$Bb16fWSmai*~O>g#c#uLXB&KV2~qX80p zju5zGL07r{Za&%|`;rKKW-*;l+Z6P+xa#gy53j+Q@Q+nQAVkonn4_qRjwS=_El^Le zjnMLz%owS$4|(IC2(wcQoS!1wMOW6UJ8H|^$=X+SWeUL;vzMs{Kp^{aEygz`AE3*%M&Ohw6o!~lWRtQ}K zi*W%&5gU8Y%r5+;Qk&}@ilK&N&oTpRJ}Kv#7JlL(FJIz@fA}Ic5Shp)L!r6!w7B7; z9e|vHlJ6fVR8jL{oO&eGTHH8KrB~fep;GhHouQLnzMIi1Qt`W`KRT3reL-P16eVA) z?=tfbY{m6o<%m%iV2jnJ>Wd-l8mDQXS^4WxlyEDSE^(=h5*5yUS!?pjEWL&MBdg1a ziP|Vhe*BOsnmuhKSGw6S;1C3{e~Qn@Cu7#V>hF+m!u)vs#9KuSL5fpbykatje;K!n z15oYCj*Fn{Lvz`> zS-!QSy{L{wwCZ^B}$na=g2Z;u=`#Bxh*w<6g z$#z!2)AeS6TmMSmu2P0nBva4N(uv-2Vw^FhJz@u;GfBG!h}fas4o8i004-6YHEy;a zzvV(`Z({oM5~&)!=%n#&2j_5yM7KTa+&Uz^pqseGsM!YI0%(5KEjwQlF>*C`_7HA? zeLSp{TfUHV^FEsgRF~r&&*H^^YhMeN01pmRHg;~A3^Jn0s-U5_?w!^~=PeL=@*+@D zzwFGs4S`iHtSmCtE-|DmygNghSOgBzn-?mn6oeDI?E1R_-} zbYUqDPchpynK!q65#EPSgzIb+%)4<%t6O1F>!HD4(V)hOd}2Gh&>37Q6lnr;??6fxJ+N_UHU_);B{5rN-7xD7C6n zQj9DHWNaa8=VwZ#%%L*y*?76b+d=LS5rG5)b4bQMU~Pi$;;87?+S#=hL# zyp{_5KsJEiVCe$_3{m%e0n#BjL`yV)zh1$H@-^$IAr*9dnN?);NY>FuA5FguAYF#J zt4_#<2yq<~_R|-vVGvy^v`C@3d0GiNWlX)7zDUMq*vUzh4|=se{T(9EUF<8@5o0@`al6fVizuueI(&jqfWV=rnY zVVywhe%P0nGiO|QglNKgCRpQa3NC7b)y{}^Hi33 z$O8(W3|(eKh&HhU^L(QcHqAqw_|F~~1{XR?Y z&)^1EDD*BnwVph^W2ShH)wqF9@V^vg$N--XC2D$OSmfuaf)>e!Ae3=ipPR$QGO%nb zj8tbfl(9!M{hxe)eh5(?e!mG<^Qw20^B^0Q_5`vCo#MMq{%e^ASU`l3`VN~|Z34bi zbJ5AiF)B(DEVdl`NyZwJGao67l<6R+<{;+3&0MxpLhzhyAz={b4xck$$j~6*KE-+v z@#Ps(&EcqGLm+v>tdl1Kjv)rQX4%L<;L-48fu_WVg)5RA)<}i1zIgMAqVVN8tiM@Z z_)m01g_r|@OMY)$p%K#kFn`U^;>^^57DlFIi=O-{8f9FNg83sz5%%&>KkY>Fnp(;n zn$mF_)=W|MiEm}(mqAAxhP{KJ{;U@0t0}=8ToP z2w+ETd8`k*M*r>LGz0#ph2>%6pp9$&&{x>3rV7ZZxsS%@SUMV3#qXGzm&?{zbJVwVO35I`D5k7-b3QFXY z#=({slu;LH>ToA_((nBPoSGQM& zCZpzV^3D5uG;~u3l~K3-^U;I7CDtrya{`Wb8S1cuV2o3pcZMEi$5$~a*{M3R4cPSg zNJ;xVKs_78i3aV81khy(y!j5r(|20rCSW zU8i)@M6Mmb`NdmD1+ApgL2a{9?|L0kj5- z5P5Gb)(WCAk99H*`VH*;aes7|FzN1}1R=G_(NZc87`{Hcn6Fuzg?V05lN>^4XKU3# zueu33v<{ad=DXo1q51I5qCMMzFJ+Lo<>k&DJN`6R%{sjqStAnhw(|GE^&JaFj}~fy z{=t`xX;om|@L}m9Fmf6sFxR{s`T|w_xl0P|z=yK(Al7=E`3VCmO}P;KN^$N)D$$iEzV z`yILCX`#1YwQ9Looz0o}IJ=n4@PqT(0D#Pr5 z4v7{H(!J^q&%sM9mub$^l&yj3aP;`)cjl7dBRJE+-7Z*n#ltByW=Q#UJc??#zxcZF zxuJmzp{f@&8oQ&Sx*9?VEs?ftSe&CNByOb6`Y5M=iTlQb=qhmgoOQVU?7X}6?+T@N3pk)- zrEwC;s>AtmFhx!oL@f#Q@u=wDSch<^k%sSG0+3Z>ncmm8Uk3r-vE^0uhiTG!al8&o ziw^*L=c<19kr8IlX7R)KE#3NFvdfuGs!ox?lwc<_f~G3E1u`=VFh{VgXnpS`3C~gV1}GG=v>&fG z+;E6Zx%@3*B@-VqNNwvz1!hE{?9S;?sk->yl^Y=8A$3b7e>@iV;=b$3D|eC>GU9Y0 zQa=c~L9o-(_wy;X5c;JlH7Owt?7CX>V-KCYLIOtV2TGdg(|D4i0;>eGZO0K-u z-%AG~N4>PQpnm%yKw`0M2LNRDvUOZ3g#S1U$Ot%+`K{N?!yE&ENjV(bu3(3XTP>z})*Ucq&jbn@s(ltAJd6$ZNAL3jRZ)5DcCy5^1(lxZO4-A+B=bIp(y zi#{!Hea!VB6$hvSWI^0AhJlLpD#?CMSp!9M(G|yCP_KA zLOM)Ym1`)~zNaqG3;>{K22Sp-f5NpAMnAMQ7Ao4mK{UQFDi3>Lri;z4dW_bWs|Fqv zhee}2oW!6V?(oXErj0j}t-R(RWp&fMa%STHycv_O?$Bdxmv2||cg^EhKLE(#V}lih z#t7R3$tOol7ZN~jtaNWYB3CvkyK2W;{$LyrGL;+hJnaOBOi0ILc_gzEzg0Ujzfw*f z!5{Md=D1ck4$^f!L75DC5&!#TVQz8Ja< z<24bwpWa;zu8s^3W}N2yJ=;d{gjZs)0Mv}Clk4}Vj)J<0XS+DCwi67NBAjZ5>VvIc zdpaoCQ;;pI$-bHUXhJ9U<65ut*6y~V;4(ZN)I2L#!cRRQIop7VARv3@9nhj0)QHL8 zx%RT5&GKhpMA*)1;!?x&VWSjS*5yM=jm%H@7v0ib)mny*#B|&nt;%C{@Iyfs0!eB* z}L+T)q zFfPP(#Ztw54mDQwA5bgyD3fpA5XMO>cd>2G{WsK&5$%W`%4iHuIDZeTZ;c#%)P2~g zTqIh3^jo&KD94l5spYI<7MxC8B%msG&V5`yw*Qe7#C$VSmQISugbDf!OUPdl#dg*%#6em>eV^ZMpYLl zdItdlbf)LXr_grDURO}X8S#~)QV^pa&9Mb!_>k5bey`wt*SuD+Xro#r@UBW*~+tPX$TwR7!3g&8-;gY*^NHK4M6#>K}gv zMQ(K}UYA?mTA4z@VynjiO{~`3$#EpnGvZ4h2?QSvLPgJfpzcWhiyx{`NNtWZb_pYj zKn-2ND!N~shWj_)B>yLfzxJfV@Y4dQd~L+V6vJdFs0A~^+7kS}4UY8nNLr4H(olTB zyx!ZI_MnoD8N6EDzxxx9K?%Cq3z2%;k`S!&wRW|AfCSd;ms5KGG-y8#*2649)d=?>n%et`B^$?UK9EttG3 zvGFvNIgY#&6G4yjPEKnos_JlD_(J!*{k?Bu8_T&l+-gUGum4+qfVsc=6@JmfvVfVr zxiF2jLu-05uSNIWA&*qC_APyuV@i{lH-AV1OAm46aL#6GHr`l-Y1X|Onv2ESm&M^u z?3;RJ;HBL;JfHnV7fdg-v9Utvh;^T|!QVvrPn!2VHN`T%L(mOzP9eWBnR8l%MJ@n~ zLMs%8QOls1sc4PcSUq!{`7MTaV#|{$NRl}F>mAy|5FavV?#s7|%gf+5G3c#(N+~Q5 zp5KP+6AY`QFgEbutQ0|{^!P-T=#MDEH3~#w$6&=f#2sh-tP3tlV(J$>^-I3GxNM9;GLTN!kwH4{yqB;_Iospq5_7*@XyC?t zZw(Y2s@^HL$EA>B>BV&x=D?lBxYqixaj2fM^G;uNvlRUe?If^xU)p6 zA9l27|Id6&so`RiO+J>}R`w=cl}!3y1}j`ME%^FqitQ*WZk2{vaqoslVC*${shBNp zASOB?>{%6M&AE{oZghz|5CE%+MI#`T0|Ixq&zx}>3|l~AJCDisOpjn@1&0NY)ChLh zqqaAwg9Wlk=_JJad7;j%DHBd|->sfo&73(MK3ARcmJ_6TOm;v6vl!3UMJg=^42e$cDM&+RAq%U{Kvzts-B#YL zTw?0PR7&8DRLEsS%x@~q4zsPJFwwUea8c8m&*egFp}`O0+J>}IP-5IsKhpo+e>htI zEg>CQx!vA_6R;)qyAel9uYnbyIa@FnE5BL;V79x4pHM{=3%Ww|Jq2RTn~cwsTr+Iy zOVAyWKEI@$d@P5YLZ1Ve0~?rTPmd`Q#kK5#__AI^Pp~oMDszLZT0i>Fi+rQ;0TiLi zV2x^Q1ToCI65vj+0gd%wBYBE|%rY@)gSLaJ**k_x*bpcQf;R4Iz<@vfvC`f&`Ammf z-O#oznQ7B3w+s9hh!8g0FrmoJE>YPfRRP6>VG;7PiF=1q#t$&!x{ynYtA@)ov zAqRjZqUt7v!?AP(f6*KprGA!0{%@u<-;^JI`_KI;>pHOfw$*@(H*x!L88F0epj)n6 zby1j!p78Z~uN()qUe7de4-32sra;H|7<(`EkD@SE$5 z*Np#57(VlzKlOvw9X%s?53UztGY7-0mh;= zdJg!@wF)0<<_mCHIHPN1dtv^)q_>HBC~*FrWGv~#$uG!0`f$!6o2U?K7TqY$PSk9S zM}rfK>>PI7O@So{*!kXO9pdxn+&(;Om?c$+=-Pi4<$bM+HURKw#pL|y<5cTR(fFx>K{<5v8Ljt;mA6Cn? zl`_nJ-~itGKap|XAsPS4mqV4<4Z@1v%rr>!H9@#mQqBgm&(yAZ%jxYm)^?zG1pBu^ zB{<>Hwca7%WY~ifdrP><5&}_HQt2E?NQ2Osb6`qLeT_r;2BfDoY>^`2AhUxaYdOdPg{ z*1J3GNd&PVZiRhpEZ7S)ArYD&eqa^<`7F|7;mf7LAyCN zm4rN*n*H#jM&C$$)mNPmS;}z4wZ2E5$}34!yEKkD^!SXWp{w>$*dm(M!V>r<#u+N6 zZmZL*(IJ;-J~@zFH)VSUR2sM{Rsy4v?(;ZPB~4ulH=eunvJ-c^lc|OB75#A+0Ey>& zsoW6R$3&%jKQA6_r~V8MgFZMXr%r`Dg#MLCg$Z?H9i(Jb?TOVWVp16I@K*&e@Xm(? z4T0z?Jd7gYOEN;80>$KNq)nT|f=Aq8y@CPFUSyw4<1y(-Q-ue|M@corwg%@k|{ersNNDub=npuQZJJu*7p$p9+Q^_o$pWNJzd@~a6NcBFaVo( z5|CorGMj2g*AMP>7~M^Z;x$`fxcQ`PlRify?Rw%^Le@W!z!Er%aNzhFwTQRMa3_14P#(+rAn3H6E`D66;7%H{|w?xEX zz|TF1sJ4NlnJVxajdma%%n(pm3HjP(V8gM&z)fOOB1JO15t9|RC68sGOo+*Y;at1> z8mrqiKxV)%-1U+OOvkuM1>oUfE8fRy1O-i>=~*IHV|Sh79yZ^HO6$5pJsYLa#Y6|b zH#cw)EdrbNQu9=8P}|#A0SlYenVD&u5OzrFC?^ImV>{mlFgGZ5&z$E{L*mtY`iPjE zJ|{3C%n@-EBm^3a>HaUB?6D9t1u+2|-fJ)*ZS;JaS&vGQPOx*lqVwZR~!=oge|f*SyO#eB~dKaxZVA zALvbfrG-1~$0bwacaR_2w@7`yAV{CI1zkbKNYKfHzWCT{4JKwT?`soSYhMnFPFJ#P zJx$Hanw#29f9e+of6cEL+CA_vF1x}V&))a$+SWaF&l%7B-+HzmiS-QW)$!0ky{@$u z_5~ig%@}}6vxk#w8T?16MN4()2Ee_B_s=Xj#tT0(%^U*kOVyBsugP4VWP%fc1q0;m zNF&2jELtK8Cw^6V+(z|F1k6K+Y_+5{ zklFFl=))no4h)#QUZD+%{trAw>fvq%S^s(Te)NLCYuQsUnC*>kJr4UqW~)J{O7C-| zRGCkH7-JFP3#DOEA6V&oO=?-uVv)!jX0 zj1#=gP5V!VJ98ey=v1`KNxDyg&FCr)#~-P5q`FitjeWA9Nunm$1*oZ4rWMl<6-hXL5dCV=FA^mvRb zfhqxfKVD$W$q(Z>k(VZ@u#g&ve7qX>3;Uh` zlmwkVkqWY#kXJ5gq)%bL+xz3`fhOQckc={wjX3O%r(VN0#?ic*v%1?XXIspF_(EKaA2p0q?Sl(hi_HzD&pN}~!vU!>I7M8@R)Oy!e^SJ? zNSA70bvhc;uwa^lVXZq$WvZTcM{hewu*No;Szac@x$Ok=#|bmqfn%m!;Z$n`7c03h zy;a+xX#mZ-`ZlUZT72{$Q` zGZnL6^Sg;646l*SM6p!RfQCb%xd+~>ADgc42l7BOF-`eJm-fu%JW0)iZa9IfKp5Kg z{^yp_7nrW>>616S3#bz3Wy&WvYIK3|;A{=LhDemqa@9?7&!}F}m(lI;)8ykp$&dVr z=)abWhOn1;mEUPrZD9&G%QoSai1qN|T(U%S+JmRui#0yM)rc26>(4fv??AG0-cJ^6 zjGYzEeGS7e>Z?%S0^lUf^rt1dg$-hwImcSjn$f34U&2K7sg2mY)5vuV2F6Py#^rMN z)rZPFz#JHH23sRU--yPUC=;hYL`fD)>x3_p+{GqiTy zCjK6eYAxzY+$cw8Hd|0&em;})={GSuLq>(Osj?K6mPz?4=bkz~*b?`=LyR>sL;Xx5GWCP>6rkPQAyS+yO}^@~-NW za^C>W=Aqru80)9uN_#kRb16onvn3;KCaZ?rXHw-#UXK=MiYODhL_)P8pD<>B$%jD8 zbyzOV3Au`dqrGEObuV{|ei<<{JDU53Ii}g`n?uIg!Vs%M<;F_pKHi!r>v90E1U&i+fSXCe4R>TvQs{6lvICcdwkt3lMv zQ!_Kov@Le~t_-Zf&_eq~N^Vuslkd3(yg1I3!U5kW$VdNl`-H`!cpp!566`I4TkAZw z99k)yx}Kzkl!Ryj*RdyrN_}FSG7^c{X0_=D^j~WZkcZ{Li?5IO%2eRSU#0BP+}szQ z%1d%`1D0Z{!TuwD(gtC+$qjzLavWwx3o({~5k0J4&^52DOmxoqoMb)ao&LuK3E^(sc2G2#Qs}Ko4-ff+Kh}$oN@q4KCH^ z^)9{58qan^AIcSMO1HF*;+;G<-qoa59ud-+)^mD(0vENwwv7Q(<-{K)uY%Y z2b^ry7NwIzQm0%i;`)wmssw~%fDe!mK^*pH>N&6${BMOQjE?(xIp6kfSD~u$3z^=n zY2x&Bj*KlJ+w(2Lb?4T|okly0ix}8J{lb0hW_ahm?kfk_eiLDSt9>g!gO>HH3n0>4 zu%Xu+#HuO0}+v;M8 zmub-r_9xFr{ykjjl2i(2uY$2jhd-i~kq&Ymd)_iJQ9vY5Fj;+SUw+Cj&6@I~n@?}U z*;Er1qth+@*;PxpDigX=41S|K{3D(#Htk!@BO{8?z~pIkiE4`gtOB7^Pv z$suSwX}CU#wVjK|_g5DukP@fTO)M~ELcXR+PNO^9+hh)jW`}Z+h8+uGGDkgCfwE9q zc5I_Y5*x2>zx|jmx6(0^wI&)p`dz>zMAB;sw4% zYVrb=((|n4X@Rjn2>iOsHqBHhtYz4NtHEkfmm%cFuh@2Wq{PrzW8X6M1p5)|b~)Nr z^nM(B1P4u8>vRfN&k*(wa{?u2Pmecsk3=dOZ3WukpsLb%s(y9~-YQhC9y!cB9H!NZ z%CyXOxiHe=MlrTg&*CI^$(vU^ql92tC|@IV7kNUyU_S|JLykZtd9}N{a!{>Ls-o1g z#(hwGm{}qQeJnNIL^PZznDgb(ehI$B0CLr)I}WiJkqS*+;tH5~Fq^7411oH@jtU(x zS&HavZMD>q#V8$KN#Oh@e?Y)$fepFF1;!YHaQ5mBw1v7|`u*e92z))61JvA`P!hHbF2U+RpB zNXTW~Dx}&}!Z&``|A1TY!$3qpa$_ULnn?3Ykz^+P^Psr~42ZkHlXGMCoDJgk?%+}V zu1z7iYkeLxpiSf@Fy?_SGVi&bub?8}XXXc0I_>XIhc86Z@4@@TdnX`7($@L&XTiU! z)tuQZ)$u|t>^Zf;80~CFfcS4_5bhn;c>zu;(1WL)9f8jEZzhJ)*H#r}NKEnhA$QS) zBF;^XgW8NxR>(WWw$DBdQ01L$wJKUzDD?^j^A13cwzS_78#IB%4hg3GMic^gl)Gb{ zJ|!&38(i;XcMJqT;YEe`2fq|$>HNCnoTrgiDmsocu2uw{HN3544w;U%gmTZ!ffNy* z=By1tLry9U+L%K6j3IfGqu+#xb`)E=|KY2Y!_5$B?o;ai`>I2a-BpM*T~!Z4O&ycY zmS^}g$I3JjD6;Jj06>K9Q6_GCEqCh}xSFjfwrpPB5KJi@c|0y0@W`|78F~=m;{_gL z=>XUMgXdKLWtu0WhH_lC@AZUe9iTA6fSW}n%MB2Rz zAIOLS%wG2ez4r=D%kRJ0jupc|xycme1w0^U{@kXxlD+jawRaIHMIpA2@!5J2NZXH>xTdZFzm9% z-flt*Dz?h8+-X-Etx~8W9?eu zdKPwRp_83(_iu%z=PtfK^vHC_?S_TGM4o`iiQE=Pv1kruW)HkGv3MR{*WQFBAA?`rP=}C)P+^Ced}J+97o)I# zY14+ZeCHK3o;w%7EeK$XuI!@r@ua+a!gY}o_Rw+gJe*OpGgDVbi$|~vm6|zlW0B0* z&?7RywhxgoDMj)8p@R^bqy+_^Grg}CK2tfdOLkR0Z$~3pOuK?H8RD@?AdxMw{-&;f zZqZx0gcuKK##V|Vfj>AxdNHBF_Yi8sv9B4e20BxnM4#s+tXT%R()P}_9!+H~1+)~A z`&%Z^?)pVr4Aop84B+-qcz1q-1nfIgD3?}Y>!5h$z_L8eZ%f({0Fz0d10p#($nOD> z5;heKN7ajWUSE+*M3|tUMh_S7`BDp#!QlL3n{DFWh>0?ZlSFN4=O+Dkz!+HDbnFBS zU{Q3+Nj^_ss#Eg8%ZVRps=JpL1W8^*^Yg@*ok1^rR~13QuY9cXDuk(2~MK! zPl4;9$}0yiRBc)=6Qt0rA$&x@n5^V(l+jyW*6}<=h~d3h@yEJ0EET!*qv~_CkyF?h zh9idydP*%VJ#)(i5lk5-@&$>=DJG}n%R|uiymq~s7fSIttw{;@8Vsi? zk>&iw-q(^pMuI6FOl5oqnAW_`To-yA$vLXOM4z=Pvx<>WZB#6IV=l97N)# zVgW|@zVuNt71TU^JIwvVMnm!Xp6;zjk1{coaFXgp<73t+Bcmp^96XC43B7o!T`QGujYW>H!o195cgnww0Y&`0* zit8iFEnX?LQc0K+Kke|hydo5Hl7t&RFYP2AV$2EXd|C+9#@W$TW*97LnZphqd$-iR z4j&?g2`tb5d7qQM?CoQ>m%HoMaCWIrx0+yEP~U|{X`q^hQRp-F)Mt;iY!RUx(|EIQ`gB>nz*3$vlKU*3zuoxTQ>>A za9d9i%g(?C^0_kIBzuhJ43Rsiu!2@i-k@9yTX0ikovXW1YmATOAHcZ&8}=k7V#|1h zkalM<7&ocPw+*ZphOviP7{i`o8?gjZ{CtL>H@S;?g?S<14~Hm`(B&j!Tzu$9`a)Id zX06}DLy$*7)OkfS$EYcmn4}{tBY#>Q3AE3w zRLv*ah#}&%h1|(XYsC6U#gV~NOQCw4ihVUw@mQT8Ho|z@H~6G4P?)eZQD&3R=kNyc z%??j9%$svN$x&l%DQondEOuGV{1G)$y*n;_iVd*4kei&W9Ds?|Z?Ec!ICSrWf|2)h zmM}o#7%Q~)74VK@;eu6rWpFbT?|OVKsTUhl9{89WzQ_Rezj^15^4nPrMyo^6)p&UB_;+16(rIFA`HI~ohQPO{tNvj&V2s2bP*8s_&2Ls27 zWuk;&&8nhCjAz-w=UBxZz_Z4(D*JE*q9uQIJk^ezGosueOeR~t*#KRly+XYW)>3)3 zXZ9yz$Yce@53b>OInlK!>C`H!)WkkRCxiOiMspy|EV?tacMvi?j#h|);Y^E0V9U2> z*L%W8eb_Bb37-d!G)44KY5g?{37)J;U*B?smy<9o#vpIC7z4I2BgoC6L%q9i-m}Xb z-9d5sH>asrTKDeFvB9=@9OK?x0?5v{j&jcZdCwZ}%UfMM9mpP^XC{WzJD5oX%^OI3 zroJ}|8L_vDbPCx|d%KRto87!&{oRIsa4zJOv|>kVe3C)h1>CP(le~Sc&P1Lk9CR=N z@`@tPh+*}(;_%88Ayd=7m5)*oA;l#Yp-=CcZ_erN2B0y8QR?r!M|+1X!yU*TDA!)Wo^u*!){&rn7344!Vp~ zT#Nz=Gt1r_t!?i}1*XcHC)OOp>N-Xs>~h4EiGI4NFXikShkdG2kyFB0K^ht~lnvUa^y}IT{OHjwDDe4Jb?>v!6#y9<}d*uWr zlMCa{GDbLomsh?YJYg--PRhGP#{J*j5x>8vz%pmSF4w+1ZsiK^7LkCXqnk7E@57yspagCnZox!IID8t0|GrYqA) z%IkfH9aI*R>=cW4JhZ+uc3#UfC(|I-?F?qP-~gs}&5N|}5xnJD&mHv@SW4mjhm3o< zq(WNlQGSi48LGsl6m&(g+J_I<=Vm+21OgNwK^06hd4PS?L@cXp^r+M^Lwl#kWezgP z$Zhpy8z%AOXcdSX0AM3A*GpI0@foSvujZ*9EDa;%TgyW@@RQT~YMX;FRhFMq20yPr zY44gxYr1?85JZXkxt?(CC0S^$n-|Z3Z#1|EK;e1=+DXDp^pgP3VWhi^WHXQy zZ5^$3m)RZrCuc(h+)m#P41OGm{xP?k2VR*7BJXZZi`FORBpN8NBBf~;f=1(z=mf5i zW)$qA8-58BGM(&;QD3N*k4(nBTyQBNtm$sB3}H~Z%vEvPDw2i_|F3$_uPVLP6{Jiq zb`8%E5lYdC-9}$)S^@=0Z_`=?xdArA|PYc|aNv9faL)7pJ%T zNxf8;4?-oCgYcKds*qh-0?xs$C{g$P5-+r)t6m#9a7j50_teTQ&<3tu?BB&Kuj1eP7 z7_LV-hsR7X3C`uj*n-B!Ju&tVwP|5vh}O8;i7AI^Za-BoypfSZeY1O+T3WDukf-M` z4KlJrLwH$kyVrKqTTR5NncdUQJrhAVGwrx`8oT`_&1s1u7MdY7ICm5fLKh#Qzg4tR zVil~=qH*Lhi8G6I#$hYaWK(q)hgB3pC4c7)i5qt&#H!4ZN99zm8Vv-Q>sHvbZR_kWY{iat;h?8N2Fb$% z?x~v|{1NppD-^h&hhdw?I1X6x)Hce3g`D2((;g{KaGsjri*NqW>6KB>HZh$4W5xuI zVZzHg`q0-Yz2}N6j-aeqle1FFfEUs&lV9M9M?7bhWRawHq+j}zO~-CsBcI_)7XPL2 zl&AvCnuOJzw&i?wKgs>vj#-)_7(C{Xg%EQsWv8d%>%|2m9t$xUwXluAwFLg1`uELo zDL@$`?JV1giH&I@Oq{3pu~vtpM5&_|D9)5XZ*g}HZRvQTDi=iq>mKp?Rz9a|2nK4) zk6sVcZc8CCb5N94`MJk9Y3K<*1GBa0Dqi-ju5YVqN!^oe`-|S{i?E?Y@U!-+*Aq4YLLmumeq%OI!$B?RXa5{G6dmNvSQz1ox!?~uK` zp7~?5rop>L=!QQn`4KuJsCqL&J}zC}z|teiL7=&CZ87tShnsTQ6-|p#-BzKrXi{Z? z5=QDIv^311+kKYVj$~mFd@2A|P!oxSGC^ zwWhU$D8e;m)85^2DHFl&cp@|lcREOzCPTu`1L$@5ir;Fmw2Tpq<&~Bf`vzW*HW0-G zLmTbWt<OTi<4o2E9Xe-v|4NJZ3jC;WkCvrgKo;C9d zzgv>5mX|!=#{xN@qsrZ4^JvGeH^DV?vR#?vt|wJqYOZe@l~J)f z*R)MNh*SZ-ED{$fPxI|sAF1$Xy?m|ZSW?u{{vI3F&V0k7sdAfY<@q@xs(&t`Q+4o} zE;fdP5M$S@qf(|LfJWr02YKOPb-xHPY~A57&^5xnFt~;D(kzgA@Y8_h@xoX=_dLA+ z15Nj>FQ)!;-l$;LiAv8s^Q&U|okp$Dmv4!L7Mp~!Y-4RH?v9r{NEwo1+#NNY>;V8| zzfFsy6G)%50S&Rl^73kg8V5W^rnNzuGJeBPhm~=9zjXKu`=#EfHSx;?jf>N;$Q^92 zv>|yMG;uHW#J;V(uP;=A+4%oi`A%Y=eSGQMXRf0%OZQGwOjUiw-PB!^xR^fE6=hO* zTGAneT_~?aeHi%NT*Ge21qCqBg7^RrJzQdbrqz3&u|&5GB7xybD|vo7O^TZRlnnPH z5Sh}_i5t{oR=o{b{oQmaBblvR61IEys z!V7myHY==7P0}WCIhM2$8e7aixz7y*RRsWMkE!f23lBwYxn&StU||E=$H;pN9`0UhLhzGHh}0(wzNp z$o3z($=yvkVUoQJNMlRVD~wAuv5o{pJmKE`Zr1wpKIrtAykqZ5j-@P_l#L;&L2D5%0wLJJyznZAt~IH6Ttm3GV=W0Wu5bJ~dl$7^20&d8!VW}f~Ak(~mB%xw1T_)pC~yBRH;}A_#?W`u{lQmY*yU6c(EL zT6+aCJ|MqMhpM`i&D-njDOgTJ66pB>P{>hwVG`->!qzU+?NoC28w`xJW$Gd^BJ0gl zX7Qyo>49|1wQEIjX>Ek)#)iq=45Tm;2tp8R&1G!;oZfdlG70aQCk{$-1C6z4plA2O zuDH%Ya8BJ5%RdE9^t_0eFG5aVKFciAFSwGs*p?6V^&x|f8zr|=r*-4f0XMQ?J;zL}>m0Pm&BFS@+wRn~r znsr~YYm8=$j=|yH)?_i^dlJ%xk5XvtfF?c6o8wo$8A7?;eJfjS8=jWeb%TODK418$ zHog?c&YcB**Elyd$v2Ci#x4HG>e8?TNdNq`XH+>oBWMeKm-A&HqWCkG(e%f< zZvd4x_A}9q-tHdyV2)l)aJy4^$(r9hQ{**=!{&|-8qoMxD>G3|eM1*MZw|_avc?JX zFTr09nqGaK_x}k-4lQR+e5faqlt|`doER$R~f!ljDMGqfIwYZ_6OFq#pn)H z-gqO*IgmoOixeUTad*}CjRl>*{y34kd4(`XCGethRg@}<$SBCEBdhRENiSGaHPN;f zfx;yi*>RD?fj;!thn`n>_kByU{gI!j4tKN1ASjdN^Ako> zN1vF+^(kq&gEj-9nzX4-*4icFTf3Ft4>t<}Q3KHqgzw#j-L4QaWdmjKjtps#H6}Lb z1xDu1Qcbm!pX24QLsv3g%GAk;E?WbNf_NcoL8%I#;85&x0cYnNlH=rqO-s)KH!n1X z&o=iuSEGq@51a;qb$UzKL_qSz#3H7d8*?wM3F(Ay!^(0xid9t#%`;K&TQ+xWv`Vhs zz3gR~L)MBGx`|B;5ws0mK6cAUoiRXh;^e8>Zah8FZm+p0aasp&tK0Zb5xn3O0YgpV ztz9azSY`!KX7(>;5z*HLg|L69iM>JEH6FYFa2n`kmg!I!e@wFCl_vH#35<<<0 z!xCa_i;59?TG8LL6Kg5X_yfAFd=y|p7xsG$w_n!5wWTYupKN6*<@AJw5rXkd&HtGx zQ+q=MV8mi^cwj)iVi)fi)hc)mgsXT?U1l*dG0+W_&KEqx&n{V&AWl};Mr-TU%NjjAVl-I{V_3>#z z`}kM29t`u@u`XCMzOg-F#>xTZ+F*}|_nNhmw2UgR)E=CdIfI!>2UK-^-f{-PkF?$r zL-Jy-=j{HnlRKe)9+`)1uM||!z&AN|JO?h$m?eSa z0SpIuPR)Wug9HbrQn!|TLlWV|5*Q^%;Tk92< zVp2SBOY_WtdmkNG`2N9+JLA^{!`7+V&xIUl)@>^WFke_X>iU_g1P}$Uu=g@xjpWfl zGS;K=x>|Wyl6CMp&a&=iKI6VkQ=PlpMeqsh)q^=82B}0f>usCaq}ofJ-aRIwEzgcV zytIruzgB!mP_@OrgkEEUUx#-}r}kzCLTa$j8Lw;>g?NZNrMyDYOy5yE#18eva92R~ z?b0_s6bv!il!t5Cj1@ttz$#(WQsA}Wy-%z&1LH`aihJ(1Ao;V$ZKASoyUP1qY=PeJ?> zK1_dPRW(5kbj50XH-bUEXF1t}`hSe!pCb+A9YE%8lwIt1_g=K21N)#3y7(wiJUB=9 z?JeaCsCvD>emKBj=YFvR?@ElvnDLbMpir_4d}az_5G1gnX#z8OztFYI7a&yva70_I zAT{a*Eof2aUmML#Gfe~`{RU@(V3;3y^eEt{80+k0J62=d-dmPleY zV-P=M>qLae^>i5nQ1^V&1|V*mqBpQ;crmsG`pL~5OuaL=^OHDzUjT($5P!r!KK^3L zQG=Dw0A+&?(|FKP%WyP8#ySMK5R%{t2C!zEHv)|fJ}<==YKMJDq|8+ydv^!VL@$Vn z%<^5PK4046-qL@6w~$k0Yk5LaX~x#7pZOWSWe}N3uQo{=iameZq8hcrRkGzBlEN)t ze6<2MdH!N)cwb&8GgDpub@t=izrV!l5#>xsyhe|9{(-BoJbaOz91F4_?TX zqhG_-Yi^+OFY9K|XlD?GWGC3TXaF{)t3KgFWq~cZ4~PDtQt6F?I?)hPG)R0L#?bzt z8j=TySDx2ipUAM2a|0+gj3tZ@P7hlqSnXUhbsz{4N8v|>N9$C-SmV@N`Nm#CSmv*J zW;~^%Ff-%6AxlD-Zba8;!2iB~#j{UJldutp&o;6HzA#d8APpA9yY-S1XKFQO014N| zXRvAn89u+_f^>KmX2Z%r z_r$tqto9eoqn0fQUkd78m)ywtStM@73j(2a|3}M**&)z^ zWK`esXJSAz#|`S3s+Iex4v?kURDp)Ao}^7S;dk=m3RD_bonl@N0LZ2u^F!t!4Qh^% z9Zjq+pB%R^>|B|6Z#(DUD7lx#YVsGt5v&^G%2!Eb$j4?wjmW1C{Lck1u1o&pzMSXg zs5VIroM1T&{XtvDq@^&4l&i*;3?A~eK`p7^;G$|Dsr@q!( z{U3X|i18H9LdB=24r^|PvV0?s_O9MM*Ct-xF_gg>WmN-ny4-1%oSlwY*im7hkMt=+ zOKNqqOP$O{(ry4rPw=dORlp3t7*ch1JFJp}X&bZ^<(}RUFfa~<$N8?jp07*pCu^l` z5x&T8#VLMzcyn72vOKfpT&LQVGS2Zry$VC#b=cwKG}5eOYWg zs@d2DLw<@!-F7zP1xeA5-$h1a{};4U$nH(`bY;fM8U49Y$jO$}2Gj{2t8E)5VSrnx z%VLsR8jhs5B^j1u)x*i$1cPER<8}Z|__LUO*6-dA3k6cI)YFnDE@TA?J?kS`n)M)kG%bXGpq8ws-nzKH<6;JOn9(U_-`3B{I1wOR$N z9%cjZsy)I~qr@u>qvVp-&_t#;Fr}=*$XF^Y7-)@~PnpnFLG*+?Y1%w(L$ieyAKO?9 zaWf>lAwwA!>x16qw`iWZ+4e53-H0q0*TZs)zORk_%`c8VE2JP1od8ej@Tx8Io&6De ztSn}91Le$cpZm937Q+Q$e2jCe#btrHyX&+GYem(Far*SJ$u2S7_*H2%06+}l152jRM~s? z!_WdgQvI&!ZDj}Z*)nFqW*QiCh5@e~(a_Ja>Qp1&@=blm{{DR(EE~3`dY+Iv zJFsl9($UarluU#iMXuTwsV-v~CiZmGZ=0M9xP_nVnY^q2!*zz`I-vRdYdu=6Mt>I$ zl((cqVN`Z0c;rEmzNI!f-`vcOLO=*nCa_aow0anhv##>s?_*IqzDzC7$Ko5pK=XoO z@EZl)9+Y zBss%mvEONjg+}Ahf>Rp8@j9#Ddi&>eNvZE)lT7+B>Sd>4GKh2%!IAO8 zA2@3L4ajeY<`q>Y6NVGH0hlx#EgdkfeU1lxP3iqu7{jKHhnO?WfY)#bYD$;yR`Z?t z?{BDae_;n5olypcN;RIVEM|>iV!iEbc6?{x;ck$0v8E;s0UznKFq(ch(dw6)51x%u z)Rs0|Z$P`AM6_=16>#rnf%UZKX|O;<+;AREJewIRm%Xymo0zON@dZfST_O7yn@xG1;XgUG5mc*lL7&6)>sejt*9&PkBY?^CBp zDrttHUNz`_5V&5ZnrUw`b@NK@oCaLognl>xXE{Rca@yl-TJ*_)J`UPB`hzTBX@`Xc z{PZi-3ay69)$o!ZLp%EKGq{=Vw51-KK zDB{^RulWIi&a~%o{gU`rF2l%+RLI9bc_#)KN_&Vu)=$)C9v_+%8VZ=l)+K{Cie0jZ zIcR$yP73W28h4w^wtZYStOp051<#O=KTE~=LXfmVCZQ~5#<-Y(io2UZmOumm67HEmwdSn0=C6FPKvhS&n~IWEEm877L9?RIip7sg5kqL5zwwRpj{~J0V<# zjX$PdL-RZLd?$#Gr4`B!o`o#I5>--1trT>JelK#BKHjyjrEUoaY#jvf44Qkmbda#EKuiABlCBE(r{Y>>OM(G#1 zojpsBI_XKaGMOjhP5&=0)oD^zAPT=?6g2z4mFWJlpF=PL1D>ejXk^_t{J9T>j5bBv ze2bS*!*!w0^uk8ip^U4II^O4=(jF~~G*NfEo;W!2p(Ng@#p!L+9ZOR0Bw%ACW5BIH*6{$&utjT?kCFUt(EP4;NWjX!-_8mNqz~Q!M7fd zS7G=*>eom6(Aug5`3AeAfM|)Ze;D)9>+VP}Y9z>UL&H$ag=qE4L^MOHE>8j*BTwlE z0;2jPS8z@mcmtx{Q&55hu@B3hE?5L&$gFWORu9K;GE>@7!xeafw&-p$>p82sXUx2r zSct@64GY2gZ$O0v-(MGL@x4Ts$YL2uA0x{>7XIzM-qGC+!Q@Iec$h`Q6R z+&h{#iKPkUyYl#5rS0fBd+jTb)@;-IX{X8wgB6X~4a&7P#MCk|mj&5m({5zbz0ucT0cw(>RwyEaZr8wsDv z8xpVqz`uS!fncBgR)JKRD}Nrbztp$kd~x{za$gXuU;~{K@w!Np932q^K=$4{?`%i2 z4bM}(MSjZa-r}DKb-*Qg@WiSR ztwBEv$Fks1-s~g^>$TIo)89mG$nkmjGq-gK7z9}l6<+zu;HfI%8}LbA%A3Eq!$12&{i6X{Q0gJzlKtV;87a``QY21W>aYqb1dV=*sJ{YxK?Av|Y;-Kk}0#?ZJO&0xj3JL>7jr5c!u zhqrSnI%+y~zodC&%amx7R#hI=VcLh`DDb6Zn%AI_{YD^chac#kewD;v+w|f-vT91_ zMnB5)a<%9NIveZDfks63m!Ns%q>8#;8*TK@d=h%>-S)_Dq z5=!`srQNdRt=-G@&77YKLSKWOrcb^Rbv)i@Yn9E<-2ERK6agn_ubYC_t|^Ki$nhVz zsiGZ$yBXRB<1~BDnLJwzn~OETY>4mcpJe01zc<(R->oS0*BP+#r_^!0)1wJo8bvTI zQ>7U%uwAYMDCQPEb)U?3#KNHa|J_WZi>(E7Ch+e_)g>a3cp?49BNV*t6Df8VrjrS7 zr$XHko&}?~NQ8y>PVGJ0{Akkb>}e}tIMJCz`C!vpp5!K-68LIU-gbDWXt1>0Gkc12 zprv1rfeujy6Khr$kstMIXy%J)+6tVpbdMafzfxJMv9>ya!UR+jMxxar-{4mt=r&e| zzsr3FY}Lt5%11{Lk$MypU0p`iI^?8HnL1RNVzh9e^@`dBb@8R4U7f^#gNj=TR1Rq< z?`Het#N@=oNOCXa7@0#t?_%BB#eiHAB`)jbcjfqkpC#x{q} z*W|;V!kqSX)tYJ26Ny^sDarM2%ms%EVM*7ecF?bu;4hK%MQ~c&p9g=20;GeDN^Sfb z*qg#aPs`uS;8nDb_a}4Ne)u|EPbp;BIr{R%YwK0R6CxGg#gT2-^AR)%&gH!p6krsJ z?M*nC6`|MmE`HS8|WrP+| z3SN>R*d|Mtao*A&F43~KDQay&03baB_(OYFhfeX1Z`1T_Y$^7cfvfNz}d-G=jwfQDA!Dd|vuuBdER<+=N2#kj1cQzGQU6rO^=2y$FsK}ao z?UGw~MtNG%@^$c-)1ORoQSIf(D%L=L>GPeNSV z9}#bwBXw|i8q&Cfa`pB=NI%Hc<17eV3@WgWY3AQcN|l^UUI`?_&`cl3hN z@-nF-^Wg@reTV7i;K6)!oZp6RT#8XeokK~7MRof?RjZm(@iJcCi&9XZxO(LrKu^c9 zDUi&VnV?P_LvE2_ocE{qLx~lPRwA8dtZ^CKx%ktsF4ud*qbW?ayY|1yw+FomnX~od_+rHT_LKe?JV}}qZeXgmD6q(^q z5tx4I6r3*N?I0C=we-mrFpYd+Mf4-}+kua3L9eO!QNF}ojM`oYVtmHYu902^sK&+o zw-PRYh3~y9R#!5uJ(pW1&(r5fPMZ~&ceFn7J{%#inBr;f*eMW`)yZ*>D81v^RP%DS zh3PBYmQqt(VN{k%^*`=Y!(+*36yG}jMvA8F1`O)Bf=RXQl=7^0)rWZ%PoXrBj(Y<4 z0ly_auZP+QXoQ}?@IZymHJW#Un2xc1aB4r;<7t>=9 zWYNZ2K7w)#NL~k=2cSS;t8|(G-`9QA5l+rpuM$t^5;htV5f-zls5q;xUqA5{0d~}RPhgSq1MO9w1zGI zFpJ8v7$LyNePGWnC9tF#C>g1#6*68Si8`5IP=+@<5V)nSj=%hjh4FS==S{5VA+tq? zI|ax=^qGSwKx;5JG19Z$Lpwk0P*{B+#yHA4sAV zp|$lEaK$;!L!$}h^ow^GUZ8iQq!%ncP;)P;U07b+?61mhSAe6{lrVe|b;P@!7{OXt z#{^cfIw4g8>aAEAa@>6mL1G(RNS8nD*G@1W_1?uJ^4B8XFFt?)7uiEyCB-*^S3f#Qmj+I+9S zZ9)kfL!J31hr@(yw| z!lMyhXjrJD8S}w2>N!dNQHQoMYGFs`u}0on_mc*va;Yw!F3Er4vWB$D|2y}u?~zBs z`a%j$yATcPq!Co9Q{Kb@-p4H;7(jW^M14^m_S|o+qFvd(T@hEeXbqOFvoiOY%nk#h zd7ER-?)eP;`kI2tL(|nG`mA-nVTBmBb#jdt-QGWKwCG0(;iuqC&Xaq?qd&lbA#do; zXkp$OSV(`guKj#~V?$c}`T0$>jD;r>PkrcV!+lp{4PVlQP7In298KRpnielKL&Na# z78cT zj4Mc%`Gq+db0-9*Rb~~8@kh;5uQ58=`uVKAxF_JMrDBDjyH2mAazdDJF zn~&rtpO9y?mI&7{o~Bbd(VN}^HS@6LJIUIaYya%;1w6(L>}V21F|5f8ob~GM+KB9KZgbj&QfZ+R zQqRLpm5A&gQ-N=+Q(#CSnoWo-OR#BQ2l=NgniG+RqL?75fF7!jygWToG(B5@tICH!F0`_mcY$#>2>InB0Lynf=XcZ3Qzx-m|?*C&HeK@l33ef>i{0 z=O}braNNL849_}$2+S@W{f*gN;-{Fw=u4KqC)WK6Suit&LB(UM=h`N{&gY#_*DYsy zp#>{+U|wtlE4t<_CCLEL@TE^8Sv0sqYqw`5ng4Ycu@inY9YUjPwVnQYO#xvS>Zmchg7Ed^^nqhx=S}R8;D-Lct7n!Ku;D~DZD3` zhyG$#lOYPq!6BKmGP_!NK&$Ei`00=hS-oz5bOBIjI*ueAY{=G=%5jzKta#}kI1QrZ zGLWLL?-d5tQl!$9550zgf)blL#0%ewU&cGM6PxSpEe1xTzPsV!lcB3d^U&GOw)@c4 zw%!cwkQi(pMzA)g@hQHVpwI2ruegbugQ%d5Ca;f3X8a-=z|Z)QSAHd5cN&+i#uQP>m8yF0u>^TlF zAwl>q$BtY~+9FAer~8R^E=7=R>u`8&ZtfCnxw(z!^G$}tSV>i;hOapTA^NA?QGj`E zTcubJ{a3St<_#t6Ron`1ynX$Y7TsWsLXBQ)QUW3I{PG9a3j z9?e={;XUB-7Cml@mLuS*9U9*4#$&Zci+FLG6o`3YXlu`a*qo~SvB2{=2PRg4x}Ejs zm6@!N>gVCf4M3EGSkl8Q&K|BRruxT;M9boybTg`OV3&Y;1J!r0gAom%(hD*O!od2Z+G5c`SOIlcE)D(y2wI z!502<^Z_#DQQg~6<6%xI9w!j#UN9>#Cz=0}BLs~oXeiSU?7R8#J%IF)A}^+L() z1?!aM9EvLMJ9I{gPt|Xr<#etjje)M6JU%@^RFB!hnDm6}Flq*85iPJ)a3S>t`>TvD;I=Ul^s|f!4=^BWD6GfcLF4{`ST@_M?Hk*fvc3m+f zO3U@r)4}ZC9!Qzh%aixYEu>~%q|e3`AP}+Qj=4mq!&DT82)Bt+)pEsRO@fvq&u&sW zl2b^crJbbAGDTY7;=ax($g#H%YB(qqW>tEtHCE8a<)Mm%_rfAz*UW-?aZ(i86L#L2%*x1=1vzt5ytADA5_PEpyui89-Ira7s6+lkzqVEO_ax?6q^u@9|7;o-g>1_ci}fIWS_k2obpUg}3SWlTJ5 z)~ZITu$3MEXKZkt>^(h9FWD=wy^LzgtPE43+StK7s?1P@L7}JVfA^>;v0v7A$+fOC zr!5xX6X?|WPGT;?n)8F;MMG#nT2}Kh$XiAWI3K0|=AnVWk>y%rk4Kv4CJlIv5q-$i zpTYN!llm{U{cWT)&pd4QWUgFbqO{ByJ_wFBh^xcuQ%@Y8=IcuG22V2=0e3pTO4 zS>j$~VCB|5D&ZRgK#krm&~^%IV=7ZEIp9<7eZ-16#oGKaexe%@9g2=-^Z*yrcpH?h z&)rteul6+LwnyOF8#YgdCc$Owg^a2GmURu|>zbxNvk(J?B=WV*X??n)T#9W)^vF+X zj?`&_Lj3?){UCZ{SXMA0bG_6_gg;RZ`_ufB7k?vlCF*#2_v|9?hLH-85OF)Wjh)10oEdFY&-af>r?PNyX1qWd7nU?T`CpcK;z*Bt(XgC^Z4#v~8Jz(xKD$d-k&@|?>&(2y( zpRWP4D(yy~t*T;+r1wkCGBqh4dfIgO<=RqauRR+7Lcq+iGByxIG-?*YTbeaL(kaDu zJS4{}lCI$51Z+E(+WkpGZ8i17!ISteCGS4i^1!pTaRJ~55!Lb2R9TaEE_d8l*P9CB z-YEoup@DCdhB?6M~>^!`KG8+eg|t?O}W~UKv5-UOYxNw2dSkqmXcny4)BF8aM-V|nmr7# z?%{x1xfkXDsDjX&_2Zxt#1+-r?d! zxb2kH@F*$o4Uq?%{%Lq7*ZEQLobtPaEqNaQmlND5lO}vrQoxeyN}}Td{0F%v5d+{E zsGR>gl_okD@qKD)vb9Zw9c%Wql=9JBC|2oDA%T`Rd?j=b`Nj3d=#RVm=rPU8+rD3{(um=(n;FNo@-+-Bslr*AUIs>^}Gjq>)ynd&q$kqK>C68 zB&YND7U{aKpWdMWG;}tfN6ybR+c17|fyLoj2R_GJd(+12PH~*;K{wf+Gz-C;_x)C| z)~4hg-$TapCJzAzDOa42;W5dkm=6vo{h(Rjl6wkFLQ4afD(cJF4{aF>B58}NJIFz1 zfy1g~ZA9I<;>1U7-(leMCO{)E`6{#e;^;QO*@>_PM>Zfk0}Rndo5^MR6uM|h{3^Kw zN4sRtKOv zkF0>dq{O#hJ1_X;1<${u6mJ&1Y)&!Pc?r*)SfdLXF-zLZ5jC;(yZZn}ZE#*ng&E(q z&;u@A0hLZ#S(zlPKP_ah??4tR%xY{8<3$y8J?h)1KhjW5$Ho~pg!H`$|L60-r8G&3 z{)5frfPLft$%?twGy%~^7G8W7^?dlXQznFobMt?kurCLm@)F;=z!lIsS)JZzUK}e+ zgt&?OVvy;H+1s}vN}s*J0s-2yOr85iq0l__CvR}IsdU_+cDFiH7~OzgL$x*J4kjlG ztLRNGi6F!Otegf%L{6%jI*XbOs>vsmp)?Rer!~A6i?nR$bUC)%92CNNoF_ zlcx?7D`>@Q7elaE1Z6!&SEoIhxS>cFL}w}uM2DYa*OFFytJ7+|Pr$>{?$JHb7%pn{ zJ7=H@^ASnKOYhGB{UVQ`oS8B&SoxQj6H16s%vc^L0yKT>_J}%kwKQ#SQY|0?a3Uw) zdjBvsW*VST!*!YlSd3+vecDxq|Ld=f?!GMHp#K+%TlhVdSt70 zgab=A_Xl2g z%a|<)Vb2>SKl>e-v06M+mQD!~_FD-t;jOT*d+hnBXt$GB_ZN4EE874l#z?IH%_d5U zcA6?3H%xF(_EO_|c$8ZUP_#$`&3MpViEVbTooB;!Z)z>#w^&gS4ey{DbSOHP8BaWl zhCSqFJy*15vkOmGS2Qli3=!Wvw4dSCCqW48${2`9UWiqRapt9vd^_dyD%bT3J-bJ( z*LXpw@6Y*4;-h7lvdL`wPE=Z-S1d|)Q$^N_qkjntV7zJt#;yH;3uyNUOiNV z{26tOVof&}8jw}Eexa=~8o-g3QK?_Mxs|`-)qXL$#2#aq)8c)HrAFhf;pk3uDGo~z zsDC=;U=K-Z%{^L<@kr2sd!v5_M=N0R7sKHu9=8uGe8;#tPpt))h?9bj26sf!W&IdP z)`-nqz2vIu@$D90vsmJ3g1(;o%k~$kaO()y28Q-pLuh-?qxvRZgU@)^L78MArfJ>dQef~O6Tu`#-#ibM8$mm(Du-(9crwe#8BX)%m@8gJXf2j$33~w~D zXI|D3t=Bv9yJlP7BK%b*p^1Plxbr;t9=e$vBr~+;7b~2A<(pVkaLpBg%~42oBq#MS zdBGO{iEt8h2c0?coW_ZbltBRm^%j})@X_^c(-9ddHv2*OGPw^EudMqpbz+PJTk+0P zo4$u0N+x^ia%*z2Kz+#Q%oVOE~^+^F4 zMMZ-b|BjT5u)wcIVh&=rjMdM%f^LerBD^s9Wx{{XYfY_(%Ok5-HfpzwV;5i(p&vb@ z)T>>W#~82pt`lS`88qT3C{Hpf*h6`*9#;I9QD=-}fHGroTzCNM{i2pwAvO~N<)pXG zS}>qndn2UGRAg^$o3H9gX`U}pT<4>sxUB6*BYHPD;}w{1P;8B-=BPQ$V+iYyjQxYE zG<6xk^wuR9l%1h|$ZHvPz>Tj_<$Q{m7l4q!w(VSxGgi9JzJrHdQ7&YJrkzPATaw`C ztT#O(UM1(sFI_L7)ywIugj*SM94rdaw{s+l58wybNlhagthmua)Zh3`g`zhwMmUI7 z9qKn!j6<;P0aJD6_nYPrk#2wy`Iae92zM)f+glX9cQ@!Z2TJ7FqE0yK>%!JUSs)A& zF>EKrd;I)VlpSA!bJrh3I&;MHv%6FNBEY16D})>GZG)Y&iz;mD9{P6yHPTze)8`(_ zbBnnj`)Bgq1Ln&9J7L$gmf(fLBd6*(ziug>ju_Ox7IXO+@5!%h;@qTIob_!=$h40Z z0=H$;GCPC*^T)bq^p&LcGgm{tu7j!M4GSZxycJUzO|&)Rj)wl^m|bHd&P3`>WQO<# zkHB-LZ3I(Cl@D!f0USSjgXF?MxR)lLHL!N>IUG<$e4?$er3)CK+470QDz zN&NsLf;p^4dgQgt?z^g(g0&|_)s}9F0Uj{q96DvppV~O^OlbP$^5V`k!WI1?_Tn?W z@BK*?+&DWVx;lV0V7^cnI6mT*gaJWpvJ1xl&a*e7Mkh0l1VoB_WDdOTbWcE7^o;n~ zlBo+Ae3O;Rr#>C6Xn@(BA)8ZR8}L@Hx@%G=D%I@~lA_|P-32%}uIqBkY^5r5 z#r&`~gVyHSYdCUVjjs`3TZvd9Huil&NZihpFEC?z#H6@kA5ee#gye`HHTTh1T z!Z>kAjAMB_OadcYyuP8Oq_Pe*a1>KFHvw6k?fCv?TEMfkt`6+ zJCcRx=n?u*72@CbzN9S^b*2C%jp4SNyJY)Z-j~b(QP!+y!;v0VHY-EzjAwiHRBw?) zD3f5U%DIt#>q*%B5^O-73Qe@D=B-v{t@6La@#(l(*)1$OHyh6+Ybdnpnf*g%-$!x{th+ zr$huP#Mta(#79^n0tg^PIZ~xF{v0qTlD|SkOg}vUdm-<;C3Q@)=Vr;l`yLYn(93C2 zotm()?649fgjb*Mv>8yQ^#h}m4|lKNOr_JX*j~eUl+|uXSbCGOVqof_x_X9ghv}E# zd>*!Aly+a7m1O|b6b?*>=gpq6;u9OOii4`EG|jU1e-f~H{~iR$n*2eCyC_2IMMsOv zR|C!EnuO{KwG6m0GuGZ_s8{)RPY;h%R#%bKRrPq@rlMKMu=2V3ZAx&4JtP~(xCZs= z31gccVHkzF2q3C6X3wYp^)UYUIn#)mTR&B%08Cd6(WDILij~-8$CFWnra>(Hu=|;s z%`9R%%0m_MS|TN+k)wPebC>>ra47kq&3k8CcymLR8>7Z>O zjT5o(e&h!seQoLkS@-|HOsAGRrGmPSi5?q{ z^sAADdNN8!pU%=zcg@KHRPuYvxP#!}8%m?jl zZO;ykYgmhYP76I}#Ey7bK!}1fCoKLdY~+CMTGU_2_ksdv{mWH8*g><-lm6#c^<%pF zE_wVBU9iS7RPAw_70zM_)F^*@p-@{!Bo08L;(e2*D+`-ICCSQq0gHWT>(_+Ao%#FF z8tm_DOn5P3j-A|ikIVS^LEN8h3MXgIz3YdwCi79@*3nl+{vo-DeBGi+aU}c1z-ns+ ze}J$FJDzM=F+Qw%E?fiyqi*$P?!ud8hz7s)<0Er8h?((ZXy1JV26B=MVqFp*PXAyv z;}6-4tT)nHHZz%=WK7Xr zy#_|TN$`fi%NxDym|L-cx)MSn37TR&s58ILlGF$9G&7H99VKAv)8sK@sH@|va8TGp zpE*&|xl0!0`o%}{uC@MsT|+3QJ@v|ZoBBv7fmJzVoHwz_ff1Ve;Pfa#^(vmRbnG8)w55LY#*@#U7mC-2N5 zaS+i5ezU8UWQMQF73P>;vAy1zIQ)&WTBJlajiz1G+%cpp4Mc7l5I=07tIM?Z7`hSE)NsVB1Wf1YQ{~y` z>mi~n#KyztbJ^2`uo9Fz{n;|Q<2S*%P3k^9F;1Z8bDd5m(ck7K&DR&#C@ci&Rn>5> ztHB4n#L|h}B3T&@*o)mpf8?#DaMu`7FxR{$Md#|y$MVXtoL3$YUqp>P=vAR2XqV^% zoQq?D+09IB<7mk>?vxWH3ld?y?r+EFwE=pb&{{^u85_d!Evi!~&m$U5lnPK}^*d5k ztfe6pN7)pNe@%I7!9xo2Lej968JXQ3j)aVUS!t7ouJLCzReW1G5mxMMyXe4F>|bRQ z?=e{JU+Al9K?!rM})(37vzbYzno+Q{KD> z$`3>8P$lkBJNtUiF^U-+qAhZHfyTJz;n+S8z^-#ZFcqrfa>F*kLJ`G3^=WwOl~gw9 zew?kn%^Chm1hiBXm{@NHkBpV5$>_u@1FAxGbfRP1%F*y(!()W|*IIkZMU52P_;EmS zyP+D>jQjTY{DN{&$>YW1u~)GqJ`qip96I5)w+>Y`Y}hN~c+ISjByh$xTW)oF@qLF= z&k7{AYW?q!2hZLxyo~JHZ$+(=wvB7Jj@;$HS7%-?O?UwjitTTu>2>_Yu(|LydlQPRV37*Zyut7F(S8ho~HpO0c;YH0*63cksl0I2NI`9 z-R-viI0d}nE<1@&m}Mf9+6kWokY<6=Rws)lnZA<<@%w;Vs>GIvlePh__GzkbP2MlZ zB){pn>&>zXP+Zar{8u}c_}RYFwHB;=r-W;F%JG z&o$(7eNKyJR{G)$Z1|-4 z>xIC+Smt1XOvbywzhgO_tuCl4gFX7&3z!yo7(>Swg1GE5MRg3pOoYGAgFCd5^bK8u z_SO)q#wMF+S?owl9W^RjBZDH2efrMcvDtX`o(Q`8+VTX&Dy+Y>1O*=p>*y*xKTo#E zYnNJ{+ecSxVU;CLYCq&+^NOvmffFw^j5&lo)TCBm8X z?C;(0^J^#os{MBC8E4jcrU7msI)BvA1+?na-Vp{wN^cb}Vw$S!ueG&CvM4TeCI*q~ z74Ovj#~WoO0VL8y1sEK0Hdw?r{vs*BFVaryL%I1*hu4yKs86MCTunOZ7Gf|_yE51f zh9JLa4?gdU4aKIEf$49B^&)Pb3Ra^-c~IF!Us^v?Q@8%M9Am3|?JvYDs8jo`M(|_G zdT!42xirw4$PLmm&L%(2*}SPnWkvo)>kX^sF}AruQ+-v#`w&JqcOMn-U(1i`#lX16 zu{s7q>^STO(KkEcjjh7YmJ9H!-kdxM?^(@fr*00%?on-!Kn~xr6XOiF=*#t2Q0w0b zMRGv@++0yYN3x#E^BV@SJ_J>kV=zp7p1?VRfXjC1B;8 zezd9tp)*>Ih#kZ@SSTaMtRVQR82HC01qb&M{^6yWs#SS%#1se=O8fU_fo|=A5?{6m z05|#E-%ZQ<#`D4#7g9NUpgtwZNZ6(ui`)2gtZNqRrb-@uTu{G(?>v2-AvmcfJTQ9u ztJrD^s=IEHl6(XL4x(|#-hD!^<&wd<*HWr7>N$iLK(K=t|3b_A-vq&~ibM!w4k^$l#ct4IGH5&2Z6w&9|{n+;) z!t;7r$sH3x0rq!k`wz$DSOm`KbB8bQ<~BITku4XsR%o%Gzb;GX341j&T5Q2@v#e|$ z{=muDclFC&%+W91Ba1t=LzW+@1an#_tb?Vp+l#^v~sWQ$)sXs44FN2fB#vjjyJgwFeX1Q{2t=Qxc@=3H9tZ0N4$2% zcMtggxY9I0tV7GsA6Kdxr{PLz*9E7Y{}V%z;|UzHvVsPqJT--$(9ayX6A67i7Z3O^ zVV8aa;CKgVjFG;Ul1c-oF<)%{Rk9c8Ok_wH-cMT2(#wNQ8!8{ph4BRDs$vhv`1f5sAc4dc=@?sU!AD;f=)DG{NspabD1Ag?db6IS_(-*ZUR53V<7@A zk2AUs5YtQ=i}i$#D>o7&cLGJn!+8e6jH)tId>NvWen&u$u8L$)XW_xa(i9zI41feM zJ?>aU

B4l?6V*jnm6r!H)UY<(-%BimFgCqX9ayjbpawH0+^z|5uf}9li{uk&*}o z9A^VA?)Gn>x0-z8YL3`Y!PcRT>1LWAVig3Fbm#;PCsiv4vAt>J!8DHN`=CESF-N+~ zfQa``Mg=jiBj1w=3KhwfbW(EkzYPbr%u7HL^M~pw*eNk1tSK6agIhC8YiYi=6@LBl zmBha5?pXmU&dPw=_!39VxZpk*EXGu~jv04Y3G+Wchys=t|7;^XYz%F#X2t*Xj4kCUR^-l|D|-8qqGrt4cH?VZ8lUJ%OQgj(J9uGk}(>TE-I zLGy%K=-RUp4jD7)`FfBCXz}Dy3>VP|#8wcQZ$Ad^(v4aW^7KH9VA&X<1M z8jq6y<3ufM+u&)77S8C$lkpk3(?Lazm9qn~W|ozaGaT;T*PW{}FStBCZCy<2MfCltW$05a%q%8C>^UhNyqpv>5N4Mz->@wr=A1UnlBz(?DpHW{UNn?hNIwwz`KxK*@uw zv@Gm&w^bJl9z`05ol?%XST9A#ee=^1F7(*IxWh3;Xh7(SGa#AwPk5=oB zr2N))et}{v7fH0t6=ut#JSp&V4w^I;Z9`%pi4?AjU13zAf=P3^D@fGiAva!4ztD1| zBinr0MR$rMBUa6XfJ73`nK`|8|BPadR(B*o5hAN7)^#hp!BN&;VI1kKHkndHr6Akj z5}HMie@FSFkr*pcnx8*?Hr{cr%3@*`+8LaL&fb$E-mmA83Fz<+2XWs>&5Cy!Jl5}y z;7Q-h)--s3Lc(r(P*d)|b4%1u1{fx1QBk!m0^LTrWHg#FG}zWAjqe)$^*^fD7NdEAlwz!>HpvS*zL(utz6zc=AO zp0yYEFPcw0>Rm`yNHrJfTA8OVB~O;7Jv{i_=jE72_Yf9OuzN@byP8_9GD(s-vi<=Y zUd;CmWgPWAvp^^YZo70UmFZ$C;u$!`4Ms3+kfmr%iSYEVQW1(rWx#Fj-n{Mdl=J)j zFY47ciHah)bv)XQKXK(yxbOU-G)k~mWUnX;dMG}~gTlLs#3_Ht=T6JqkLaY_4a}ex z+Nm^Q>}03(N9pdr#!JNkW#r%z)+gF9wP14L?l>cCox6hpOD39Vvx&3d5F%LbE!2jq ztHjuxR_Ihfh7rRGE^puegdtAoj_$MD5Iw22Przcf$bMmQ8mVhoMV1- z0w@zpGr(xPu8djKgdIVKTJ{uB6Nt*lxcp)3=4o(BrKL7YtjYi=uCN2|V?UBq0X!uwZ%Qpy|38L>pTeQuYrlT9e8GTo^*e>G zHX7dmQnzraLV40A_&e*LE)_G#g)L*Ui6oBw=HCH;iznlL7s5^^qT!W+I^8Ptbs=OC z1YQ6+@CayU38fNx&RJ8lIg6rDD5eF?a?q4!_2 z;nu}ePJm4YkA%CnWrr*oN_0FlVlu5v2BW+CPfwkZgkyCy%xeIlT4Mu^9^0f0<~`Ar zci4A~IY@Z1wW2}LZ6_c~L5QVzKT&dwfaf=Xiv~tmt0RR+i8=Wc{=Wx&M~=+b2>xB} z`IMrAfr|YPny2Jht>z!?UF0CvFQ?PbTNrI5d1l$FMEZ?%V9b8MPY&aprR4t<1^*;s zlmL2ING$y)m5MC5drFx!wD4D*LO3RI9V4!ZtyivNf2bU#6w=52u{QEU; zbP&!Z+o^mJVMF;Dzv3aIS3E%q6;6L^IJR>^qE3#vMD8js3Z8}W?7ayz)zP~@e9kcs zaSW9VIfRs6({ODeX2ZU3lI8Lje9pL^&avh5{H0W@HrcEYWH+=v z?7eB>(}r`T&xDUetq;Msj$%susy*J+e%4F(+GOMt>3Jcqy}4aLxUA?TM#t{MdYbXg zUCY_TM9ewjEo#!kU8aS3((8kp*;OY#t%})J^Fn=bWDz)*$cIx7#rD zQ}xt`&MboHx;u}~3ZKyJiys+%e@-|zV#}n_7X2YNRXx|<>*wPF@`{uBQ@;nkFnzRc zleh1b`FE}@q&=OZkJa;XB5UjW=Ph!AxbB>cOuc~hE`94<>9$v+eUFlGgNM1*&I?<& zkGGz09lY_f7Qb4gWhlnAWaU%EXY2P5a|$dUy|u;9o0a!ji<^ju;EIMfU%8)RZ(Vkp zzG-}=%&nK>5DuqoN4}Lpi4Coo78c?jojlf)rYZQ|O-v~E)i3ycVco7hyNx!u?0sA5 zmG9YLAW)uNZ@)Dxp+tP=t?84tq}V5OE_qZPbkAD9 zTS7Ob{E)b|qWiD3sGF@&nblWrNWwYU?u_FKN%bdGkpT`V}0Fe&F%6voDGX8X`hqKl)| z5NGZgP3y;;tCbI4VO+B8n8Ey=OVdXee$k$0?s1-Ue{e=E&W2$AJ;%nX#pttT#>e*A z=`Vuow#5DX{VlStkn}aqB=Q{e**Sz=W08_w8EzY+?zuRF#Y!2k5wV|z3A zn?X}Yo-NbPFu6}tDbN+nDLh@3@cGaKgDP7)NeNMub<7C|{+qw1m;^N~@DKEsvhW#+H`h4-s)I!lg=dcx5ZwPJ@ zYINTIS}JGDFN*^{PA>b`w4MnK=)56Id(^~w&~-k7&kZ+rUoJf0@@nUu-*zq=FKF+2 zl98#MbE2!`*b3xRtK{1L!GyUhGX&^52wiq9OhTr@ku^u zrS|c3Z;Zm>GII}I9hR#44Dr;SSF~esTic}D&74B;V)_cF&A^EE=LXSVP>uygF^ulq zboOMs=jZypo9Ciar~O1d3-7K^?03&cJM(^zeSX>b=jKf@y2`KW9nwb278DyXD>N@GUU`~xl{Go+v86aKd-*=ySeXH z;Dc4HD`&Fz+Fy(r5|8kw;ocORc((UV@L;yYbPmou3nHA2x+XlTQ2N^Ncj|>@Z1?w3 zf=GRQO*hu<7L47%ZQoj$cqX_xGJvspVsQU})T~7Xx1ax|JH5+|e~hh>QW;PC6zrk4 zE}bP(FjoEp=1A@k=SubUMv>3A`H8vlZ7Rr#CMuC9QgtUlkuWIRx>60=ZTdZ3_V^(o~ zS6gZ8sE$*$%-saPoGWFA_Rupuvbr1`Os^GAbCqOCtKZ(uGv}T9+d5LSNGa!u`To_a zrkRcROr~t!>)-dtin=RM>OQ=7S<6Q8&{Dn|g!c z<@}Vy1nErd)HmB}J!`}scD)s7mYLQd5S|ISa7JI%j%Qj*8%GKx=T5)GnakMIPV}`d`w#TGu`sklZY4FZeO`{ zCq?#V=C_7nBd<3X`?*p@Yd-ci_jpTciKHbUiDZEgZA&V_}rej+1Tj2Qi+s8jj zE^n9$+g3DV=(2AW<*}vR@G5Gs@l#jc$%W^qN(*G=X&o#pbj4+~=M*kI&wWsNF03|% zeQni>lLIn04h$Vkx|RAHD^YbJM7O_rk9%v+`OBnD^QlRs!oJoRik8ZQ7O90*qsA#a z9u(4@Uk5t!-p3nUDau&cIwki>OGxC+*Vh6!8g+GsDdrD$a(puO5pUk$?t+sLRwsAo zTlX2ep460ga>%wDU0D_(JM%njaLbd%saM}6MMhq+^@M0m9F$Z4dNNUM!{`S;mja1% zhI@i81_kY{y%rFUk!0=ej_nx}T#*{!lsfFE;U|}|Wi?;J-j8wj5>6|_pRx5G(%sab z?|fMG(8Y*~yB=DKQViUSq)68jt~mR#X78zhHdjsQN>klVy>+hZ9{eoqk?hh6Pq}qC z|E$lppUORle8};Eo1&!bz9}n7`aj?JJ|ja#YNywGen}7M%N||+%3W=q1NB2|0|z62 z6q+dQ+ZxzbVII7Eo6U_gQ|sjG*#ZkMh8PxyxfyGkY&NaITwr_Cdqu_khgrJqHie<~ z(wh_QPrv^@wRdtLv>bkIvaX47tHo!;W0334;gwt?HNxG;M;gL5Z3tUkwSp7>MSO$l z#oYapk_S>=Ua#hCFuh}mLurwr5e(P5fo}#omR4jl4^hZ3;LWwWrYcs;L^S z;OhgclplNK4o_IWczoO>887WolH|9mvg(78+pc3*OCP@fuqsDZXx^wrW2|kt;gEV; z{?vJhpa;MDfnBWsWLdFZXu*nVht;VXs19?M*AhW^&B z8VtLw>QHmjtz>vmVb|lji)skAPc_fpynAptp?#aK zv{>RTwgm68@ST_KW;TklZM5yJUjN{wbb&#wV@|}N=hT65yL%V5$ycp-O*Q{MTok;i zaCMHFn~|JKQkd`CzVq)bF11UJU$MCFO+T5@N@Pq18}D1t$k7}!KX<5>8vk)TYif5^ z4_{+HTTUmU(wxsE?HvOwA}t+dfh$MLzJ zMB~9#`&DcOxeRT7V7+lHkzTR;*GzQ?)$MxlQ_1swS^Ue~Gqd9%E29+Ia@o0Wf2iwt zF_5~-f7kS-Y(-&lsdRa5J`J(SuFdO`Z?McTj*IPiHmhVQsPI(#)4^xqV%@G%tbFv8 zW6q;vUusRcXqzI(JK?|1se z4I8arQKA3UQaCntUAVg#o=i5?xE=UC|MKJK4db`3^`=@%7HvAQJ5IMwF2O`=@6A`` zVVwadRtB*dT%Fpuor}H1V|ELOYrb*kPFb4v?9b-Qbn)yfa9v!n?b^366|HlHXDy86 zA0MhW*R=dOrm}1^Z)D}loAGiDqj{MFJDRjNDw!HZkC8^_Pj6vw%_}jVNK26Y7Q_B( zY>(p4$HBO)uiEqXHnn{Tsc`YEksJ)gG~T*r{ZZ*cQ=jsAS^H{6?Zy#1bM@N78unhZ z%tp@R!&PQ(qvCA$X8K<|D$93zo6z_Lb7E#K#9!jFp9X{f^= z*ly=H9`Ksc_gX$YlH`{v7CaOcM9l7OtP*Nltdk|lKAxJ@T*#6oY z1OKZV&ZKs}6?$hMaNW`I;lZ-kinq;JPpcewXwn^{@2s?Xzj>|&{6Z^<_d+3{W) z9kUw8QmaCx)!tq5bkIpr7cQucFB#fu6x=*cjdQS*<`VNetSyk`E6Cxg)bg79uO&w?LN9iYy(ZBG*6oH zv|cXO>@2VFhu*#uX>A{zLVDI1`G-7X57?Z;zj|}~#_=sjo_^6!a954!`TTL~Mtt?# zaS7eka#A})+0z_P__uA{*{}a=p_QH(s2t>RwaMPA;*)%@-}@$3~2vlE*GKpRL!?`@o zi{(q!^P1DOhkQdBK4bpEH&V~+Gr9F{awlK>-aXsQloD#s?Vp_)y(3=Fd*H!6zo$|q z&AEiZ!Y_OiI>w#1ZNnwcJln#Na3b#os}@%1#;Ax{99N8H)NyrtK+RnT`(^YU}Gpzd+C^=&VuA}@yd9-a~ZNYSTEm&ttbk{W3| zHPF*EJzXGMS?=QhB7AciZT!}27X0?y8eN$=Lk*%*%S!dml{pG#pWk$eSZ*EJ%c4#p z`>Zs3JIdkfsqd?Z-$aoRtByL8~(^uNxEdve?p0?&qLW$-QKvclCA2}y#X~g$=8yM^Xr%Yh{HX7 zwt7%7i1VuNhNkA_{QUg4tXHhsf7;HoKoeMxosWOS{d0bY`OAHWCg)5~WL3XX9G{Pu_X(WNOBr?j zHO$(2kG8C|;H}{ImDM`RR#|>Sv7sz&XR#BO91?lLJFA;;RWts~ z3FjKJf#~TfF{hG<9WyZ!c5C zdwAse-0@d?;@+x74vtVT?1J4T=G@g`j20gOix9`N_3`4uT3VYe7wYD+vxkZgbW3jJ zaA383n$+~7ANz6(tq1eu+W9+kBfEF8@X}6oa`oRobMmZ(*ah3w{tmdH+@`)YA!kJE z%%0)is}NH{+#{z)%>0|>?zn4Q6Q78$+2)@7!@uyB&i+GJTKgvot{p!|akJ}IJP|3Z z!jZzOb=`WS;~J^3qn1DOtL9=SwOM#ra2som+>bSUrqvxpJmO^EZvLU`onp~r_q!Zd zJBpHB+G!b@Bv%%KuG*H7;*19+S2p9*?+Tfd;eg;IYX0 zTB6{28wY={?UAdWw|=e|ITk6|TVisjcUj%Lo=rNh1292nRcAi(sT`2-yt&gRzaSvG zA}<2hrTkkiH>>@<(?pjGK4lUmSi@V__p|bLw0l=i5BaUJTb0O()Sb!C<9@ zMp@^iAhyGLvl2F(ktCMKkG+1a2&!H?S*eofa;9d&*m>mO^5ou;sUL)-9RfMe`ho_1 z4$TYs@SlIB=To`G*)}HiYVPCG;3L9bD^oXF-2J`$g$z7`^>p@_rnfHys#veDQMQ%>K_01Do>=t4!6d zIhVRQ7i+Igp-G=f<5w@5+wn9p@luhFw#GsGx-GcF`-tZPtq5tI*&|n+Ygoh!+^CiL&2_4_aRbFKWWU(%ompCBr>^0QPvMv&E@E$83G1C*YNT4)8po6r z>~~aMD6dUhwm*E0<3cTW#fOjbZxtDt(TshGQGOlOB{}(^gYR1AojOID z&-7LJc?bo&=f_Nr2~@T{9amEnNYY)|v-xhbMcGU4m-ADZPqwh!I=9Wpf7a)9$n4PI zEwc?b8duQQXD)lL9OaWQtgT$KU?-7(qkekjyGLzBoVOZsAKj@K#@j}=)w9@J+v5(j z+q*WI>N@k~&e03;ySLq2JG}Sc)?3w5_yiM4l1@`}cI20XUaEse2Iu{&%l5PNQK$X& zGzS}X44SD%8ZY^TR5zQob?1y1CLO-mcmIRqa_g@>@p@X(H`I*FJx^cE9C|tK**Twa ze&_jvX5&ev0Xzy{f;{w=N3Zob-cskYPP1vSrPTXn(X)ddlSh@74UN=sSTPFH+S@xn zTu_*cd+iXgUCd7@nC_AKJZCTd!Mj}oV~v*hy4d~Ix$8!{`A$&87QSdiV}g#V&a;h0 z#Ceng+pme!t|k4&H0J57<0zIpUG^s%*WFD92U8^cm?LTtpdt9mezR`&g8Q zYd=r)Cw%p+!YO(B-gp#yv-;FWgFMHCx>|W2O=XAet-?E$=HM4{&c%#ULTxN7WDPdy zU-gwc9d2Y@tP|kF>SpMASh06xqU_H4ys7bDPwyqi(iL-Dessg> zq=Vj9_8fVfXns3o*W(Ajr6wjpWb`QQR6-#P8r_b=8?E84HoI`y`w zS?Q{X-N(3y%nuk{hcy_l!xB^C2ANxmPfr@=oqZm&KiNH{g0EwTX~yf;jO6R`KPU9s zBT5=i1uusmj+iXz6%##Pekv^LP~CRfjDZivpNII4vlM0@lytax{j-N}!m-^2Z6c~G z&zWCaef71U0B70XJeX^?2t*&t9eo44LL#)B+GUbiS z>7%|ToAjT(u|9u#=juZVPquj%v#GCYkh3w?xg}`uQfk#y%u|K%E1wMGEZ3|Oos!@V z=f8>TI2S&+r6P;t;}J>2>dm9e7Y4}fLOGD8%bkZ*2B&7}R|{^g#20yGP=-Syi3# zzV`_)W6yqFtt5MoVl;lv)8{$m)W^PVx%vK|r-vx7A9|+8aD4r-prI7|?x4LX`wz~I z5=rfiqJ+?jSYv$6gNV6Y+eAhA?3Z_XA8=pFeEpm2O_(RU@yb*4%~4iwxEzI9O3qtc zef-JD;*AtTO-k#7U`hvpH11$xspa_HCOO-vLgSQ+|hTU$83ljpKauxm0cfoC9Ee?)51`Pu`M9cKuaW0$fj?Pz@aHF zC!G(xCx$H>uAJR4Hn~Y0&xb8aRJ&5)cRrMN(z;^r!(->YGzDbcQdBIre5~9~j^WTX zKNWe>3CF)d=yL*onsbV@twZCvRhiD>&x&uaco`Jms=wfnyD_D!_T2o7EB9T(D|-%_C{2`P2PoVjf8U|gZS4|Q z;LB3B$v0%&sa!Gk+ggqczvd{>0n4^1b=87))2aB{x{}G%)uhhZQiW2LjTP|BZdphcYi+HtVAt=J`aAJ+XG%hM%Ev8o6yAeNB{`lSd zrm!zxsAkUOn7P|e+eAn2ixIb(Wqh++II#TL*I?tqL&GIhWvy7#pIo2rCyQvhk3W3t zb`pDK`TYwT_0nX)lAU*SM+4fur}`v2+>(FMCMr6QHs)0CJ$lVfE}gfxwW`p3BJRzy zN(<@s3eVhCTt<6kfAmf@U>Y0WWTm~yeVO{(a=GpPo1EHwdao~LQCacQ@0keE3Wnpw|lZVZQYhMjx)Kmltif! z_La-2N8j!{hQGm?c5Ig_0RrTaAeV$WdJ)c54tUMExYR^Rdt}t(RdnMvm z7;0+zd*RU6a51~LM30|WSgZ;e^xbvpg2lnNK3Bvzczzbe`1XEf$r|6g*5X@Gj)tCI zv`@6AdlC=PY&1bwGd#?Hu=^pa+Unu;hGzDMe>S|@BfDGVuWgRr?0-ycwSZsi5Lcjfwn@|SKAt}H6N&aGNt{QWZ+^;Y zvGy{(NK(D2>SxY-`9)exOln4S^?Q;gTMT*L%MZ(o1#7GbmR`MDp?LPjixd@;u9k+VTW(nJdkE~fXex=fb1Ghz z=2oAst#oDoTg@Rx$DUM=AJ&&-ymw)PV$89s7cC7FZLTh#)MZnZU&ilN>-tM9_oci@ zRq*@~;^=)$3I0M(vSp~qhkIlZGZESz?~C?2jIQv*w*53#3-|plJC+g8$lVU+qkgt_ zCTuL)YGh!FUEa*I_JaG4-H(qrq+UyPD-;qBw%TY&o-3>*;4`S1IUSH@ zus2I0zhLOJXKT}^y4VnT3GqYv0ZAQX-E};N=EH8tbZ&O8=qa|FG}L%%8ufd7!p;MR z#>K9BSvua>7Z=Y?tm$cSc$Xc0LLlLy#`osdZ)y%6ww)U-N@-dSp}Mwy%IR$6LyymT zus4_*x2#+%v0DxIGD2JD{6uKiQS8;H`F-y{n!ma)P;^N;>OeV9?@Nur%n-wE>Jzlq zHosS$m=6^L?3)jdDC8S26X~d#)wS~!80lRl%(-?A@5`T;i!O8EL=UzWz9y%xFmIfD zCo4#x)w{=UCn~X9E7~5~<~#jtU!`5N(EOINAF`W$Wj9Os#~plsH$7;shx=psDsjc> zVfNbkYnS*_ZWnO%Mr*dKtEV_mE~JW|9kIS7xJPN{X36&wC-{12TuaXR4?L*z_k4cp z&2UfK?0d5?DjswC`A60K4?!~K??Sc26_dCk<*L=BBnrw`6m~yPX6>x$yXq~UC%XKg z`oN&|=v5tF4IQ$Oyu?${{Man6wgaR$PmgQ+}Tw~uYa@NHK%ZM*D}PqhANdf0xI`0NI@2+Midq0gUJ?h750{W8E6&Sp-q+3vr& zd`-x$!%nBDPRUJ-b@yn;ukRr3Q6~EAI`ARKeUDrBC#Chj&7ag1ZaDfhM!6+HeR$M$ z~??AsL|3yfD+teB|Scw{h@KSVkE_7SQe@9m3)GySC&y7;EB*s$4xnJ!=DE50`^ zCw$r-HV&Sb*mGxL&%DRO_T_6`bc4h>ixV8(hSnOJOP_ly`b?}Zf{>w7Y_D}g-9*FeUdmwy*>@`)3hwxbJ#`ARCMyf@sD)XL&D64|W{Q5bZplnSP^sN6TqNy^heAE*$~pXN;^=V+A4K(8xa*Ja~$@ z4~Pcw@agW;czB@VuEmGRm^uaT*qX!?G5*i`g;_cKNCWTsSa+!uT<1xCAsn_hpU5?6 za-U01*1lT_Krn>s9 z=I+Xx2i`o(KBO3yuiP(;&lI)_a^?QEyX8mi4Q-0oi=bfFd*YW2KB#K!TeI?F`F$-j z`{QeD_>xYq<^OH>=(60oD{n%cl$IG+YJ_<7>0~PijQh;pPMn-PNpaXX&2#d7o9FuF zXAC+*7E)@S{Gjuh-KQIXvPW%HuigYTTyX8oauVum9&+!P&vYsAZRy`>G|czxhP{`dn?U zkoUmR4JTB_-=8=BdiH7aGEu(;wI9vH%?(uEtj>GB?N!Bv7B$G)M@S;xo&MgbviAcZRyw1ITGruzi&$a=U83t`k+YfIIQc+D>vkH zxY(sveeROo{`v}WUOdo!1uGwGTvKB0z?L)#9sKhB<2xM>9&PTcGR1{%-Q+7e?k4}l z;MDq?f|+*OY7Otyip_e|T17_A7@mt`4C|F*b%I~D9F&uY9;KP&{uC%!mUiup$@zu5 z>8giPYvBLfY-7K4=$v0@q9|=^{VCd~x$w9j8vHhAaB1cS_s6@1+`mh3r@2Z!5tZH< zd-s-=?c=6=Gpz5q=D813jY0M7<$HqZyhq7Bd$aZW_e}KbCppbTA2o3G!Zu_-s>)dI znJu!-GfG4$_JnV?+@tLUye*s?$JI9;8ngAfq(N1=i$7DjwMRSgu!oS--mu?CCr!A0 z_1A^(zc|i;%g^rZ;5!@VuKF;xlV{+S&!ghgo_via=QVU3_$YVfqn~4A?S#1|J9LzL z>oim3-c__e%kKDea?1Go&b1lJ7k+83knoQWElky+y_Xfaw7Hoa^*Xh^V^>oq!FdB)x39QpR;4^-cSGG)in3XQ}}iN zl@pOpqnnz}CV%uxKk-4NiABkLx^YV|d-Ss!M5=<6@ZM__$CD z>Mo(EY)u2LT^sgg9ExkZa+zaUY+K3Uh;uDBcnOau`|r@jgA`0I5630nJ7Lh5&9?n> z9j^&ZcJk%E_gB|*v5;jRN#pYRrY&lcG;hh5C9cZXKN0VI?)DYlJEWorg~@M%51Ze9 zafvdM>demm>b~s<`(}d5;mQpz*nK9#A+vp~jRT#s!j#$_o4TnPl}9myCbKW{@45*p zS}Rsu^O~=Dp_tFL5)(W5ZS$?f9YKS-6K}+ef))2(dbj%b#i{WmHkRTu9_738UE?Bu z>`vsIuX~h|W>@m2;+*9M+2@(6mN#Df&{#NGmZaCsGuSl!`NjG?V=uar7w+B#8Gl<` zuv6?q)t!ckSg|OHSF2SXS?uS%X=dft(9;{5`OtG!3TC3iv}pc7Ucf^!Bj+{|vE1X| zc`A?S^}jG&+iJd@q3~G#SMA$Nl?8WPbo#?eHb&($eA=9BBknpleYn8BUY}HT>GiB? z5J$%o{ktxEC8hQr7wa;JkQXUv`I0EUEIiHE$DK+~eHUKVB!yG^Rmh{&F7D~u+~Y7| zaq9P=@YJTyHS!yNoX2fqn>rHS!$QCB8lbI4)?cZ)dibKD`K3T9w7a%eH81>5tJb;ARz)sG_(t!5Gb0ycO$=KUc`b-2tk-|Uj*WB6PYFb_t zQm?l5;*sd!$U=8VzU-|tL5CAOh@a&Sem6TxC=(#fcxU2C#$ofR_D$EXe?I817r&}j zCHI4Ib;hoJ>=MddX+bb-_yD>yP-2i z1gzd+@?=%fuZyV>8fGayUdIM47uK6PePyi-5^m$xJ++b)&LX?5UubvKC6d;hFb`{N z{{GIB1jmuv(t!d^kGt+a96o-MU}&}DjG7{0i`8C|jissK4r_w* zd4jH!xA)282FJZ!y-uC-R6c&vZSx{S3N4&qNneJ=jCw=P1Nnr5(g@5sHgWCYFa|@R zVGI%&tfT}6rz7MB$y8qN1O^+aoQfwWFxVX{sKW6H3=Z!~st5)8kgKTT#R&|q`1@3D z$^$BfNa^P(u7*69PQYMB5x;-SpOvb__KbgYFEqVYl zfPOHC2!#w7$qc>;kQKk=7C+K07UCK>!+&(xnyJHYm^%E1sl#uW zI{b#I!*4)`-%xpq-z?(mg1trO8B2h~)a8G6zBvq(Mlgg##sq)DaI$JFb%I}MB*lnK zO|=T3^1<1<>>N!6{iCLxjHP1XOr{5t0Z%3MN+QtVY-QvC9ds89y30pZrecZ<=q!$@ zRCz+?;`u;lg9YdqJk%)<=&Udo(mf1@K*dlC=`56eRMvW+6~Ct^7*VKLycF1zYMea4}=V2j(vFMfgO3XF}o< zKZH{p@yp4kB3=lO4B}VH#BadF?+o}2nD`A~zLU)PKt2e6a$q5q)j)=d?BF8)#Oq7=0q-LI943Ci zyNJJZ2|vOkgZQa3`2lt;VB$5nw}_vOoVJ7?up^nXA$cSG#48#Kcd6`2v~qfqW4D6!>3a*+{ZfEZ|+lpOd$QAMh^XFJl% zm+&JzGKilMlOJHm0w!d`(3xP5PhY|h*pbZHk-QOpgL`y5;AcnunE2TZY?kno-qI6J zGVwby@dpBaM<#wpm@knzAIJycPt7T$vOCIAv4D3Gf9Z`S{D5~6zbX?y;9bOTw1gkw zkwN^dnEU`c7BKN5n+^CmC|8#7FZ!o4ItP+B!Vi8-81QqTeoXuvq}@yS9Xsg>flU0~ zO#F#}->73nt88-$;;IAaMvoEIc>P9$%HAAGO~;O9jBnD{vz_blND-~314Fk~iv&^H+} z6F(W|D`nyb`5^phs)bZevizd%E#f!IU&0S~7x6Roi4X8D;s<>~`it<$AbuyA`~W-B zAznC#2tOAwX$e1IM>6L^@<#ZPzXJSRs2>wQm$&T_euyg)nEHl^XW}mf{P9fu@i3n% zb3Tv{!k=zbNac!OM@71~h~Mhg5`MtDh@YuXe1LZm|H&o%2#*Zn_rLV1a#4p+421A= zgWV+n|37gLHw?BB|=;T^5F!ZjP{n71UbkE55D+z9O$$+^ozem6#*YC9#3A3 zlaPPFVaebpN`_etFbrK7a{>C-K;Jp&r<(xvY^axz88}`t{XgF?;XmXz!T)f0^}+@k z@?-yALijKkt9}&AVhKiq7$Q{&ClEkIe$@bcD%lbIs{t#u-Wzff8x<1(xg$H(AOUi3 z4k|etaxy2iz64??@c{5$TvQecHg$2>SWjcZRC-TDwEb?5Gxxp(2;%h*91+sj_sP~3C z$cfE3n8t1vOyjT!rXl&V8juI3fcFIEANOqW{y+gAS`T)F3U>mC|GB}3;-QU~2(b;c z^BHt3#b2bii}4q?V<*_AE{Hd}!B+QBafAjciobAho^j0cjQbDHa}M)7pcJ4 zbM(*f@f7b{#K%JHUBt&~(6@+>jr3{}AG_l_u*1Dz%lg0`y!vm&#{+9*fi<$i`p`WN z-Qm#v4c*;PjE(MYD8BxW>;Q()K>zQM*89f>iEx;?=k1ozGuy5ro!7=aK# zC*T9<22gkZy)cHs$H3hM64YIwew~oXAm9V(282L58QL76jRJPg07IrfURW4&g#HH5 zpMd%Uzdv=vkMl2nXe~F#3MMiDF?*+oMSdO8`FnRsKVhDW^54is<&cE0X z_~@W^$ah2gpT53OMs!r)$ee>fATQ3b9caZbK@NZJ-e8xId}RA}fNV;K>xoE4xuB<| zkWijD%vKM2QXfs@fW!%j3lcXZ9!MCBeLtq2DuiTe)(`_RdCBmSoYB}4CXa;wG!J9o zffbLTV-;iQ?8{>4EC@fWg#v3~gZcu<1<~1+V(2*D82T*K5uFX{(tI)W8K{$?j)U=t zJ_U6u)TNb|=;KgFv=z{o6J)_s97SU@02|;KN@ImGC*)j^JHi-t$k99&r7;W+n41b? z>zQ+{hVi{n=K#7Ol)uma`@9ezF%;!#Dwu1zIZxc#gtaM1fyDSwKGhXmx>}YRDAv8|NxgaNED8v6V?tkR+|HgTd>szvu$Ud%Kw2%Ka+cxkB z*~cXt`>$;3AN$J+_LU9Nzh`?FZ zP5om-P~Y1?LpA}8MKk>PzAAJ5=~c$p1iv~|?qV;Bsn zpB;nYwsQpCgEn4#@*-WDN#lkXB6{OBcr%M(ghP(UQ2HnEl>S8E!9t9q3Tk112c_Tk zBiOaLhr{RMW9WF`!3Dg~Ja{Ib&kGCOJ1t}AX+(&>;0>D<=v;Vs%Lcxee=Ur05hyes zXk&#oROf*l^@)da6(xp_%7_+?XwVmxxuFf!5se$_AVYng6fx z2mcyxqQ4}AKjZN*o)gCJ{cF4xlqLTfzw@v0e=s4LSwK7auYSh=q#q~nH-dJ;U;VWI zoqk%-j{mD4@t^cVc$J}@^RIq#fA!-n&SW5rfA(n&(EeZ+|Es*}ukwn&%0f^^`|)QC zs{bkT{#E9JvM^xzLqqjHW!zuog`Z33>kkdpS*a8nKc;qAq&|kuk0}`D$7BtQz}e-; zL=U5LiO$v}^h4(Zoh>%NgX$QJZ9f<23nwWP?(CTiq(>iqz*&Ku4f>%o@AGjkOkkH9=grzJF(bb7Hr`Qfk^FtT6ZS)2>ml6}U&pG2awAUR-C80>(J6Xrv5 zu_q?OepthrF|c+@zc-9`#3VBio}Q;3fk@QGHr#)y6dNdWLU z#xqz6V6Uk040iawfrB?sUT8Zlb&bIX-$z&=j==-X9mcQ|q^Ve_3j^IA#_}!pkEV$L zodo?+Uv?NHj)`X&Lw_tjn#KoXaD)IF2KurP18G>o7CH;@HLZ1FVIRUb1Ng+DuQ=cl z2cG{P9@c+@=Lg92Z#c5_(wb)(EnfIxdnLejv!~)%h!Mj1AC3i`B3Hnxn_g> zSn(+%7-9+o;l>iz&~ZpM_>{$UV=z>jFd>B@0(1-}nuf(wA(3e~0_3PK$bf}Nh4jB= z5DjxC!8t?wrz?C*q=Ptg9$WF*VJ_u?4_?;!tiq|;^G&-o^UgTLi*WBrX|uKd`oVr+ z)q{bmZBepQQXj%YhhK*r2$vOEI1z$;5urGSeqr&wgoi#Q^$s25EY`|cy;3#0nF&T`V&yc?D>sN>K zWrq=Clx|r%pIca=P84G}Iwrxo_w>8rFx<%I`l9n|K%x_&j`WcepUS|(*~dcs#|dW@ z=_1m(AS7#$ZwwA2ir!I?Zn79qXx>B~Mgj0R4Ok`|u7S)m;AacssAmC(H_VUpt#by`#JP0qhFZ#-Q{Usf&fgI`JB%ac52=gKx)YbUMzK*aC4CvKC!0b)o zVVs791x(?9B|4smf#~O84i;578^jX(h`cS0Au1Iu}~;944KmJ4&&J3 zAx?3m(Cnd|lbFHa#3l{Bf*1nJOX_dNVp{&RS<;sF<}nr{`lk(p31--PgPcf|e*VR8 zy~zyr#XZ~&G7X`#5h>YQRKOOJLg*|i@k6XcQ^p!$3T=%%Bwg5ByeR`mFa^1qf~=Dn zFF*VqWAzTBW3anvV+#up2$A=a|BVP2(EMt>|J*I+!!lhUOZDO zNkixiapIF0?Z5|}BX<^%9neW|CODaNUZ6i^(jA#}m%r$Epw}_!c0fmd37u7RMn8bR zKz0C?>q!yx9`JdH&JJ}P^mz+(Hf9~g3aj9JBRUJv&>3xIjz|4lm}6OihU!hsv8Z1o z&;&0<(9u{_2cOkn3v`aZc;lG7Ie>2C&BI_rd@e@N?;$?WhWa85KbZ4y03G!$_zS}= zCJo6AVaWRnLk^S13pB(p3urd52Uv1A_#w1+6k0m75BS-B8@w1J1^S?Q(L9NN=7lmJ z&}0ANjc~nY(h=`vKo4c|N3=iuo0)wOZyxA#@h|?U-y@*g112OVDLD6NUVi9@&hkm- zd}v*$Zv~SVlo!`?1n6il5#5bRLuK?0;}Fo0ezO_`!&>cV>;;i@O|bds404euG)cl6 z2HI!ojc_)IEcBc;LDUO?F*#n0aRJ6g8!Xu*WP2Qe-(=g|7#Z{d;hF~<;sQC+R~O(n zkKaN^a|uWur)3KQKd>W*z}C7D#25kf6k3iGg%%JPN<9aCK=xEDCYtJw7X$ws1U@u? zY6rY70F9FzKqV&!QL)~kbPghpZUgO{#KTk$!kZx}V)p>Ti&G1t*#O^-V6*fAH-R7o z@5@vnefZUA93BhbG#X(&LEx)c=(+Ii1xvuu11N#i+k~YvzZKSI54u8v`MqW!J|~L8 zcOI$`0em1C`9AP(EQk*{K$&{*i@;o-lEMh4rZB=09e#=e2j8@C^}JNnj}PJtZio@0 zfvyPs{?NIp%2Wa-gh7P1cuWcdjghGjVPNW6sN66n8QRoPf0zf+xY0cL5QY}CrNKO? z4e`fP)>DZvP8Zs))&m{_4t~~xg~~#Zrm6vdT|x*$k&4EJFwkBt+F4ku0-Oir$Jnn% zEbe~+^7l-7FUa6e`A__a#&tqF+D}AdBW_u=_biSS8rtjjzs9_PG8S{D-ye9Q^I`+% z0G*e3vKYf1>LhQlbB>^o#GWCvXF5nY=K$g6)SBlgWMl|%p!CtZeo%hdPLEGY9p}mED!N5MrfL#Bd-m7|$ zC(;cm$56OWThrL1!|6pJ+fSy~7-U#K^1*0-sB5o*tU(^Nm@#+M4s9=?jRoq#%sTuB z7X1qkF=OGt5BYv)bQdRp&ci++n~&_{0p#aEhfz#&8WM{E+#`N3jG~ytrwRNH#OW&` zE?V@F0!c&Y9B~qo;2UEGLyNxTmrjD;M|+DQ1v8Z4Zh-iqcmVl(1I?uvMHg}uqoCO2 zEBHD?up>fhD0ZOqBi~Q>H|xW|T3!Nnv@W#1Z*tcdFPL?-KD4%HP)9M~UBHXZsjU%; zzfu@q-!I(@K0-W!Y|*pB5Fdj*WibT%=m_$IzQ{J-1D=jBcLU-BF$`M28LZ_GJq_s9 zOd67pJMcU0i1xsk&WX=puo8d|@VeVNH|FgP?Uc|VR%Sc$8#key(=iHujx=nD)jNuj z133SdwI^Uh`@o4w0+~|!X87xy6n_zu{iE0?9KO z;{G@)q75@?@O_XQ#dX5OU(SG@wEZytM;5>0UrY`C>H^>adw#Ddv37A76 z-a)aF2EaH? zPiETsg@0!2|JV;wAT^J$wAZ3wKMXJt@Le^6KJ^{eOh^ZvNe7>j&cNXVXuMDd|3kxj zL!A%=?@H%~2>4l$2!=5=f?+|3V2~i$K%x*L=r$0elObm(L!9PF>9?zoV3<)O z81|4Hy(1Q5c@_$a4=|%L274H6jue^fW!LTpM(0&i?HR=z%Sr_?6Fw&sCipp#U{?Q<#c;LfVFGH;X zK39Q;L2E^G!@SAB>yPc`fOV!p|Etsph9B7RZ}85*K?()`zMIAlz5~hfh7?gZ%&-foxi|_mbU5_rQyD3!}&;Asyjm+N9U-mTb~H7=vgAK*KX> z&zZD0Od6h)1m~7QyN}upz;-}64$A0_0p=4D2LHo~Plk7fWVrK!?fPHu49N`iz5*hn z2@{gxodLb~{Ab=78fdxjv(=sih$Rh>%?o6#hc$eH_Yn*s24YHxe=-02UVK&+Gv;jo zz7_f)|Mu`P!bzfU2K>mcp>y-cw*@fYog3yCL@DsTLP0!XP2L!|=K}9Pd|3!fKFtw$ zqx(EJ@V>22f%V2PykQ*bhy2~2_wGH=Zwq=qo8!S803|;NDTNh->7M1m?B2Z_ONRUm z1f1s~%}w#32L}ufBwwiOLR}nE%~u}G1{kLf$$gv;!vcp^6O}*lU|s+(1IV)=cY)W( z|LWTdm0bW61#^=}crYq3ha*vvf!5{%`5zgaV9LOo1ot+Okpz+jl%LKbIj1oA;0&Pm zJu#3a^3N(zrw}CJ+aM&w58l{V>*1ZwARgXCr54}l(A!!SRg!_;mXN;G*TZ~3X9qn% z?@Z{O?j?-p0~>(!553d%0#9D3FTT^&$1{d8lF08f-|2$jt%m^jZLo7h1BmnA&}M!w zz0)lNJa_@%PlF@{cwj6m@gMQ9z`XJ*z>gYBV+Cx)M@x8cgjjelSwq!@@dy*b_6Lsz z@cJ8%9rj=2c>{R)wSKngM@nJL+3SZHWl zqLGn55|xN*XNL*iv-XaX3JvA+e4YCo_GaAP@A~%c`^WvbXU@6Kb*^)r>$=W$uJhx5 z2cKgn?NlG{;_c+u$@zmvdi@K5sXGXG^edm4@Z%h-c#F=T$=?M}2EI#fKf`~I*v&b-=gwYUtVgFKS^O^W-}I5?#cxut*Ou=4 zB>6+&f&4EoJ*OB>%wb(;4r6^qzuHje%_-tnf$JQ?Uc7ZWEEh}#MiDZkhlD#%Pb<2xAP58?4DM{P@q}Q+UW)`^Q3x0)n zjQ4cb0kl@PWYlsaCtZ4HS*wFDZ_drs9yFlKD9ywAy3r7xQJKZ<%rt>uAEuWcZ{Fco~!@qERF=Osx^ks2i%w1d@7;_gh z<}NP&b7Sr=@!4{xoIt(sqSSj7ZAXST^LG7zjqU$?lYR`^$xBccK1V9!*9!PD-pRX#Zn9vh&I;iiWT6gY|G^v;|q#)*#$+NACW9;j2{Iq;b{d=eQH^;G0T3++=8NXNVIlrHvJNtemd!4(zT8&AMK4D#1M1-dbw~9B~5no zr7=GKgMbg^KGXMC+OPJ7PFIX>QvTQck7luJIoh1@X%p>H%InO{&9=Pg3o+kHv99LhJr`v$tjL#!^kSsXemaf+WD?1~bxdvPPt0%nv3i@}I zh3~e$l5pPzZrP6@EfLCZ0$%kw`qoq53~c({*z{dnW0>v=?;?DqCH%gR_xU`N_`QVu zf7cH>Nw|tJ?_%Cx2j2rc?fkAQ#JsRao4q@Fwf}qN3vn~P)G@ZSq{MGz37RW1v>m?e zM?1j8K8###hn1B_f6P1>-h4p%kfX2o{XYHf^ncgtch>(M*KcAK(h2RmkPIr8(UiCw zpCy-n#m4%pvGa<%30EHc;{9d3HP+Nw`>pl9rNnZy&;Jr|Nk4+PYV6$q4PpaLz)CMX z^hjfYWVzR_Z*3ueEcu#ST&8-3w?}xV6mA5s)2o!FakM#mkS@Gt@v2_o6;5<4|GdTf zf{jT??xi=P;RKuaQ}TlKTpp;WwXB{sz^c6H7B1mwws;;_9i-KG%ZiSNPrn6^u}kgX zRQgl$U(q=)vrzs*?GP`WpJMZlB~SKX0{_()O>z2xx*mA_o&E~1t-!d-nsvHxDfz@c z&AcFCZRNL+^{cF`r;k7`=&!qw@l8G8Or`snFGa&`x%~B{&4-_kkLm~Ywc}%lctM+u zKL#HKH<$hYj&BZ*J=oDMa7iX^<}JQUAJy*fSbkgsjM80Sh*!U{GIcq5j)$&4&a&k$ zChs0_s*hE_>(9B+9SP8S9&on-=kTbnRL5Fd$9RiJdt$`P3UHmX+UN1<wfr6hVpm+Z1+Ot$uF+0YDoBIwgmz}#$c%?;qX(&E|% zu0w$NE&7|#S|75GKil9%bNQ=>_z}9o>ux@Z$55GwOEspfW?hwSlWMm!FsN$ERW7lfSAlw?#TYyS?ml`-j*^ zvYqkfJGQQ+R;E?oRNLlzsjG$la`>C@Kd!=Ws?K)y?VHV>ylxhD5nDJnmm3z!&8-OK z<_%X}pR#pTdY{RU_PlwcUA^78+E0=<8k`qGyWZ=0N4y0^{r;KSV{PNd1Q&;1#(&v9 zU!EB^ZMzO6Up$=1dv`L-eDFDZsAa{|L|+>E(%F-r9Y40WiuJNFp2skIHnFf=CDZC? z75of&x0=}GsCB#gL#zj@Y*qZ$-peQ-YMa|v#rYxj`s7v5Hp`=%h|#F8#iLfsqY3ax zw9kb0uhHl5wIDs}v1P^u$~eBBYWr{jaPpVbmw*1zJH|)9owVoqEk2B9jL@EjN?^WA zdPQn2GBc_0A=0AI7U8|i*0asZVUV^%sYmCZMPC~Fu=B{jZ^PCM0)GJTKLO~sqD#X$BZRTHaU;n!sAKM=S8c%TYJOs*n>}-f6AJ8 z+nnBNcq_cagqQz}4W&xjeHQQSmZp(|(De3UUO#o0HvcB(wegJG9P{dVx_=$>vOI5W z@^#AVoY-f^>P^TWZfHBF;N^0)=R=qL1eKqIEa|u8Oa6#{ z|Ix~qd=TN*I2H2Hfw(_Tt6bKOi?T}!;6kF%yLEx?iPW5~p zIN7CyX&37gtVPtM@vCW{bYJZoYuooKV^S4m)V>jc_I<$f9v%V?>A%Jt`S8XLQC?%u zOPYgpGxlK9o~1tF-25~=#_y2)4aun<&f1e#Uj8-h&$DH}PktwIFFww<@*m{m36_s) zyYxr(+-7B>k}(whCidxmi{N0Q{#uW@?Ul-Wn#dLHN-Dm z?4rW-N3JlIwJpVsXPP0Z`pTDYHBxHvJPA8mZc#-`ZU z01Xl9{v7Wb-c$5nG@#qs3ssk(PSUHOp~li`XtOk_KG~y(!LRtmL%g*<_aN_bdLq!1 zvvBuWIMH)&fF99&IeBW^G~Q~PU_Kv!5uOVzo(n9V&+=AWN$Y>2NqFvj{hgBMjW6sx ztBKWHp~K`zejjdbqXMjJHuQwFrBMKhd_NFT^~hI@y&Up>+JTrAhhq6AK6N zKY@H2f1op0n^ZpXKGec#9-%pabVEL&V4WZ8rE;N|fj_rEJ(cQj;g){6GV%-elwqt8 zJ+dP$=!k6M&UWI4o%lAXTwy0N>BbJpXbQjaZSes+6SwtnhSvD!t>nF_JjxDDrF(^U zn<)<-aQ^)%@h{z%Ku_MHOl2o~X_e0#y7Rx`_jb!i58lF`{L(maYy2?rSnwkmLq?i< zv8UNw?J4H>gu=eIofYwcc19A5jo#9+YcE^ER+Qa=tNk2x|9JhU9`I|RL$b(YVp(yOXrNES z{C|qy>d&Wn$Gtm?zkcnVQd18+CrvzLFIWEJU+oT(W8|>bI-%1Wr+{3^)pt<1?@`sZD-*zn1d|YL7L{{2t1Ql+k*D+z#&d-=JAL@IwjMLDrcYIe=zhW47|qA^|5E6VUvPE) z8xwN*)%3C2a#0|SeF~-bOGcOrhud<)?xbznZ>F(stR1VqLA_(3RdbuK9E!ixMw`>Q zynId7kzzl_-x!z0uluOCmH(>e&o=F0a4rG1?&X*l(K-eA>yopu_1s@To7Vz|ybZ35QWa_PC+9S_j{ z35!#5p!BJdw*YSGi_rymEL)JXV+4C>qoO|y{c-9(+Uf%O9IeaVTEsRLkOgB4maXyo zS$IqzA~%nar*Z~I(&vNIg>Qp{GeITkt-$tEtNU?hW=6CCx^; zg1t4#0lj6fIdd9fdX{gJMahWtTz!3waM7QBpZm5sQikKh2Iez`xdUv!Ym5qaV%xxhPh2SQb}_FA z_9#X>_RtUiB(vg~^EbpV>4J;%_;IHJpF`u3_V}~D|0jm zdrUdbMSx#CH}*5RtT>l(NPG|ST)wzyl3yhoqjLcp)#uQQjGFotw~Ue}U3^)2w!gkf z*|hb;UHnMAV>~mqt)@Gd|0MidraGWgXR_2r(GW}eHrwe2=Psfz1NV3Q?is&`d57aT zx2*T)xuG0uB8nN&mWm9zlJa$BU+G9T-N(A5iQme$&4owvI~SVxTs)z<9uIcdW4%$b z;91?dLVcL^^<|oVL#y&X&u=$oUZiw%N9Xlw;7?t05pp-Nu#)-|J61dNU-L!Dpwpq_ zoy`zkSziVZ1DEva@gGVz)gFI6QvL7r#+CaMypWvwdCQ8|+kTb2`F#Zc66DjT4_JSO zI7ig*br3r6|MujmoMh6~rSa3rpW2}O6m5(549Fp8gA6^&kJx%=+j?2Q3G&6zCpr0~ zl_A;9xOb0{b8{xowuP}1nbx>9&+t)qC`n#}w6TYD4{hR+#`rqg9HfmnNz{$~jCqD9 zAGdWZCr|uRzUm%f)6rMMk4XHUJv!?6K`fgx&`Uds$;?%U;RWNZypEd86?U$=kyZD{qQD1o`nXV1(P3$7RKD+p?Sy z+|v$+_t&=0M)I^a+x;Z<;G2Dj{~EL3Vm(fB7e}|nA7iJeH(1|3z&21i2nk&(k7wfntSQ@cz!#3awfmyc3eI~Fx@`PSpClVzfa}28@o?dI`++s z7jbwDoss0?J#@}xUZnnXHnd9iChgmsVU$&ST;Kb1DYbL&@|u&m@_(eAf>S-^a2iJ( zobl6ulf5gaM}6YpSPwSiR&aeqW0uB%p~(R_?0!`GskT%=v&Ob7ZNELQJko?Wn(*^3 zv3bu}{OU6|cB;+t1*N}^jwdXf@-#lH%|pqT{yLa$V05pW=GvM^h=z|@x#BFMX@|FZKWf_`dn4b-(WbelV1l%<_GH$|Wc!?M zXss-Q&nldnBfEBd8Cdx`qES3mT@ALbFOnDW7908Pt7~ zIhfA{V4N+K6Wd_!pgB*x`>tX< zhy7|pj=y^zVfi<+;Pb-m00ZQI2w&p-E; zGV-*j_^RdAe;HmaV()>k|FSdUt8losvCj+Jx2UMKKh@F7c)*=1ri|=t&`v6T?sQCJ zeG{-Bw!DzfF8qF=r-+QED^2h3-yC|Dw-UvkAo*l zek=5G=s2uJ$< z@|Sd#Zfa8`%LUKO*=dN@!!J_JDTXFC2~y+w6yVM zpU0Xn$T!elftxLV^<#6?L{JX2}J%^R>gCSLU-xMj}=__t_}yb|9u z{S~I|;RN+22keRQg^-nae2I|{4>_0oNnV1y_G4B9wncm_#|0m)oW2)V(0}-);IILv zZ>Z0g`?9`4XNm0_xEg3vdC}%zMWfRX<^Z*I$+`Q>2LF)0(7hLmLpIttWIg>h#`fFL zH0RIhyYB*b4}CU&P0TxhKGXhYFNOS&uXUNG_?^X4l0(@x-ShCMO@rL1?s^C( zjo($!x>vZY9=HA>*@KR}#*&H*zG54C_mcKKr3^}|=km8%nohB4nv=DFPx`3%wq!#%-?xFX)OkE`@)KMP zRclg`SMgM1h+tiRvfgdR58-H~KIMfio{yH{QCv=aAY77(Af86@L{BBOJ^N>$4#oDA zCY$usi_9TYtViy5bv{>-%a8SDGah)X*=k<7pg7&i&x4e|)XL8V7H^RGUYE+RV(myo9atWP%7G4B%nN6N?1 z7-VBr#EH?Ji z#czxs2tMV@pH*Bbf;`mp4Cv8T>}Or)vf`7-mG+m*zIcXi#yu}rt8q(ywdTMMkNn^u zj@Q6Z^S{*d3t+wju7%JpKi~j(63()QX7CT-jzgpTydZuPH_I(6E&x`3iKD~KNrJGf zIYG-}Y@$Cu6fVIBVOTSY;)9huueZQ_)Wk9>*+VlDJ(Av}Q_G53^%?Z3twyifh*zR7 zk`?rISXDeX>~i`>{s_PGk17xQhs-p1)Nf=u$+uw8z4^Qqdu@V;jl8c^+bNfW7kbAe zw>j(~zavJ5{ohsmcJY!5emnW!O*!r>G&;PC-%a-STjDJ?qn zG{V~SQ%O_oNioU~+q9G^rEu6a6S&Yd#@6w*46RjSZE* zBbX(?$Yv*aS9PM>{2uAz%KX-NWB#+>sOjk4CE+r21FLV5o&lX;Y*FkezYW|Gl0wYSAw{-_u9It9B~iuPghw!5xO=+@kec}Gcd73}*T z+i~vO!U3J?cWg;sa`B|idyqW0h9DXB*U%;w=E8gVGqSTc;EPCx?gdtS5iRmT#T%WW z2=dU69cgYd*TAVw_0+5W3-$+kZ`Sg}zotR*vwPL$uUlyh4c6tyj-Z1&6vI%v-m&dc z>`1gnptF&@Pgz;NoOILo1~RZ0oEiO>G>kKRyGD+AKbZpMt|@*-MVbTRh4$ z`>%mlzXWL?3rvjqMWgBw9WPiqkon3($yeTXd922T9l1UWM*z?N_*}Z9iha8=95x`V#q)9Ey%0jR!!(Ex?I?j?U_D`}7b; zZFs+}yD1J2t?khLCBsNJK6KjmX+I?!K^t&a%=jxGTR!yhwry`w#*YCo=D`!4Gkj#F zzwgBOH7WE_xY~00WB1_7)f)Q%-Q|8uQ#Wau+%VZt*`#J{h29HgGqS#&>eTO?|9b(y zolT#obZocA3+;K5uPR%o{Y8>tH>NB8?R*)0z6Qbha=15~S@X4i!+3CO4E)uqz5NFH zovK4I=@@mqV(q!{8yKsETYcrzvG*7%zd>ajj#h9yW6LXk)QV5Eg!*JF**6;vXE;|* z{|Kkig9JPXwCfehs4nHpPmx~9ZUx6}`Bv_nislNE4dIG`>uM{*KL*B>B~N@2jms=u z_&6pmruIk&mA9WQC%?hf@7k+)ez1P|4T4eZS#%1&+8u+H_0FQ1 z|DmI1{+Gdyz{?P0sbtm62iU7tk*4q4a`~B~G|r~Y`8E?%U@meP@M=e!m8V~;pF8~+ z=|k`> z7gv5wB8AfY(q3-Y!-W7h3ESw-SjVbp8JLPdv;!U>Yz#TCVFb1r}zkG0r}r#eI~Wz z6kEs7O&!E`ZJzeI=?;ml$f@f63iW#2kKy(W-OhjcUmk19)rnl*?HhU#o`;z0g)_Gg zkEYqb&OA>xjJZI`%maILr;B2b%mL9W#d7BMEZsBb{}JVN)*#IN7`nqxF;cdik)ff7Y|jhVs)~o zil4}S$S(OZ!+m!aj|cw^?*n`{IE?%a)KzQwsj;{oy3T`tk_pM7;@L5q-%kDn^1AJw zqLp?}(QW8urPa$@4)pp@S9!{YNZ*KziY~2bT}Qg)Q213(BYbeOH`ccIbZD=GN8#=> z`n(MKgMNrtlK+t8#5*UiyL7VzUywQ4!c%pvR{M+z|-;O`hVamzirDUJu}tzBo8^!^n@*t1AA>H+K4@xK>?u zc5yBIQQO47xt4!M$Kk`Dwcf;AeA&)#!@s!JG!_=`x3K6$gU#2G z?_8|rOzB__9V7n?e!FET2!f9Fw3_hTQfjC?2MoBzxo=N~CPvetsE zC{N?E^h7!~G&vA+{*BRpd|bx+ayX6AE|&Sq9=HK~nl}kw5bkHd$!53WSF628+4gEI z6FsgD$+F6-UZ?ZwAN;R9aFTiXPA=Z$Xz32X7+=TIAsZINrTJU1PS<|nOF@gn$9!}z zI7eF~v4oh&z#5b0Z)%(JV+qag78Q@MzPw|SE-e$l2rP@l<` z$QN`xJ1YRAJ`jxhQ*iQ09o(t59@X!WCmPPT^?X7&;){$t4&dM$#n$(9I5;7KpJh?>V0yR*Y4++eaGT0$DwsC(NPB-4o8+c zd&}w!+47Z~fkBokD}eD5?NuSK*U*--`PbTa1#pz9bou727W}Sf-AcAbV^>XLVR16` zPws(+#9f^6W&Z+k){r-0SR$UQ#JO%rL04sp@g#9aZwvnW72RHcJ#+LV<&xydKh?RZ z6TiiH&NtO4n{T1)@$pML6ii%K{7W;pOmG(o zw2g)~|GXM>3NC{V!KY-1dWS71#}v<2A%$=dDjryTRDP>S4) z+gB~rdpz?F=F_DWY3`k&thp}D0`6hTbhO|Qu@Xw!` z_$7EZ0L`PK!NRIf1ltVkm%u65{ee~NRpYC}9hAFpF6PDPgYM-q zuY;$abwuS%4Cvvql)VE^& zu03lfI@5vt8GUkcVEP@M*W6b1!C%(w{60=`4@!!@RX?l0onA^7@$nj(uhE@U_6>t#sAvsahFY3aXYjdT=dH}wZYL(zbS5}e%BmU{p}^_ zd+;5bso2x+HNdRSEH74(uX|00faeZ)e9J>#eeKIk*zZ#_PpAE( z;$zSWctjhd6Rfk8I1}vi&B~AVF5G7E86Vfn6&${*6!CR%YF)A2_Ib1IbHU7@ocg>5 zxW&Nz4mii_+BArA%#eIj^?Oxp$Rb1q&lxZ^ed4Us_ZL zGOO{7a=xw`+m0MtnH3&a_Bim9-cHPMULN@i+L}FW0>AD>0IxYSIyx@<{-15%^8X*& zCz&yAq+OB;%^fRJ_%jLF(+S*3$NCyP)%U2?cJ3;Oj^@99n|UTMT5AQ|)WeSTT*a?Eh5yZhpeI1$Tc4{Ugo6>b#3!$6DAH zVBJ_T57;;9v+~$n9Wb*kzFEMOfcYB4bbKx5aUY(yoZplA{Q&P#yv2h!?XO|%^(e>q zLyVPgiX5joCEqYdFHhMw#h$Jd_Ap(b*gWmA3whU>bDlaIFB)}5N9`F${g>GKFSPB6 z+qO%Wv@Rle>31l>ljL5^tJH4cCKibA4sRQ<=f9k^WCpxdHvB zGnoJ1T|9}tVGOv(_#%wos!O&&>sDv48t9+Yp8nyUFKBF|f6Di3oQkcUYTI*IpnnAW z2k6_fIL5Ib&NowcHE;U6()n(Z6^+T_v1F_g+F!iF(2S1y=evJy?`KfG;$H&(&9n6l z3)Cmsp^O=mXHe&UmM7}FAWxQ+@kB8w@#GqKLQL(R(LKm8_;t=W65x&3v%su>-SyT0 zf36MiM}0CFf3z>p@u%46%ddm2fGKMi#XK&>@%~f#_V(rhda-%`lD<7*>HTN)?NMO= zH+}mCFizj+eLceXuE-!9? zzq(UXdy69IipC)M?iz>QI7?%5y1@9csatSm`CDv0wrrF9s?NmnVkdAKEB5$k_<)Q> z=6hE1gTu+$edq2kynd`kywP~N$M*sLcznh`V^`2sW2=-u8oZ;Ee4h#WM4M=ofAfr` z0oYfN-)9`YOgQGvhaX$6;VxecsK%c4T`}*W$^ehjgYc*gy)TMKXBS%G(P%R_m{=IY z@77t|b&4N47{98aDQ9V6U&W?`-~#+o{t}yisO6W3U+Xb%5x?|p3G{i7AAO|!(CnN( zha+luX8I!f61;c`UI?f7;dqg?_%U*(KXi9;4%qVk7|cf(o+|oB_5HE#z5NsH3o|#g zeIXiL{h5Ez7v+7cb*&`*FrWVDX&dMtzCYtFt%!MT3%PHZ_x4ZXlOe;AG-F2`-!$XX zC|cNa*2lN|`c4zA%*Qa5CT3YLd7AUoHnqiv8hs8{Vdg1k>7Yw5uMVf&n|F}y+X zTG4zS{z^FE%c=ULX@+O^Wl9Euyw^NiYdY$K>Qru6HD|?_6W?a9N+}F}(dhHnixPJ+ zw7$QLR^&d4?I;kJEwxyfeam2IbX09&Zd&*dZE&L4U}{LkN@?%{V(xP%q2f$<>LFa z)75(g^*%(S?y=utu;-xN%rBHRlCeShA{uD`2WCl$Up$UE0<{?Z+LUY5H9D6<8= ztB*FCKAKD)O&*w2>62Mu^4^Z`+B8AD!Uy>6Bzja=lV?X3~AvL+4KVV5j=Z$~Jd2Gzd09 z8QHL5#MX=rOUs7cTD*WViMW3k@ck1)ChtJ()+%u5&fmkx*BYmOpUUqg_BXaII&7aw z1?^|ArahA1A@JkPYXkBtzuENHr2HYki4JF<{zyD1NXLofA8+aSilu|Krsqcu^J7UG zN6&@+ZL(R|_|eH*&G#!cHY@K2^8V`q;k3F*-3KIJ#ovCl_!Yj*!Z-U0)rp@J4oE&r z+OtK`qO#{~de@w1asPMx_1*sG=^On=W)08QmeD#KT3ev?Y)dES#Wo#h>uMj}n}2|( zlDdv7tLv&A@AiMs;#S>TfAwzvclbYn_LR@#BrEda{`di}Uu&U3c~VSNu}i^hC11F7 zKV0wpnDOOg4)S=yBTsV1SgU@n!X^^qsrAzSIPKfU z347VbjmUxYYyBrwv+s9YgK2~|j`4LvmSCq+x#s|ftBo`OjGVC)ovMl<~K;AT7_+#s&{I3|N9F1M% zA;){hl9ZDf-jbzVbFoL9@6vj?@i)`5f%u-@fWP_jXNUviA7RQG%(^md^Zgj(zZbj= zK4cp{Wme||)z8R%!uKCf!Vh)+BQYNQ$8)(4R`--HFK#pAz&XglIc4L(Ie~Fta(;i{ z|EF=F(aNWz&H0L5)FD}(3-6pP4=aNmY&<_x{lNGjze4>Up)D^y=8q2=FT(u)&NaS0 zWS`z%IvgC!|61>l3EvIyKR3tM*%`bi^Js11^Uv+-|3VEs!}h>8?k;<3TiYGTBYDlp zkmSchJ|C}!F4mjIZN#4AZxF+TpIybN=D&YFYy0E=o#5j%rlgQr<`5q^jQPCi_J}=y zjNeKBzSe`dTV*BRELgb$-M}VkKj#Ym%Xij)?f=(z7xcS{-<|e%g5PuP?I!sAhKl||M% zvwW_7S@B@en@#t@fT-%JOyes7TiGpppnYSKvt`8_D64YPZ>2SoHbZGW=|1`F+|XX= zRDY7Ey|`DBr+w8bBY3YZS2@k%xWwW}l7F#HI}h2FEX07ld5HSKzpvlFk2jZpSAD?z zU^;DzfPSMtk&;RSdC%@jbF_j&zx=$x9(zeLZ!Wh-SJizSd57Az=m9vVa z#>(Zz<{o(M-O+nQl={2VeWJ6uhkfIG*P%M$kC(cS?vM(fK8=2Ep5^aI#@WYElDxh!l(k>#kDqjP{sF!lR^ip=y>5IrW8)?k zrfPk^J6DkI8$4EKASya@jMHhY(V4wS<{qM!*L^?jGTNy!Pf*73d~ASr$MfI5-|J@& zufcy^0Dqzk{|L1Oo+d1Q+H3INAHcsITj_Y?@IMEB_*V+iXRdEfw7gs!fWO=F@=4$& z_YU>|qZ7=lnNuUz(PzO`0_I`f^?^M0=0)kd(l;z_#q&kW597H)m&N@6$2kxdh z+)>UmlV{TV_~rudE}rePW8P+-9-ehPD|s4uy7!BDGsece>HMDBLE2++@1b_SZS~!_ zHCkse8_4g*;LhMtj7IiXvBu`?vZC>&PhozQLB~_e zw^p=CzxhT|CwC0~UVYkCOy}+{PUUw?4`XI(scbW@$!8>Io1)B-ShJ6^58=t-{KnsS zUNQKQq>b}*FMYg^`C3%-6E|PcIMbXZekq;#x8eKndq@hJ(tZr-m)-u@ zbSCL>V#fYHY05y8Y)%;YkR2cv-f*s^N%1E2ooKqv($x1p@wm5e2Q;~}1?&fA52x19 zrW9`Dci7YKG&029Y0S+#fURNwZTKhidxt>tkU!ngc@TVpwigLM|J z($aJR`Ldy5@M|sq2HWPjR`1nj_pOR=*fviPZg?kNKMu~SibY#LOZHUf-F4=swL3zKjZP1#jWb!fUaWZ)#u#MPd z2m4bCtFze-*75!*!}|fet8a$CJg(hZ!wE4r)%qK{Q!5>nEmgZKZM(e;-zz6wZPtDj zwYiG6eNFAcPsAbKG{nQc#n~Ubn>74**-p2&Mg1jzUc8uZd2uEE7EZ+b*b~g~e6H@! zkGlKsBi1%NLb@e=r*)l=iNDBF zFzpYvd@fMl@ofv`C3`{mF?Nm9*$LHmtEF#aS$%2~eo2&Z#KZ_gskr&xOBDEO=+Zj% z#pt%ypcUuz;E(JQ-z_xyCjYtWMBn#|1n8S>>sw>#)A;@d{VpF-^E>sw=yJOJ7;tNV zF?)rmSAA4XKOEv@GKEa0a?dE1;_k*UFwi5oL>b(-fa|dJWe2HG{d6~V5>qdUCMOsB zmf=}U{^^#VT5of7&#~>R22VS9I1^Y}dlS9}&m^8Eo>gCpc_)OpcZ0Xqj~jV!xKT3g zuPeKEB)+_OBlu*aj#=)Nat3Dno^KJR)7UTSQ9RIN-};-g-tDh~KRWZbfO5^t8H@R^ zZw`Ky|4sbYx^^@Fh4W{xhK!5}rjvY~5BwnYWT|H{DC8%jNQ)WDZ-mSl=pKzSZ--RvfYgf6LIx`3GqAavhH=ZO5^S|196i zdE(L=4=(4<^no>^rO-Vde(Fs8so=W?UaH;Ad>@ziZM5e!zE#LKuzUDMxBR;`-}lEF z&7(p+?7!gK#EHahe4qKYVys*J*Hzq700;L!i;oP7X3ni|Sey$!<>$$7hTiKpgv?oR z%?Y1|j+zwrBHriqGuJ6SjSLw6r)BdyiuldM^!+|~hd$7E3@R84?!o>@4n8ZoX#>9G zrp8<0A$_2ATgim-&m-S_$5ZFD62ggWwNnT6R=``W7ix}+T{ATP^cLb<{NKR$A4P|3 zMJwOto(+9Nnd{=~HLN*?JleIIx8&ga^jin`BnRKG^W{MGoTRp-JBl~ZF4?2c8+m%& z^wCB9zUl0}zp>dyomWtgXji>c`Txz=g|D+u-%LPe&Hb5PmhT2+bG7lTNh@4v@t+#N ze=@(D!7tr0Yg*uJ1mDB}{_%X{{SJ%2&f-54TotSr)@M8JroM%zvuA7@aSye33vVa) z+6Srj-e}vKvgMj=xzUtcZOg41q}+5{?kG#UZ+m^-Tu$G1*s|F{%6`_C9YNWt7A_Nj z`=X_7qJ{eaaIJMdFJw3BI8P@ziNlLJ`bX!Io5`2mQT{f*5ozRz{2KCyibmmthw4|! z&56i~N0!f)9Jpc)Zu^k+4$|oU*PASUF z|Fi71KL*|+9|gYOT-tdNu^8%edt~1r?()`a;6}G@q+aQvbnL`e&{b$*&Dz|{q4uo> z_R(cte-CdnM#2*(V`HeZkNUnv9d&7+j}Nk^zXEzfwDVlU$1ditUBw@$KPW3b`3vyB zO!{N@bnDAJP8p36lG$H?b28~_<0P9eTi#~#pCw=Ye>-?`q=~MmrRxX4iLN!k`~kUe z^LNqg@&vnzeEIvbaSsB2J#Ez9$R_wK8?CboFMvOSe1&-=8%Jl~?O%tlA)6uEdaU0e z{$B|W(S9Fz)wklOWaARa1$dm@9SUD=Lk^4$1?LF(-`OI%ZnFcL!>h&f)AZ9HL_+mSU*;$IRj3) zV<~q5^k^J-^Ot*%10%t)M7jnY+rPp(J${Mfh1R;oWAS2|rQ>|?9R$Akvbc9x$n$z` zhlk8y(I5Bz~0BR`in6y%X19BkK;-3`()my z^Q`+q%$vx&lefOFGl}qNyH@!6R>Mb_Zoh@XwN51Z+~m88iJR{9|}{UFkp z1kyil)3pbPVDl84Szng7)aIqgTUC~Kx6M19yrpG%U$uGKThmdNH^=6UAy4}if^=qW-bv(5 zD$BdU=4p+2bXnfDHc#i`n{1xit@dAG^YD|*onGQ==;Q6gwr?$JzN?sy(mcNBUY<6h zg*9NF^7Jt4(B)|r!8Gs%aYurAw!Vr%Xwdq0Io|9bX+uW87p@|Z)`+f$c^XfNc{@iF z=Qy3XDLUT4)5bG}XDrVso|HF?`2%zD6k|NLN@rBFe0`R=HQ$n}D`@XQh4~t-_Mg?6 zIb}txu7G{zzRbG9p~|nRE3kgs5F#D@q?~`2L4CVB=F2>1qCn}Vuhp6cJ_O;_sOs9H z7!R<7W=;AI{;O`?*P-<3`}pab!J)B7X-yWEm{L^qD6XvZBWiqD#qRnn>=NSlZa=2Z zSO_j=alQ!LMhiE?mgVk+hF3_F&M7{jeRy7iIeB7)85?d&VyoblmqErzr@eWNQ6sS> z-#(b}7@IZ(S=4x?^RnMCu?hJ+eq2DZaZb`7r$>QH_Fd(lqWmK85g;}5y{d%f=KeVI zdt#Kq@{@OA@3FU?JhG);3V$8G3Z@#~=)H^f=*`sCydSsuYwiDsY<`V>H^C?Mo$Qiu zMy!1%*2;Y}zOB2&rr|F|$1$cyyjp!H%j`|0e@s1}wJ?}JBMZVeiTy8zPR-MxwHlmB zdsYDa(W6XEJ6)KR?AjlA&~vU1TG9#pGh)2jV>v0=QA{WN?~iSVzDcaLnf)}W);`5% zB)^kV*&@NvhEZle(nSB;Sj5_hw>KD{Fhjo)8eVV$ZgKArnwoOy{6y@fU8uj&@EF<>?B`Bs9jBc;#Km`|wX;{6GY{ZuzdS%a z@)N#$k5}5kKHxR@1M+#=-~p#fwwhRTeEHU`)G7XG|E%A?)MNWsap2B0=LMkE&20|? z?}zU7<(K|fthA6uPolu!+vF!FI{Jz?lAqyQSMU@)j=K2m2+OY&?U4<-k@h=T`HAsW z;0?0UMjJIZ{}^@6y2tm!Wrx?b$Gx>Yt9Wv>sg;Mh2xC~5czKq!;4Hk#vPP5Td|8(J z$g+HUFIybRljIr2)50^FC&e?CXB?0EQaosaR>g}AU*Rb>wIS{4J8h}HwAX>moBMh; zIh&RCvVD@7Pd%b@eg54*-+i>g$Pz=Ld7mHA8m~VW34vccQC~S;iEpodi8yzl?=rOe z6x!|T(OWdOT+P`P>eE;uS)PynI^8vKDWgXdb#5d&gFNbDe*iuiyv&001aK;TuQjB} z^npj3^wdkwqHXM>l%66px4sZ6{q!YYE)*N;$F4frpG6tXJHknS{`gbdhZE>Ot<5Bv z2W-0vzkOlc_>d1lhh)vf1;vMqbZerKH_4W0bh0HHhlxgPqt0{95RJ@_42{sIcHH`+ zPZzx0mX5$&yN18GWrjKeio=o^P#&H`qR862cyJC zcqsd%{+AtWqOauZwF|$IzYgxgVm}b|8a;*9s^5i5FWnXQZo&pl%cA?p%7z=flHU8= zi0^LYER@oE4zbdBcK-@+t1W6n935C|a4$fXsW0X8dlvjYg?5T3f5C76Gc?Dql#TP{ z*5L~eg3q004&u8dfG=CWA^eb%NBkenB z-=pli#lFYc_gMRmc*uaKSZ%gXI*`7Txh4Ig{clSXJn%;SBRz0q)?>f*WkhSJS@MHp z7UOcXO=)S3Lw6VN1a>O_^}CYztH$*-J^?!Vm&QSj5!XSNllSAHOJ&gI($t&dUd#Vde*<+)`3Lpa z+xj0atN+Jk_0I^@|A9dLTW*Sbt1n|;2895)y#g}H%9=B%30pXEcq)KCmHZ zNGEP3cGh0Z#BVKb0zPcpC?Dlii(lh~+7N8xO7Ls#@HGoFDL}82s|SFQTxtDAXR@bI zmu!wleV;}?*z;N%M}N=#YTQflY@5a&Af8U1sXWsb#Jw=@-bBOSq_3*LI_L=-Fox!0`Yb#SZ_Nvl%^ttY)LtkqD&bTYRQA{b5kPb~KOo`vU z|CIPGJo-PrkV(wiUpQD>i}uhq`NT#Z;7-^IrpD0dm@=fj`v$`9myi9E?sIGxK+Bwu@T#!|oNH2sFJs($LXd{0`w ztDNKesgw)Sk-jnR&7Y5b=h<*c%^M;kto9taF@nBoV0(0$)-sj$C(=^G z{j-_!Gk#_9eStbgR`}!L)*H|<{G{thYqV)SW-gWPn@(Dd$|p3ZL5}HzHGdPY(u$Wv zcMMxz+(G?8v&wWq@K;}cI4lXhdR_$K?N z@+sbuU6pm?@*^hp;*ZOM{oyXn@zQ;)gGM9X9LBBAZC)?;#`Y{O)^~F^d2Vqr(aE=N zvWtr&GmDE}Z$~lNtNf1Qs2=XL$0u&_bVqy#=S;a{J<(B2B^KiYb}*+9jt+2ifTIH( z9pF%Tl~p;F5xihKn13wh=_q~)U11(vc#?P4%KBV>&qQwwU#$M9T~2?lr(Ke{tAQJf zeG1Nh7aNfn^r~NG9NN?pIzVd?=*2f>p6C>gB!n}4$%84=yhYgbam!MF?09G z6xtS|Z{<7Vzvi{y%AB!AHeW~fTlueYlGUb5-!W@jk}ugcm1BI&zxIyw!I!fUXZZK* zx!9ZD+pfc=P~Y6YMNOT()ai7YCK|t6a4BSG40xwb1|K$DHo1=fv-BVRpZof@xrO3U1QVUAT1pCX};Q~5zmS0P6nqh(``CyTAUvm zNWaXcD-Nmoh=aexroT!$G09SV4s&K=K9gx=g69poHfj3OKhG1ReJRDr@G&ZT*w=^8 zD<6VAetUdg&QJD-dgKRm=#m&z$5T(!*H+cp*O2XpbcKmT1nddkZ*c)UR)% zi+_q!M$)o@vpI|1QT)@n$OL&+V>)`Zrq~3IP_OStM0(`Mptr-?d&9lNLA+UJzxsyR zac>RJ3?9j)WaiUqH@uXbXdZUt-63pPDr7=)-3$FV zUsU~I`d@UjZm%(;jg|Dwa?Mo&^1}Q{yxBHW~Sw zT@)>K8NskOmGMU7{6_o&l}(TyO5WO+NOlzO6>pHgCgg9;Mbw#rb~A7AV}EJNJv2zU z1%Yz&sarat`V$`Qrk&n_?Y)gX?Zu|}Ek)^KC2dpt|2^q~-Nu-@OLV|{*_T29_nS8T z9@5up?6tUEI&s@*cOZSch5xF>J)gXyO}mXW?yf8aW#9?rwfQn28@R#3YCWi$x_-|8 zNk^g&@XGXmqFw7628ZL}LjfF;?Pn|wd|`v*N&d^%b~x(5aVt24U;I;(NNo=o_=?>{m&n6($#*k8YmeJ5YGMlheX zFs#EEe!BE4Y&!cCF?^!~v9MI&cWdCc?t@fpD`nrU z_HEAMV<#2c8i5V+#?u#_j3>lbDzX|Mm}|A=^1YmYn`G>jA7@c~S81cI4P#B!=)2Cj zYJYNdk~4ACC;tYW9F`zoF{|yIz5FHRPEKOG@TI$wzAwE9UAf-s;YPcrr?}&23#WM6 z!5(Xgz&YRa1>lU00dA~?8yA4P+2YgMtazz28)sU$<^WvQ!aWHbwC2&5Qg}K(&3WuS z<(a`Vj_04{)!l>eN@=P854@T~xeG1Lj#rD}f#cPJ0I$xsaE@1kbG&K~@ahr^=XfPJ z$EzCxyqa#|9Ipg7%kt{#0IxP)PP}n4aXOx{JP982%~kqd-(1zc(Uxw`R_2x!Q=Oc7 z%PuP(F8RR^3L#tO%uzS-Byki~GpL6@`3`%S5RodrFOkaIejhqchskJ}qGKsP%eKYw<|nkp@o+S4k?-NY|2oIQD%K#G6RhLU zk-#c8c%y}Jyb+A!b#ocMC6{44&y9J_JYgPxEy&kL#jZW>fAYMGdrdm`X@>b<&3w^6 z6O}f5tYtI3lx$jOammjVCzH?Ne{TibRk(U5b|OAtXTD26$!WbtE#OJIK}c$}}`VR|Rq~3Hf+V=jxJ6 z$eUO=4;e|*m->AOzvc64PhEZI0u#4m4@1%G_S+K5oMXOIAUmV)8hU&$N47}kPfx#{ z{$*bILGmOwYUihEr{4M>g`eW(u`0`%wwmsaqQ(o2zg224d1J^c=lO8*LhwR$M;J3} z;EBGKfSqZeP1;YwJ;wAyd|7cS{c+tw=t!pfw680~{~CM+-NU9eSLsOQ^Yn#juhxLt zi$|!=RC}=!8r2@b?7B^|>bI?qcKPrV^O6l>i;NwdAEP}=SH1EFucfZBsyl^@8~h84 z*T84l#F4Ve#49u}n1THG^MN~hJ4`+4g65Q-H`k0`Z_{3UwbCuLS+-mH;q~P5tK+$X z^u+CJ)cvKGvhPB^p7I?XSE$Y8eFR$YdrB)WCBA)j%*)^_Oyx;T^5wL}pC1{!5X$&= zA!W{6s$bLQjF0Y{k^ajkI7t0VU$!CdAKw@%Wj`PH65!Jwpi}^tU=9!9(L7P}TH$zm zo^ae<{Ic3@+BciJ_!clY4+iHbaBAJ(#Nt!z`#^>jH$5I4ioF`WqHQNCesANjwWcm# zPn&>?$60erA6R@)b+!55<FczLn z-mWh&59Iz@wOKyL5YAXv8s01~?vwEQ^HKOCUqScR?!?z|cYeN36sa%|+Kllfd0-A%!V9DA>!@icg#IRJfT=Cb$}51&d}RB6cNPVuUYUCvp+oni(Jy=Mcn_JgZr=0i7yRXI;;Z?t zXq@jHf>$yueGeym{z-@LXHCJuQ{JrYZ&E+92OTV~3Z{={r09x+_6vKQvZ_ z#Ygl_ee3R`myT)gw8r@)Z96aN+c6hM{4w-?9(avk$FZlv`2>QUc^2b$z@HXhwrfnL z4~-l`1NVdY@j~h*Ce>%^&7}KSKiVWc+oz5GLFa}bgYuul^jUKc_uwD7aI0w6SmfxH zEJ~KNr@({eD}JZ@xF+SX$7Y|zc4(3wG-Hc=Jz%d`M(1R-5BJ(aDCdu<9}UnXJ&=wW zzq~Wuhix%*g|iF#MAuO8n>HA__`V`^sSNYjJ#<~C???aqUZiy{nh9M@i?Oo z(yMCfT2H##Aw5wWot}!f?l z6KC;cKfW)UKZyOPwRXkXkAH{Gf5v`XItZQHuO<#(W2|A+SD^fLSL1bu#& z?emY?K6kce(i!Ys4%iRZ$FIJ#yEF>Af_?lHX$jKef&HEuGsO?1>(r~eNw5`p*?uzy zAa{~o-}kIASsyZPnK8huuhF-z58p!v^&2{< zUw)wO-go1WiLD3d*i9UxoQ_G*&8Z6mGj->@O^LFg2}R)BX}i_fo7|A1e2mhtO7bo>ka`fp;p8-gsCI!JH&KeQp^kPVG1&M)u5hB&``yot{b*pN}J z++z^vWAWwx!Y^<7C;jqqmn#Onw_onY_TT<}cWF8?j-Z@9N7`i4>i-SBJY*1kkY3h- zcf%-OFV8HKBWK4RvFXl^y@!r}K`$eN&@ulKUoXc&N6?OS)9ws;y5CoJtUl0Zj$d~H zlL98luNz4lNt(VDAYWX2YyVZd|6A5j%I$~vwT+n0Lr44ks`v-|x}c0-@1f&g;MbZ# z=*U2W>{tRig8Z6FyA^YaSbjwU{8HR>6#iafWTMv#=kkf@LA{+L+Izjk#l2row)c+U zKDYJ*+k0=}x0k%Qw>{C`TXAH2Z>5(oG3K9N(fl3GeiRjVuH+kEVR*{??;htT>W(J$ zk>)IVD~_h$^o!Ql3vb=1`Hb18&iTV!VM@YZtB^}EtwN`5Ibt)X@OTWc{B&n zIaA7*eH3x_3W+|&VAGV<9SCt~iBKj*y?z_CZ^V})+8fngi3z|qfrt6yp8Xg{kY?_* zN_P}*ghrj|R=avHj(a^k;Y#A{wSGG^2bbTiSVRJRBSp8*o9LDaJ`W$yG+~rLRlDx0G@|U%@FlDK9)bIe*=Jq#qkR{j84R zRnilS=jt*%Q;uT3OB{YXWhNcu_g(!_{x@xIJ>nMbbmXp`Q96%#3+G)PGxZaOYZyuW zBW?Yz-c8`BKgzH7*0OrXm({z2wM9q!%aq%+j5$C3tNkeEo)p@lyB41%Z#{8-GnXMx zdOrf1)?CAWz**Ykd`Iuy z$;W+Whf*)!*VFgj3l(jAYmGCOp~NRm%!gR3sYAM@@9KuS=djo5r$yH5OY4x;b?CnM zZ}@{gDjs3h5Zaa%zXUysE1B;yvaX=KYe-u{8NoMMe$tLTYav_PC1*bXc49$trZqCj z$28kEC$kagRNEEPjL{zUD3s>17eMFqr=u6?$=G+^ao!t7h61UPSs))rhP>VcR#%-pp_>5|b@dO*gGhW^3y>Jii40lkXb_Kvjem9Fo+fc0M+3++ve4wY7ZnQ`+tjKFT;7dc0@@m-4=Da81&>3$%6lXWA@n@-sBI-ND(BR%qMs zS@y_4+Zs!od{gl(NZWEt+d<%4Qbrpw+GzO3T>hgxyIaG3)v1oW&p&8P9bCMgvOfPf zV;Z3GhCyiDZfIoOz#d*2C|40EcZDsdIJ0=I_Nd%s+Vc=W_7>VBJBnWr(%83IYcSG} z4EBw_`vQ8>v<5!q(tSz8AHHR%xKanP>3O6RcRtFduU5Kkn`B0N!q+E|nIti1)`zQ* z3$t%LM~tb{zyIuYzUQKtbkkD4cb7bs{e5Z0)T5h4C+k1@o{`rLe3m#d?G&u=2&ZuU zl=51?pAOuTo(0^+l*^}NgUPD~rmkl}@o9ZCric5$$=d{ME3kYUzAqYpjRCs~IQH?B z^xfIXoeNld7{C=Fe4y0`) zjs1}gy@9mNq+LwfmOxrBY3Gu*Es(Z_v@=M1BapU@w3A5N9!PtGG{)P89f7p%qOw8mB+#-?yj zndU+h_Vvg5Fk@|_Jx{E$a+lrXT$hj!JOTfdIZIo6Uo|o*ICF|<{U;^xy?C{v~rt+Ptwph99c*+ z2Zhgd%*l2kr|O%}uoogyfxQ>+krmBZmvcT{c3yqE9X)lnXdC){ruLR3eOq)N{h>2f z&K9kc{*y0TL_Da}L!PrmE6F>FJlP`o^$(HfY*8n9E#%1-Jx^XIdCnHiAn!=>WQ(3A zZzg%p7U}y;hma>*^cZ;=@|-OiP2LFdWQ!goZ!CGv7A44QBu}>J9`cgpIa?GaZ-4S+ zi@r);J$cR+>3baek|$eq3wa)S&KAk9s3uRg2p^@i4cp*sQ8#&fVb|EA%gK9*JZFo# z$a{-DL9#`kBX2c%&KAui@6Y7P7EK^8N1n4qiiz}-CtIXFAM#C|ElQEMg*@4!6UcMA z^)dQY{jYv){UY`WM@4g{aYx6z-{Nd`AL-kx#MwkU_$`|?mG@Ylkvwsp9ZBpH&l;W_ zPY2I5o^d=$o;seLM{s8}kJ-!A#`u=?eYeUC-vwaZTXul+w~_3RyNVse6hb}o`_}J= zAH6R!*fYO(zyHVF+dxTCT>byuGqbzHu&@KHW?eVh=%PeX2StMsbx>4{FBx706r-bJ zLX6Q>F`^P3V3&7v6;MQw@f{7uRY^34BrBjIAqhlHkZ7KHVFFov65?YLOi+HGZ*@1@ zY!)?|^FRM{rcU+TzIE%?t*TqMs%}-cR$@1$Sx-vkGqxE=W7bQJxo9o#Gw6iLjaz$H zXY;Mxp#{kVqnpD#lRI;0(`vI;|HiHUcOx_0 zxvlmuoqiv(%Glh?n8*~u(8lke&E|RaG0;64-dX3W;#*4L#O1lh{*5KhE48&8-PQUb z^3lA?+^y`{N4|cNT@%z#`d+;3B8!kzJd7AxyTJ?UEa9!;eS|PXF?d73`!je!Jtn-h zypIxwDh6*Tc<+E0)NR6B&-+Tkxr)I%7rgc01@)cqHt;@9NGS#{1>R4<3+h1Oy}|ox z!brv7jRfyW@Pc|#c$;`%Ll~nNyfNTO&jxj+@ZRQq9pPfd;9U&f4Df>bQ+PSvJA|}i z@Y3Mj1YS_53U3SV>j~o&gEtPmZ-5unv%=fP`@V$nioqKX-UZ+Vb+7Q=<$XWG)r!Hp z8oVLk1#Lj#?cjZa(4ZK+2JmDn26eRX-sk-Q!UVKMQ`^iCCiQmL6Lr4T*WD}7YyUH&U3ZVB4L`zrUw6;v{qK0c zlDxDYs+UG;R`6~a@9yGVHSc`g{Vx6WDc(K8yA1Dkq4#{Ml z^Ul}ZY2MA^T{G{F{TZq4T=@oon1bYJX9-ub$_l6N=q zu90^;f55*wg$744-5I=Q#jQ`|LAwZqC*-CZ)5Gv~wdy}-4H&EIO< z(&_sZI9HsbO~zVN4=@+pPd?7f>-i>ieDJEOc=mO@SGv~p9VIK>xHYNxvOCaycaWER zFOTd_+9r(rtYO|=-u4(5=`?ElJUyL{sD2P-y0%mB~!k9!c9E{;P~;-NTttVtt{OVAdF1*lfes^T6hR ziL=Ipp4bKl5H=j%)jE+lGb?7T;CUzCMcd3CzS@v{&g<^Nu9{3+7T?+{NHgX(w*2;bEs>eQ*MR2XBrxl; z$))6VlZ~FkKiI4x?c~gl9iLKo$se!dlXF#ZyI?z)=R!SbH?)lqcQ)>6H*wvE)uRY6 zwIT9TUT(W-r~f+T*LPCFv^&wyz@z%Kd=+)ynaZbfI&tpVgHO$&bsnG|oDBPCjeh-s z=fImy{mEZ_C~_M@@MS6)&h%ucwYYj@SdR=%d+J1n;b0%^?e@Wt)rj4W99vbcIwQwm zAJluLGyTK#L9c&Ym)WZi8aX;s3#(4e<_|pu9pOxI`(NUUT(~!NX5`q@l_TR!D|>vl z)l=VjsSWp*9H*E%OA=d`O`)Eqlz#JXa%?s-lq^q@9DBGnpkvW*D366KxnFWGS@xGK zk%j3C@E1asnqNc?L;n%>$PztwLO_-mBg>0Fr!3JAd+D=JElc@|?@N{sBFkrJli6BV zml;{!Z)7RG^l`FGrtUZ6d~4$VQZhT6G`)1UNa2-+|Xr&a!po1E}}XCw1WdQuN4MKKC!wv))MX>mYNet0Q(&7gn=t`)_0)-`5c% zpJ8q3!GG5g`YwRJtGAbqcqyPG_!f@(taSZn(h;hU&!8i;hWBwg!i*Qzm|jWd6FTo< z^>@GPL!F@KXQJo%&v>FbQIOyA7$fh+rCTLO+I3KmaK@%hdx8TEPIKvc)rqH1eLb=n z9MyxXuV?O|Uytk^f?pSrL(tKIdbrlB2kDuMsfUZH2fzRMy4tUYPorm47oSPbs4n)^ zH_*3g{~^W$qp#IBth=fEc#$#YWBW#XUEJ-}g}dkcg*|n_|3F=+kNEXbqq^us7inzF zkiY6gbH(nej}E%%t$ozT;@;dLOz`Vtg5%m^W^cyp8?iv0te{R-e1W@y(fX-5%?5S@`?z3K8`wN>&eI&Km=q}CA;kj1xcj+(cC!oLPnEfv8 zwfOb(2y$;}>b!nr3;BIc>z=_r=hNqGfH^zu&-pKgUIaVqerQIpr({265_60#rh0bu z;o{Of-gm5P&2cow2m9W7U{UHeLQq|=Jjm67vYBS^Ec@HkIkvY=y@wjy^Fy<}GwQwJ zdujG_| zW$(FI)N2dU&8@Tpea}H_QqujtZdSX{{&R?RG0np)>fP$$+JJV4d6?E6v}SKx$yHT4 z-(}`uDQv(yN_KD_b{+FDyL}$!%Xgn+W!`IR)n;^H1~?emuw5xy*nOj-X)r| zO4>_M8BQ?SvyVf&M@H@*OWNXII_$8H`#H;W z_L6#*|J#s+>!0B7=llhjzn^39;yLnt@J0o5?)_U+0$`+ZMm$WWCf&KR}3}_dh z9JjRpqkZ^F=(1m9?y!lY6YhP@ZnJnl4xYw&JQ@EI>_dmO)~TY+oG?Ot4o!K!5J~(3 zIM1pwX$^WHdCAw|a&Y^KKF?~~y7$v|*ptS$D9t+`H+M02>TTM+d+i|3G4*%vDWYGP z^X4b&Od&F8V1GI@xVaP=oXPp?u&ChL3}tI&J%#t%;_&OQiAAaVTI&1n)YXcbuGR@* z_UO>nb_U&qKHf7?9JD9dvyseD z&W&gDsRq_K@XzY5I#+v3PR>=}*ISM(Vh(p@B7^y5E?R%^7KV0r`zBvLY{E##;O}ijkHj=B}albY2P?+VATq8;!wXjeU|& zg0*4K$HDMKUT;xe1N+)fw{4hewaK^At#`wF~OoaZ7z|ZfP;T3d%c@Te3y|?ArU(T~|L- zc{t-9Re5^PD>e3*SJL{D+FGc`ysf4!$0z4QJ*IBeJ>%*>iq+?y_Rfwmr;9bdx{M0E0Rll z9+Qo{T)z>%7v!}Yd_|&}-pun8Lkf|^YUJ9ybu~6YIFVytM0+C0x_@S?d`iU6*W}Mk zd$UcxuI%5Q%YApi{z=)dIN#M*@DS^D_D2RT-L-SDtMmTKbN96_zRpG4uefl@?V-2b zXZ##u_m6VZa-UXgS2SekuqF^Yb0htWywLBl_o6Niz7Mevs@!K(TddJ?pV8Z~yDgVr z)_Y>_oZ#lmT2Acb16@9U$#ZM7OP{^T*!pr8j((4A@8>>a6UKgarAzZAo+IA<-i$x7 zbN}el{|V1qUvv4#Zz8sh?;45E9}54EZobd*d}0rm&eJ?kKEQ=9=lP}^+_X>deAp_b z1_aiA2XHTi&b1~|?j0ApzhXK6 zoo4qx-%Kv(dt&|4a|^xB=lfy2*IgR4>$ZiQ5sCD!<}U9g^tqnJ%Kp{+#d}njqQIo5 zyIXS^*Z3A;EoV_3&Ow7WwV!*B;fA~Ut~-1g-3RVT^kS8l{H;)tU!-i?wF`~0PE$(ZyR{=z!AufF-YxK->o*j z1=gLpANxK~N$xH=;ls8Kq%mVx3i&0o`Rqxq%o(4e;voWG^2>SWD<7J>_(W4S_D5myGoMSDw|c-7(OO8_|iXFDo&u zFo^on8Zh5$4R7(fn1ZbOA$hp5NAEQj`f|sU!jeGCw(!`wl+r`lP1qT=Zo6=3|klF zV~OlD($iY|ewS}XVkZJ0mVef^*6G`f(bN*xZi>&&Np@wFc_?*XY2CjqmK~Q1Cp2#u zfxRU=DI1PBO`IW^UB-XZ)S|8BFbKJYGp`n%^z1^Ea%mh?`?v*}=^Kd1pZOU1C1&S7 z?DKl*WaeDQ@-52>YfN7AnoAFwQK)Db&s~TvpOTB({5WJIo@5(Y&9mP;5*n(T8r4tp zZ0dhxK9DXLi7d4*AlXKoDcDcYYDS(4I-jBYW{|1c6J^~a zSM-w__yp#1^)RC@VT z0@rz}N@S}v!e#uatwro0CH4WE~9<<<+=nqN;eEV<)^uV`5rX=GNN`$+Bd;hJCzJo_P)uvrF)TwWcxMn z2P8#zWKr`?hdjcxsh7kb=Lu$kSDqSAJzr29O#SM8KX{BfoKFCczSiG%vWHqu_PB6- z2H%Ihpvdz)+X+pnV7|_CFP;(I@ZxOIjGs|>P&NyFX)^m*QDKxBvrXizu zBR>y+kNoC%@ zH0j=n#O#uEJm)>yF6}-YT>xF`nL33Yw3SEvJ;t0O{b7Wm`v!FFuH4bXSi)FVR>?S` zZ;n=x=W1g0r8R~&--w3xOFT;_{q@8Tw;#u|zA>0!+}6BWWA;qO@4LEvwA}&j1mJUl z&j$WZnPu%p(Z5^O)!IOa#PR1O*4VAPL@fHaou$oWviZLapno?@pJem1$j@D$PW6(` zvOA2~y1PSbp2F3b{Q+s?iThYramQ@R#~3q{F?%Ls_Dsg?nT&n+m7e-Cbrip^l;xYY zl691E*h=14nmk)9Ns^maUxD+ezUpILea zm_^>Ax6GtVn{?>T&5p*{_{^NfFO5lMo({u4UuR|AvM!>mG2Z)S(wHFI0ln3Oa=(sV zTOEOat-<|#_wLP?o-(r_eV@C6@9t7Zu@?GlVrGG}5@wG*-hhqMbxcunLygJNZ1x%Z z``L$AAS1?<;@8yo;8%Sy4Ub{s-@tb`dj<2vi}IJALc1YP#?g&oYi3S-cc)!xJ{`$s zUviomgPr>rBe83pS-BYFroJ1kF*EASEZq!EbFUA2^)2LGj@&G3X6a?g#>gp^U#ahc z(?(SPN@JeU8Icy*K{HGESZvmJ?KGd%JvLW+X)7A!=O)>wuw`eK;NO#dDu02Vp~2i8 zxuZ8dxyx>N9N&M99g=&z0l6SEwVjiYy?3unf%O2}uY+jjs+{Vts({ zN*_{N5`R_}e+KC5{J|F~tMW)8U$qD6FO72%WF;F8xxc7$U}4G}!}gHvhK%#nXd8Ysf2WFW0$xOyx==lcF8sEwu~}PS zZN~4fy1)O?%8$0c0Q`jjd@Sn|OMx!~E?-k0U;gs<0bdM!aR7b|`162=t!(~4@@eFK zW8nQH(#_`mMBozx@b8eW3HYVmXPWk;cBQh-zLPdZ8KT*l^rKn1a%g(>A{&b-1k32a z63~495K2kpY_noDs z3xV$dz9RtN27CnYEx@+~;QJq)EuIJb4d8DC;PQ7p3;0^#YXk6B;Ddqt-)i&oT><`i5+cBMbnR+=8`%5An+WTHzd-yvu!THldA^#E zB0L6cB=JDP5}tF!4q+`JN_Z4lCGn1!`z_rx&zpGGH+VBVxALrfmJ#0yY&mf=VK&dA zIg#gCJWIcu^}tlSepkDnbR7MVwpm8I=`m1!5<8xGnVrstt#r26A@rTD^aYIr@-L#| zH+OT#!5HV4Uc8cL_Hb&IUV8sl=xI+YEV$c{y zY!jbDtTaIy{uy zk$F;EjrV>FI>Zjpy!2;{=WG)&#Y0V5(b?#!n@(WA8oG#UKfB@1HTSbAGvjIs`9P$(@Oe zQ}5hnne_|#4MB(bTT`i;(B$!Lr5V53E1+%0G|$!8^7CUq@#b99Hd!MzO0G@d!{czr$1P^M<-09Y~vz)$@%{j)Yt5IWA2}GwQe$hTX~wf zN@9jtH;FQ5iLh30r5ej3glgK_hLiQ3MeadB_Jpv$6`(mX{e|@iH(!V6dS@=@+4=SZ z^~85w3S~#J-;mW>9e1Im<}*%RkUtw<%TiaM2QE;5+iX{kDvn@mwkxr*FU~%!{N(4R zb-oCEPV?r!SCG!=1o};xS$DvGqEFSpE4B~oQlpCW(RGz6cTGz5kVJNhyBoQU!QPr* zM*HDArS12|s(%On%XX(77mt_RTT+FQ&=w!j6n)s^?Rc$Y!H4=gCmFC?hUY`6>@(%5 z?1L&7K9`#%dzGV%v}KtYx$^XtxiVzC1eqgO>S|PxHQ_z-V@;TO%ltiZV%@g3j`3aP zt0Rc7F!byrvc<#28*NbO>)=B&EOVyhOnQfNkig>(>!a{n-g0@aD{_aAXSzD@M_p7v zN9zm6c(RrL(p;!4^=(rxVffYDwLE==XujMvF|`#wUS5EF>)=s5=`4SoHmEU0ZL`#0 z^9k4{n{56r))=(5Ct4BY_8agNSElEdmNGVJ{fNBHdb9B} zZa@yC3pI0w6)`{i>@>g34=4b3-{1I$? zOlfPYS!3DkI8B9c3+*GTagTP+os4$uqGGI-dB-~S0ls4l9qkvh&uny_{B~C}UzUHa z<)jMqotTvr?^nb7$YLdR7HMfJQJ1WDFQHBP%mDmAbO2w@?H1lg{RcsQ!}f*z%T{bBrv~=eXze!s5j$V@7i+Yx9--=geEI zFVENUJb>rP#OKmKt7(&Ee>>9!DfL%=_Zw3Nx5)9y-qGHGq} zlXR8UN`HoqbhP&DM9+3KM(HkNPbZ;YB{%r1twi@oPpXgg_xh1^0X{D4*iUHd2K_$Z z`D4A-xBW4mZRT~-4HeKTPk3Y8SwG!&&43T-Q|MdLv$kaH7jU1H|Bnql^m=V|79LaF zCE9GhC!DWLHI}X)q_NgLZ?1Mz22J_XYmR&#yp=KMVIj%glhb&LOrpG#Z@90&X_v;% zdIp%<#UB!Gznbce*VT;G+Aph)&o8Zz{zLyDBb$0>y;J>yZ|;&ta?3(PvHIHo08<(L z@+#i}TDM5Mb*_1)($5nw#J)^q>&X7meFH5G?q0d>O;I}OuQR%3i$mz!t0%d3zTl_M%OjqicdBA49Q$1Wq zx@v1t34Ncpn$a(5*KShTUqgq;E|$LvI;m*5ld2ijGgWf;5b& z`R6>k^t)a=7`rUw<);tYSvl1``FFIlzNoe@+Y>uW=XFmZukTf~+fW1fFFw>iPvlws zTYJKSDfaEwt4Jdn70^(ZqVP0CFbjKgKP)kE1?T4xaMz^A!(cHE*OGqVp^GR~z@! zSbT#=a@pE}R*C=O1HFJfsq-V?dHg8-TfA30KPKw7A?%MmGJYdKOMGf9upI7jP<^D0 zug+$_K3)UY=f{r?ew;i>(?x0E13PA&cuvqRG&c?kaNyaFg(yc4hEg<=yP^(N#QW*ssrIX^Qv@HDtqfLljeHG(J17 zKh!mb*D;z~8{Hy)CIYMQ%5sL!6Zw=ol!0IIvmo)y^uwJyT_6 zJiu?FR=A>l8TcB>wUOFtY1zW;nQ&o(kvKNn1K{Xb*YHael1bF~aBjH7KKr&y?g^v&7) z!OAb`mT!gO(VcTyStENh=L)NBr0ILm9OtdAOCHrqOPS<}|oMuXT5o?1>O|sk>j!UJP>%>hPH| zM|w&3DNimm&T{8<6%AK{*JS2(7PeR!YsH!;XiSssawasD&-IF-9V5MHpMKQk1<_%@ zw@~So2iuFi6nu!%;%92kX8xjY-MKVI71@iW?w6D{9R1<;nr7~(qrN1MBe6|hKFQi% zAAhsdC-G+KFz3yZJz#47@XVW~@PH}#aN`Wdu^9z@Mo}6hY{?|!%0xEKACZUJ+3kwcl+A~6pHoC~NL-$qX4bTf zU(Az|x$NsmvpYvpxo1LCvHIFHo`daBc>cTFJv=MDq;xKAIfy5lOnFP^E-!QC+J|y! z{-bq!%@b5E$@eca<@YqISS{H~j`7z^;nvqnw(~mcSg#uy(I?uVWqgE`fA?1O6Zd?>lK4dqquB{AnB6yw;4~-wh%)JDit&PoR{b>fg?SBih zMqm1CW3odX!bx5os7=(6zt)@Fagn=xj&j$=q<8c(k2E2`_W%I zUmLrNcN1=IUmMH(EuasR!wZ^YLw{o>ecsN{J{q`3iagb)#m}{xGY00_b~AmVx!pg= zpKA+ugVNC_cTx`ybu3+WyQxc;mfG)c!3kRnw$OR1>!eE}V{|O%OcvQsrVEkmtO9<} zh9|9ws=Xbo{saGO!4D^98T>BISLI^N+o4-x-aboXH~wR0UM;ya!=w1U1in?@%fuga zyEraQ(eC2WZ7_6ay1E{E%s&=&5$$Goz2hoq)nw5@$U=JlW#({~nsu!EOA+U^!XeyE zc*t7G@E4^+xclNT;=`R^l=`&(0v$Y?^0@QKbG$Yx``U`%Z^jJySx8T)-<|EfZ=jCF zyUKBiR}MXo<@rX+p?7C^Jo$6gtoVVy6BT>;2`1looujb0M`*G$C1=Nm7q5{X0Y`g& zDvxAxYlJoX_>w=V?&Yg#wYYbn2}gT;^65YHaMv$V>oC$o=6sIDw|KzOxYiXqsxQrp zo}Iy3o$}WCZt@Prroi!ETgsG+d zs3$ui7=Cd0PFV05PJqYr2;N0dU}3_bzoPTJ{VO|3dDE0F!`!xk@0sAADZQb7sWl;P z7chHOnoD6DuM6@2Y@Qic*jFD}ypnbkr=Ntu_veqAGo1kr>%^Ni4`Y&K=35DHMfZ8- zL7jh(|LU{BwD=Si4->o<8N_J^4!Quj`#RTZMRyaTgi1m+p-#`T>F`VMlK2pRjs<4T zRB~i6GkLKuwP)R90r^W#8znDrtoWi*oimFuf$yudXgr^c&Y}%*E`)ux+G+=V(&Db8 zX??5>QJpYD$fyVh;%Ks(7HFt2VX&R4urKoljjBGXYSw5x-{jt_B88F zXKOvoS=6pqwn?w7^YqF(^vb$YpWHh1$}F1XT*|kkbUbZSb?EAqMFwWaXSw|m-Ey4w z{xNv<%R5x{jtp*qAJtJa`I`1>O)sGz_L_SPeXYuBVBYu6q1N{CNo#u>@i&P7mv|iU zKM%9EUrtZ1x?5Q9%e-_Cf-_$5K)S`i zegO|(CQXX;zvp=X&qF&&e;2p|I;5Wi>@o5@oHTXgmzMrS`g)$L!RyHPWN8(+#9`uJ6PFYJlK9fAE zbv$n=|95#E4vh_h2jq1Kuv3x4Pf2qe@lS|PApSA&k;Kmv4<`O0@j~dI$nH+Mq6 z3R;tZ2isN**wr2KECY5iu!|4dyKZ(rXKg3b3fSS@tnFWic5mXb#77ZdNSq)ZO?({j1;mFCk02gE zJdF5z#9t#`PkbKnY~pi>=M$ez{4nuZ#P#G^-)C=GKSI9MlxsOSr+`x_zB-iaesFej z|6;Jc+ym?&()1_I7l@A$ed42tRgNQxk0AaM@d3n#6CX+3hj=vcp~R07_a<&2KA8A+ z;x7_6lUH;7-hAFdewmR=OVh!r24|x9>A>f8;Ee0Q=heW(Uj=F6#AU=^Bn}fh#5VDv z#Jf+S{}X>mtaAK|Sn~dWcrx)nh`&PoH{!1n{~z&%#D67zpZo3K=T1n~yRTo)C*LjH zJ9`;8+rW7noR0jS0nS>%1N|@w?AxUIJ!urb<;B1A;x~yO*q{DSd#M6kM zA^tw`)5I?jKSeA)zE3Q?Cx|x?KTiBE_u;?I^CLWO3H`e~Z1UJ3ct9Szp0&2mBF(*| zxtVwY@g(AT#CH?lMZA>wPU7XnbBTpFoA`O+nZz0LUCr|}o+oyaZ;?F4b;$P*zy=%u zEz%rKd=v3kh;Jl5nfM0cB=L2`y60aw*YI553H@I{E8cr8N^>F z9!flx_#EO3i8l>H-|{?)=MDJ9b!<_ zyo`_~j3O^6UU!DYQm*g#n6g%;vvgh7OJ2}213ys#dN^lic> z!Wu7(Bpydd6VCO*mOnw0@CIQHVIpA?VF1A))Dw1Yi&;6syM#4_<%Aaq&4h`BMuOI) z2cL+|h(F9I;<~|0OKm(GpUK{P>ziY#k8R)-c)yW3Y>s#*>pwg36$npLEEk+_xkRpOr!uOnVb{A1!5 ziB}T8Ks<@?Bf{_Rw70JyKH!EAw?9jKG;s@Y>LhFX4~T~oFDJf$_(|e1#LI}s5lIF(Rp9y}4EBNi7;5QM2-*F0lYqejH4tp4)r@ait z{`VZ~z5o9AVf%Ui{XJ2wH~2nYtjon5&E4@?Eay4I+;7|ou6*hPc#=V1?|T_tnRiBz zfqh`Mc%g@D_7tr7rQ6?f?`^Mv&Z!Hzm!2|fPgQ;on*Xte7E@Z}S^TP(7Qb-g+n_VX zeOYh7kF2Dzwm0*!Z4=yYXUmu2@f0>Tb1~xw0SyO!j-%X~Pfq0YR3-IMLw>4{;;aDxD;3@Lb**5?C(^*T=UJ=Q zy0~OzWR5(vkH@-3t?{qGN5ih{Rs0hF`QU+ldaxr&zf z@Nrl-K&i2ohkPT+x%3eNeylr@$Bo0hGXwY+G5>u%#Jvj4i^KA#4|_Z)f1YDDG&FxU zYYfz}m7)y%*Sdm%A=_TmkDo8+#A{hYhc~_zqq5_V&`NuF5!ki{ou@!94SYX{{SNI7 zPllgMsDG79{kW1nqF+K|D)68$MTUAB46Iw*?(M9_wPk5Xw^BC09gP+Z{fDmWdvrnZ z9_ZWvOzR9263k02?iPT~Z0KlT?Vo>Aec>Aly)hnMDu6f5!`lJgPr(`I;Uqf2*$R&8 zyNohCPdkub44(H^g0PDf$2SNq1nC|-$()|H*Ne6)JtMuNwIb=jQKVBpwW)_ax`e%J z$yj^X(t9D&M%AC8lLVKx#FEetFKl`tEWzZ*(PNg!+>2GyfDkUc*`SEjh-2g3+V!g3r+&pR7ONM=jdgHx<7L zPfu4u+w95fj9*f^SMA^M^kTo(dGb|M8{G5lYU!V~p1db|^8Nuh&w6z-TXmOm_qx>% z&3--QC_|Q#g?NzOP}zLlCz*F9g9AFqAchQ7FFxHQWi@&uHLRdAd{w;Dj@9SR(lh1J zH(S(()n|77PVFjH=@?{;Kr>*r;TJbg?In_`W@vHxbPG#+wSo-#Z0qt$M5`E+P zNDimNRey_s_uALm``6YV|>-z1B;6faz~$^OXI|+aL3k2hjbv7S z6m7y)TC0`48NS8NSP<*i%AI~Zm+`DSFZ}PnTe@cnUl-lUP)R!357HkhLpYtyPdt`2 z71n6|ej&e5-F>!WaHjM=fwV>G0oCnyz}?Z`ZS!hJ8pF_0G)Wg{hfNyqy?ENmIcDML z48=~)%)Zavw>~}ju86Mxzf)h&Og5h)&s}NC3BPLRD!azDoxrWEE4Ne4GiN)Hnbztf z3H2v@mcc!N@+uGCuXBKKk+JAVzxpZ<Y~9IyWWtl~RM~c!`^mBo;|KGi>A(2r{HOzs-$LVJ`l4ur zJsPyF+H--4hG0G&_646DC^%!NzQIUaC^pg7?{wTT^h@+5wE;h`3U1MMSFl%r|mfz|}kH zBgtVWerDy##+-C}#Q7Hcmt*qfsU|)nyZZ>$mF|p{{B`yymDJJ+*pxkbL8D-3fsI z5cF?@c8EJrtc;u2)Z^TKz}QuLaOjre;p{_Kr}4c`v2WObE!@mKM;80L(673FdO>%3 z=zp#FZEwbh;+~aFxo5rtIytOVgKJwL;?ysI(dS`k&e_KhTdJX20>yXE$ zKpqG4?9*0WF$bGpI$$5|;Xv?%ZSXav_uAkp(apNNck$_F_imFN+rt+<*~(Al1=5K3 zJ?+8k2Vv^e^tlXu4%sXRPj~1@e*Z|IW3kgT259^jOmh>pTdUdSb ze4@UkYj?HcFGD)Xa_dZ2mf~l=$B*AfW(8=@`~;di12pR>qig|=<6^t^Utf%W{Zw>@0OkErqV9Ly(&{8S8O@9sq_M2+4W7O6_=ZD#uk@{no56x zmd1$b;7vHz9hcSaU#IRg?r!kLguU`$48=EibDVfJd*k9ozE-U~FAFu79KJ8Av*2OU zzQFgAjylSnXW!Vs`ppgOF&yfCi&S+jyX#iq8ZXqgmcdi=p-ao2qK|4%S#}qA#Wjo- zgB{L3bMI6HIQLPt*@-hb4>zLtTjSe>4=>O14Q`Qac*d{hMU^cPpKg4~F3#xNci8@c zwA^=vUznSg`>yz=%JhQTWx0dh0Dg-nEBV3M)_05W6{D>3mvPIT_(raRynZOZ4$`Uo zN;{aeKHY`VH{`nl`OkyS3XebhYGOOpXGjnI*z!XbFkjCUmi1gvI{GfjWK>bGX~;E% zd>iGr5XT=3`pc**mCeRCszDNX`HK{T-eQh@mdq8jIZ8GTdWOv z?>oLbpLgMXypw*9?BiXMcV+u{cOvh~_wnvn-c>lK6+-YDtSzW<; z31?bH6~9j1sN9mV>gZ3m@7n$Xb#s#QyV9V89L6sjou@ zaDM>bfgR+$${Z+LJT_1VX9enD2+w|<4JJReYt?6%I`-Q{7(cLeo6Hf?DGxg*4jS;Lz%?K?!c3K(f!rjR?+d#hvxoaBg6Z5gn zet2!LUraN;KWZDw^9k`lp1XAiNIYA-g*=v#emU>CLndddogC!)9B~iAx^BGp+o#gs z=cQMh{4+GFm_tYK-Ks%u>K`@ae-Lr~o2-))26wfr(+ImZ#;nJPA1C5H9@kaRs~O z+x6ij?Y+UBH%UibM82l~q}(xwIY;aTuW#}Eq#2KB6Y}Mj-`s^J9$j2Q98KI~`rS(K z(c!!|{(;!PoNuKMN>&xLH|ZMtUbh}xJnrd`-GH4W{dFQde1Y)-yLl@0fxSIC&%HSK z!()HL*L$?1X#5^CuBjjPif4PV-WkR&)0$fTH|+aM_f^ox?Zr)nM0T3-JJxyb7pSLe zjUGsuvmTo7Sfo>%+J*m)^tsQA@}r-2%Kxl|ZXT|$v^Q43zhn^Qd(TSC`P)KGdPrd< zI)t-lMjoeo^dt+-86*$cl0Uu2rN{c2IYVC_pN_4?`qv_N%+?yKFJG-iwj3fIH@wK4 z`^7|@?=mA_2V9l=Noee{no2rrCO(e#@>G6)9VpKWy)tM%u6L4;@_Yh1G5(jwXBZw{ z=H4;UrEcu!=vNiy9rua={{eY)tlPo!T|PMT6`S74`}aNhxA0!`_l~l7*L%;sR<%Fj zeMi2(pLC_oG^*(5i_uff9D%TB^OS(!repjZcr15(yIO+?U^T>V) zrL*}#lkw|pru{c$^Y`Enq%niO7Phna#%6Vo;+?s}O?`4cHOU=a<)%VLgL#{Wy2c5Tn02Xf5ULe9diJGo0coLRV4xW|E;JvGDFm(8zc-gFHA zcXGe2pZ0e4K6XuREbSQFNZpSzYfL*idm#Mxxli-}@U?ECvVQkAbXha!Z+Pdo=WJCb z*Xq#M@v#*zUsJs{yZ3=w54rsI?7;8k&1~!wk^7Zg`c;af`3 z5L~){`62U5N8jm>DXihs4v?K$_t3mlI!}0}-;$r&l+yH88p@_Q{4S@lwBp$IG_BAA9JkGUOOgJzmA1F+dhG{{F3Pv?9o|JZ1kMYlse=Y@{@a|*e|Qw@H{3<++WD?e zxM!_~=!I-bEkI6R(z)?ZuqD)_Qh<@jaA(VHNzFcAItY;EN(J z>0E#9MfYji)SFos@aAg%v-&;$-EGrU4@p-?{Sy8pTPwrb4YZ^?MC;)0O@%8Sp-)v^ zo6m-_dEND)d4Ns2P}*IGqmJ`0lRh{HSd9IVCM+V{N5GbAyO(eeVF6)2;YtGis_ia9 zGvQ9c9fY}rIfQQ#ZYI!9+GY?KkJ_;5+O+qAP1iP+FoiIgpg975>TS0X@GEVbM7Wi3 z3qdp{5^f@#K&VQ8qY%OdX1}F)Epu<=Thy9fg#Pv~^o?}KsmMlcrQFHp7k`g_=HbYu zGGh}s0|Pkoz=>a`GYG8j1MiyLV4jcRIWmN~Sz-hJrLL{T8r7m`;&kTe$Zu#ie+{y$ zCzehtqn;~S$HTW)>-sN7l2_y+ywiK(9|*mA?6R(jRzv>_{I5*5mMZN9C6yuCU*F)# z@@?@e3c4%btX0ykNsBE@8+RCo?WWRBY%bYdR)73j36(uKU)!7cjaN?Tn-qKv@zxXv z(B3q!VQi=!!djz`C!S7G-NXBG`hn%)b2n4Wm*1IHO@+~uT^!D9xNBwPsr;3Er)GmdY&N52a^sK4C}P9?JT(?tW%8tYA&!K1&%qyxmG%DEmoK2L{J zU#zV$H*xFUU$Y9QTs;-akfs4YUD6m^DXIDyQKW6g;>cLfr(i49oO*5k;bZlV@q=?o zwiD(U$Z*qVky-67_8#<~wh8Z}if1luEIiJ$$p(t0!^Z3!a6q`$jJH${bCdQ3#e>b=lP` z_YoewQQ*dr59fo7Y=lz>j%eK*kVS9sB@6g)Wx;##QSP|1_{VK~%R)MqZ@Qa)s&-RJ z9*<^Rnad^@eZk7&({eW&S*41qOO3m}j5Ib$mKS)k^x@*;ynXQTbDfd*?sHb1u%B;q zlJZf0jUEp=8(L{oZsb?S+$Bi+e2=!;iR#=hT)G0h zEu<4%=~Rchhfn3dNIY6M8Xm{;tUX%257r&ZeUHqv_uKLP*jw7`R`zPgelQ~NUf*@} z`Sj)Xn*e=mT2oH7>(2V+6$Up|oDz_&`b~m#X6#HecBUw!)`}ZAQ)1>ax(8)c*v>Hi zV>2Wd(Dr`ymxom+W;e&cB z4#lRE9VDBn!lO0a=N(x~rxb5>=f&#h(uw}M*tS=&X&CQA@S!=RmFCVq!>{a>k>P63 z)}vz?-7H(+V4lU_3*H<}&(**tC{M@bU*%Z?|KbV17Nc`6=e=wQ;s2Pl#vTD*ZSyDa zC-{Zn?6g?F^Yr$m9cbP@WtUm2)Lt5EmbL8Xwb5p=180=v7vax|RUVZ^Ws=TcKz_@a z6PUZPvMvt`4gaiZHYW=QEWI}W#NFBaC{s>Xj^gKbuZ-vx%70;zy*YH;e$oT{XRP(+ zyehBCqrUQFy{kh8f~)aNbWZou>kQ#l9!=(xwRQdRLF0Ui&LxLinM06Xbt@ZAdt})M zU0Ox@ke^qT>z6W%b0Te{Jz8|$*c-H!kE8XgthF6Kp*G$B{&9FGk*Dnc%qQSgfv5Y_ z(%`90YR`+Z7N3k~iw~h6G?%zJ@9tmuyhkXP|J>K(J!+j1GPVWst>B*Miqy-!I2&4c z9NIh9wa-C5>TX#>Tk#d>#6JC^Xi?Ap8ud4@1HVKVN4SD;IpH#bY}QK&mk|0BsH3*A zgo_BQgS3qyj3&?y+D;^(Bilw0h7*PnQiQJ&(7$cy_qKBh=McV1IGZq(a2A2F(xe?i zOx?FJR<;c$XpMTk)?&1eNV^Rq4`a_Hu~WQ#VQxJv{pAS!)mihEo|{kEH0RyGTvut< zoYquYOK9f3pI+_nZPMI!a8qH&VD_&a?d44=+*ZYXx{FwQ$L8wJn6&=#%mQf4%VDFc z-}vb_z?1xwSid%7(M!;hZkCND+K)oF9GV+%arKDi>}uOoNz6}6;Y`|Ry|nr^$)nhY zzD>5uORF_%t=0UTSZn1QJf2u5Sj2eMraks2R2F!j^MJb!ragA;zv(Qj`m_3VC`}*F zX7dk#`@U?pB>yQRbr{>>*>J4w(oaVfzhmOj#iy2LLeJir32A&^!@N&pjAc#Fso$>T z9L^KiZ_i+}sO;1y{dXaHHKlLSZH~93xtHJq@Mm)Nm~jvLrz`2^P%gcV{Q%HiJjhUvLbf-=%x1lKwHs+Ka7 zH*+M)GrD-&*BV1Nc=?PXALXrlWJ|eaa`QS8ob9ZcC~xT=oog(ENB7RQv8sPtV}`~< zrBiv7-)PDtT&rb|OKX_#Tgb9Jlg+PXzArnc99pW2r=U^km1&)qW-a*2$08rm?gQNoUOL+D zi%Rz>=_W35->-zv_iet(P8yy6qi)RpuIgTO`~H0{9_z<3)nl18mbu4_QdvvZrd@;= z16TWy+*Oa#k&=<>gAb@19-7JHA!twZczu=s4=68>7v(bxer)(B0I2V26A3sspemJUlA^`;iBG_px>vtoC4=0jPsVDET%Edf}Y2U{F~{lkOJ2*3t={7nE>>D5OM^3Xg~GE4{HXMwBvmEc1I@UH@| z^x%mA?ejg_H38gVzX1GL`&?zfq-9_^I@+)Dzqmj&RL0rzP) z2jB;gr_cAq0PR{&#_0g=w*$1#4ZyDn&>j$gUkBW$T^FEzBXG$t62LtuAnzTI&|B$i z!r50WyFHvi|Da<+&Gh32#`V6;5%5pb`U7+IS-SJ1OOo*vo$w&6Yg!<$TRX{X#($XC_>al!+kw2&o#geMkI75E zhnjO5`zVbJliW85jg)9IXNaIr7aChVj4#~j#uu)J^-&``>3d|a=dXg_#2nO;EcxFT ze>RPS$nRlnk{4ya%fIk!#w?BbLp{6y$Bg+cj6<^fZ~a5N-7j3xeOG*VdGzm)#~HJC znR5y9ZyUEFW>wfX6g5_bli9oM!P%+O>+-!)*^WTJw={E)a)R}S=A~P$v}X@yn1{lT zc>V?S%TnWV@~zVU{gii$Tb@=uXWeHu(znYOs%ygCW8l8Bl6=G>4t7v8F}9d|f;5&M z!`g~y$Xi7%#Kw%a~q*|xm!`OEh84rO~hP`2TLvfcL|lR-Me;Nj{=+H-8cUdb%o8cMsm%=h&>oP5LAwfp*A=aozSqE0-; z!N?NB~{tfiGg>>tWUQuQ+Sepkn-?d=bKg^iEjWz!1mQ_TwZpH)yjhx_B>*WdN= zlW(H@{=yHsK7P6%T6i^mq1$6xdONiypm;O{l?Kd;Pw1dX7~ zEb-&X?E5@_8kzkG``y$zvVDX!L7DCRVU^X7@Oj$VTxbSm_B-x)@MSiIcb_D)mje7v z0{`>M>|4+X%IrDu7vx-Hy3UW88Hd%QT7Hot)} zDwLt!Gw-wp4bmEE-++RJ`= zpzMFvbJiV4kN*$Lz9}%47D)S9%0B=+p1rdFz0ZGE z@An1D{_tlk`@&~F|5&Sb9Bk+7DTiOan*!zg8Sr3x{x}CKeEzbX z)1hn&0%c1E$~OH!DBGey+0@=YO`Gjlw$`UVf7z-#l$1J6n?U-*rr)41UK=5Kk*z1vpvjr~PGiB1Q1Eq<4+`j5TNe2Dwg z`JPe8^}DQemX>;6>C%zkWy|9+>pdns+HdI0FWwRz==bsb;``#;&fKK!FycOhdcvWE zLkPVI4ncbkg9u;bxsGrk0fpXn0HKDUJ&3Ca6A7~jy@2&3yvcK%`0vEsi9gQwzMS`E z1mE|*eb1p2zxX6FW8a~UU|IK;HnMl6eFx2}zpL`GPOp83O@uetb6|c`T+4g;R%lN2 zbMWW0E~mMU#`QL2DnF8~#LR)r{({->(V05d;n`m>{_&exf7L#S{NsPev+`Se+Je%B zrf!&5k-oB8b%XDA{Lb9zeD~`6<2Xx!pZu;4e)7)%*Z8bD7H>KHiP zI+(fXo10xfdHf~!_{lS-&Qku3ltpyd+h9+_Ez>Vq@725G;j7$%UK|^k|94Js_d&iN zptH)ObG=80v+~9t;xN)`ZBpqclWxQ1t{hqSHNNvdp{(+qXMNa}34Yb`*~Tx^_|7Zc zTGl16Cv63JU*yq$lrpM5-k@$~LhB80ojeQwHQxTm5}viL*^@PzwLKSH| zhuq~qe^C~0p{U3Ws(bN#Le-wfj?bYIMu&4%@-aky*KAwM<{x9XfS^H15mTCfZcub%U z`|&K?x1p`}*%w~dQzz;h9ewcsbi=OgJ@M&NU90X2jn?+n&|UAfIpY^kpZ*Zv_WAhU zi>~_Jt?shxA zvIoA$kEg<64o?}@&2VY6C1m*ch;-UN^6A#%FDrUGfyX@m@#CkvYk)EK3t8AQ?NPqw zUoh}o(NcQaRb6j)tdJ~PynLRg{aW(d113Erc}C#nHjjV&-(#F(-s7|5^EuX&ulA8u z-dNoAr+@Dbcifkcg81AYK2wfVgKwv_)?ovdsM$s zS)L%ja))|;V4B%GQ$PF_zAYPQ=jF&p{?M|Ig!>xbl~;Ne7GKobA~g2Y>H0(NDg9}x z+gIxPyWfYXv8TEFT=+z*?MvQj``TBN{FUZyrLk0J=t1z`IJP~F-m7o^_IlSRx~~5{ zW_)L@DYkZsp2zI*iGGLlS_7_Qe%%r`_YxFs%4P2V;GPck3vA%FZI7@X^g!pn8$Xb& zQtfusVr(4wX)Ge#M_5R>mv9dO|Hc2``xf`5ZhfDJCS)i%%f}<=TiiQ#iNm3(6_kX$M_aUpcnKlw)ijK;(nfQabMbsc>Orv;=c5m8pchH zoerU%(62{RDbd^8Po6K3sKAf0X}^(}{2K`S_0{zw6@ozQxK{ z`73W=-A%vmhphc{eFM)%M;SYHZ{K3&_e1FTbsDF>K8Ev}QVWWcxhe0)b>W#z=hWY-+iGY zzmTAB@v+}=(~k#F<7_>C0>WPn-SLLTC;Jv3IsqN&of{A@^i4CKl%a3#;*5;sY4i)U z9fI=k{ZExw3wZ^7i~C7eb?_}->Xq{*uROyjkMv`d@#g$HUEkv6*X`Qg51vI+zQsem zGI!=%{QlK$xsUMZoeFLO`2>B7%aDy|WdgG34Zd_Jd@!$Z_k+YoxkH}FHh06`vgqhr z+>bo&@a{~L9u|GUQ~9{hgmFhSchKH7 zhAAKA_Z^Q1e6?cz?ElQS_^uAL@q^goTdevG@^=REswcls<6Ha$b>jOL|6Xl^x|J=W z@*hv#cJwV)IZpD*aXICXEPqKl!Ie(s?c&Mw)A$y@ZrX$^vu9+7kUm(qL#}PF+vx#2 z#jpE8f%n+@|K?l#lK}k|-iu$g>(2V+xnBF65|FL>O@egB?=j{2y&2!)4BtI8cA|H- zt${s9{CThw&~@xVCbwFY-C5GId0`1a@i(zpJz&YUSP zhnPApK8@YbLY>QI_}|~U_k8^y<(;&+$|^^}^}EOQThiWJIGfF<@iEi=Bf^(WRTV@CfD8{#-PHE^k3j&8$Vyza&fikYl69b8jR(YcJ01y9M^*#9L)xFHU}5 z!TUB$zu^p*c=)z>NV@s%FCO4s@UNSCc5U41#FA1PJJCw9N7y=VYn;6}eak)OxN{Ww z4PQt(C3By))^Gbs?xYE~-rZ@MK9nJtrhaLamEE;_x4$3td1XJ~V`P6+K=zyT?8*LM zo% z+VNF;{Iq=Ez83-qr9FY5~dm|xaM0x-X<%>kHS z)=2@FU)J#fm|xbB0hnLbWB}%uwO;_{m$fDUJKXnM3&4Co#vM)VGVuKv-v;LELgRBU~CEV4Y}}LuNBQ6Gv_Dd7pr{Ug0}RRo*R{C+I{|o z;A#Af$*U`QcX0$~d}0i_gZ!j}d_QdeE<2@t*`p`EZh>Bebh5QH{$24eH=X>vI`i8y zV>P_=kzE2UyMc0M*tf~f<%}-lIrOv-sXLQQxs_M5tB)=a?=9~0V&Gj8zMqyi4rllF z(K`L_?l~gu37sptpTb9rv)yJ--5)FcIyQX6N3f0$=}^bjoOzRsk0CGVSO4Cpn^lIa zEAx8s5qIlZ>u-_F-o8Cg{nNdhQam3Fu3zWa6Q8Qi<<~DBx|6mhu*Wt=JfvM7!n{*` z`@TG?clq(C-scAL-%Xm}IJ9R?HAS5@lcs@l(cs80lk?O%yEZG5Y4^)K$t$;P+yu`m zcZ|Grha7W3(;nrYIh=a({WF=P?D5SE>fAL~{=3dy5rFx6C>wzJdT0(X@owzo6tZuI z{|0wYvL}4iUB;P$q-4;3@8OFc?`qSwd2YWOEMj=?{NBUAe-Sx*wqRFmgk_}F{w4F6 zywXX|H7~W_d-&crTp1gCm^D$;u0IC<=U2M-9(H!W-!GMS+Li0uJb%*tel`6+`~7}v zps)7j=XX8j^zT;tww|#q{c_7+%q@5O{eDk!Cy3gq+WD2>?`dZrbHCr?9rC;&kmvb4 z`+aNyc;=os^g)mZ`EJ&{)PBF;&zQsdJPh%8@b`?>?>oESZyL1aA7W)(InSmqslK)D z|8e*G9RdB|{eFjt-xim~x1j0IBg&}zP>1{dYV7v={kpNvBA(^@_XTMDH}CgTI}iG2 zeIUNP_LStgv-|yOUfTP9zY=R7K7W59jq0_2L;D?q+kgf0$OZB^oM%&SY36X0PrBmc z?)N(s{9qg0sPx|be(OXx>&mx>PxlkrLmyAJYLl&`5$}82!#?i!TLGT0=XckkOSGn! zQhRT|-%ssUW0>UfnD7((zTdCzrS|*%{=&M3(ukkM9zSMWqL17ipn2CP(5wm2tf!33 zQQPnL%b*7v;5VJk{~G>tDeunIq&v<|fp)}k*9x?D5Pib^o}0tmU*q!&r1=S9x#plw z2w!sURHN*yugjK$c zI^)(6Pj{yZ=g*YG-*XrQ41S7BSwC3fxa$Y+{HERSTx;&tUOLvh+BV&Z?+yOtjsM!c zJ41K`8{eA7w=OKo!I>R%KH>IuyU(|Mcih$v^T(XG12BKgSsQ@)w(p7n%(s2B0hn+5 z&I!PL+jn9B=G(sG0x;k9O$A`S?K>y{^KIY00hn+5RtI3d?P~>KzU}+&_u6H!=L}B( zw&x5_0Ji50PXM;(3{L>I=L}B(w&x5FFy9{gv^IAwZBw?Gm2vyu8vgrwp)1eQxBIfW zpZPxD?E8#1_pSrU2R)$v`?&Hum83I)0xsp z?x<3lyST8AVj*i|$x%6z7|@t-s+vaSiJU)sypK z{f|%1SJq9=JK&asQwA&&z^Mq})PoZPrwg!X0H1n^WkXn+2~U3U-|Rv^e)aSs#^b z=glp4>zsnYk8{6e+`ij#4&kiMFl?Pyws3aX>=ib&&MN8dxFmEXpC1X1TPTBAhF8rlIHc{o5?|T6jv> z>Z#{mJhR&}qWE3P9!Z>2Nbt>AeP`#;{*0H@S18^)Cp$09ecx7mT8XR=e!$NKUI#qt!Rvri-?0>M2Y43`?f}Q0jg16e4?O0<>w!~w zu`$5=0`Ka<`vR{9elhTVz;%C_^6dv)Z6ysn0lb?B=e|mKuwvtY4*;(Fn1w$8_;_nk z*}(XMGX7fw)E4K1@=pCI;`Z0nqYzFTgm z&n(#7zjX|4$4>l>Hu%?){GvmovlD+T;j3Hw7tI?uS1P;4+!4^g+#$`HU9!2a z!0{h#JC$%J;SR!F!W_bE0v)bxCZUdSHeni}iO@)(qwTrhZz#{h3Hayjb-y2X4VgOx zR_wb2A2% zefHV#Y3AN~Id$sPIj2sYI#oA_E4zX63Hl@Y9YTLne9LES_2+!M9sKD}>!ZEgiOoHl z&L)3NW|Mz?ev^N*x5?NctKCgzp1mo%$!}s#9>@H5Bl)+GA9t})vWshroYj6QLyShx zlG-@>E*&33HZCDuW8B49KEe2PyM64f24k9`A4Txm2Yy>nxXoX{8d=|Q7TvWb{K6Sg zUc18o95g@KtfPZ|%5SEAE~TFb+kVai-k!`MXDW8SdUCyo_~A7&kb+{zk8F{JWAZvwYWb-<5RMr23!MUlF01={kH z{78

B}C#R=w5m{NJdncgfrRlv5e`buWrZW>0T?CeHoW$ZO!AankF!vvE&%ulmI? zVtQ1Eu@m3v4m!!_Y1GRwmm+_)x2VtHlrneK%+~jN(#_yJ#>F0?AM%fEEceyFvz@pF z(wj(E%;qzqHTaslcHHamecw@UDlYTX2NOS$t&B&PGc2=phjqtT>O5-gf58*K2#(-A z3@o*0;M+FW(4K)0%%%`NHjm&FFN+)z6T)4`u}XTc-Sr*X?CkrXrAH5G>!7FF%|Oq! zw5xvWU3j8j_Hr}*@ux@^-NYm7pQyaI5&2%M0pzmRssA*_EEoE$4`3$zgw(dyrzzik0nr ze-Jvjl{>Jl@f*SiQT{4{yYkz~OTc59>;T_19PqO)XQRPQXQQXm2l0;jS%hbFp1A{@ zQkk3lke9^cgL&=?wmj8Y9q8>&MmdYf_ zOJ-L1+-a89ed;OlWOFGmMP7=$x#YEy*Giu3F6Fh7*Gk?@@-pOQ$dm1*ybO66^4?Eg z8+mQy$^KGa8+mQy9Zz06dF|xM22)-;dF|v)Bd?RZPV!`jDX){fPV(MKo=cufo@_DY zx#YRz9Y$UkdDz6p9#dWyd0pfkNM1L2-Q;OrR9-iE-Q>xR>mjd)JlSQ+>mjd)Jmfc> zB~P}jY%}F$$;*<5;z~~;Zwh(38%=pr$itSV4QyEQrjnPjc~i-oN*;Dr$29V$kvENZ z)tg41Y^RxwXDfV?sQr8>G5)!sm|Lok!|pS7`1r?%615FOC&jSSGCv=RXP+C2GbdA?O~}>S6iBknw*th0(p^) zw3i3`Pk(~@yWnZ*oKn8hkX(z`&mujI{7I(e`?zOY;4hF2b#VvdXnChhlauER80DTo z79{72|CU~q%t+P+_fYCe&NsZqT~^NdCdOa)s%6{{)Zb5=O|1nQiJ z)v5pf8gh@mko{6c7j;-z-vid4DA!C~<*A*+f%PrYjE<}j-_LW2b7C1{&(tT)FBgL= zcnmMF=^L>RlwKr#3F&i5PgbQr?)7uPbkGyh7ovg633eN4FXNjtx)3_`P#2kQFt?dG zC)69t|1f!Pq&M2C>@7eql@-0D{{;VJ>M2j{tB+xxaCwHd@8cUW8gJFpmmZyD&BV~i7&>qDQGs28Qj5!C6W-_lz@fv^8J^wyogF?!2IZ)HaGR&xvOsT|%(p@9# zNY?h`8NEfGbl1pQas}_`JZRWMo^;p9dU6Ht%L2Vco^;p9nsNp2%L2Vco^+S=Rb6CB3CQ>8z>bC8f8>lkQTwbk{V}rJME#7o)dgR&SM;Fegp+TI4?%zX4tL z_z)A{8f^KY7U?b4p3+;Y+X~;cWH*rh_|SN*L5*(PXmpn;ldYob9v}J%JQ(HkQ0_Xc zoQ3w&(%SK zT`=&gJ?~_H3NOs!ZbPkYA9_BP_54?`H>8JlmiKIVXQaH=*RkyH{Fw95^D6%(%Dc#0 z6EZ3}*8BWq&bHI`aGv1T!|#~6J^$Y5hT*w3=di5F5l zjPBrTIG(3+jr*(Ey8K@G6zj$FSuc8hrd*f>I5y1=Ua z{M=W~eX;7piQpQChB15-j*EYSwV|W6A@5onI$9s08^=(liL_*-Omn16k}_$^w2+pH zlo=Z-lcLNx%IrZ}YoyGckuv%Y@m`b}Pg*8YWK#3A56+}-}vw}AV4`%~Ys{g&>(hiCOW z4c$k_gsn@^XE*rfXf!5Fv=={0FZG~5FHc<9;O;j+eq^P$UG^^g(nWlQbYg5!c3pp6 zc9Hli&KSq>i6a+BV!tuXp^p`#fDU~J{IleaYnPj~r zp345x&rg0BoD$yb!?BQyw5VZT8p7X);{wAIF^8LPeQ+v;9 zH_$@_ZWi74=>KmGs0(`$Fd@I58%M*gLY0`Z=<9QiF#n*~|*6pzL z;@rtU8_&xbD}%QW?2txfwQ2ErR_TS^#}=%ly=b4Jb5QC%Bm1{uoXack9!U%Ld7qD@ zh5Ni4BWYor%lb%K80WH%G|8^!nYN7NROf`@1L*k;@Gj|lNzhULNsW*6!x{8V@}uv2 zr?SeU9^*5`j!&qMJCPB^8Yj3PazDnYopEZ*F>gSZQiV13ttE5c!h1Dd+>_@F;y(la zRkWMT1oKmB5L_zoTG_^46PK!Q>T0akJFlU0FK)ybtKY)g!bjg7PaM9azH@HMEN0({ zxkKsGA7*Y^Y`>*D$9!*7?H!=8$_H&PP@k*I>#=Fe@f*=*KB${?>1Q>-LG7!*x6;1G zF6^(F>w)uejW>3N=Ij#R{8nFt?+xkKi2b~xUc$~>#dC(|SZ80o%(LKV-Vb5SdL0;7 zL|`mYJ-%5e_$B0T_QwN%anyd8!nmS$ec{px9bA`h07Udm4>~yp&eB)XDKF5jWT%Hd z>OCtwDuL`As^?Phe6XI&!SgeE9t@s4d5-m5Sr-kHv?aYS9VOby){y*bOeKGcqtDQe z=F*FQ7uXv;jML-52A4W#{1=`}`fg1=c)wkJn0H0J9oz(GhUl7DzJNNV%$4<6&sFR>_rECmYb-?j*3z!_-ic!ZTc(TteS&%+{eS(>$d#qP z=5x&->?0cb&jwC+g#H7W(O)vVJ6da=k^FT;a6U$LpmjLU ziq`DE8Csi|G}?+4u`??0Vvc+NX){^U_Y~&pyMimmWaoS7Jp4%?M8^w-A29TMfu0A0 z=LLE$1kY#j99w{I*+u@cSD9}ph%dO?W9NLbcMO?_&vhoGDf=le!TJ{8|G~mFoX5lu zFyJerP#I#RxIJE6XW?j)bM}K*id`tJqE?PVJXG5=N8+BtF zO%wj5Kp!1#`z76Ul%6X=dQH#tUFqFC%VsKhSD_PEnD1YUM`S}e)B9i4{ktLWJMg~j zv(Sd>`8ykmeQs+*{R|r_DjQLm7_G0^lU|bm=Qwl`oirwC@JcM^`=5is`xuL}^7#7K z&UyIj!XI7=W##4Z@LKlDdUvw_H}YA;WIGKqX7o|EochuXjHmufcEBZ#7&6B_C2v{> z$)_z`JlYez_54dc7lP+4!Xu({`a(SEqsl&M>cNZRr#$vgG0;7strgPz4)7e!_u7Nj z+7&(6q4^|{W32L(+C`!ZeHQ%pIl&qhThFXvbF3va-s0~);kU8eH>LOayzk9B%=e_) z(cF^3&ohPc;k#qgQ=}he;e6QE<4*4_#MVwcwwvhOa{?_6pe!xq(_-xX&%XdAmqKsgERAUCMPT^g53*8Ri zYL74D%!tc3qcY;#@?L!7i2le|jQrHkJ?m9-7Df4_*S@`DhdCpX;(nl2)XQ)$RZ~`Z z%gvr+Tdv>OO=b2M)9!NiwF2AaF6y-agE4Lh{!uq>-`WH`y=#s=f_Js?8}L*el{r*p zfGt@VLs{it23+|RT1b;_Q(76=nmdG_U|oG`%;22jS#Ty@qd|Su3rWR zotK~Z_^xH|676VD{aMSiXehefZu@nS?biVB!b>z*!?R>=gr+0UX*a;1c(3|FqGjoX z`nkwx>DWD-d-;g$)d+j%>AS|Rfc>WN18W-7KJJ+4q1zLA%%zFQ2#OC^E*PY|+9CISD zrQgLDf6#Lwcs|-Z?|$9+3ED%S?X*E6`ful5{{QGq=r7c#NPPMMY7aW8KO6N7t@OM% z&n;PGC<9(DbY#9wR`_8j$(9puSEsTr=dWzO#|8KQC_epe+LB!zo)vm|Pw=h;^t(-X zfV0L-x*%EF^-SnHk4BGLoYzn`w3*+u|Bt%6`2U1MA;95s@}z^b)))g0EiUwfX7Yzj zjI@6lPzVp4-@8&tf}V zN8a`P^c_0+*0g7+@Aas?t4P0^U(V)fuTgj4>|tRYYx}Emg1-lKE;@#|BK~ehAAVGK z6h_+8IijdPW!s@6zLQXgd6BeGhi!dg=dwj+L4yo)t>~U(EHlO6oOZK|e#)@s%~oprd{=Y89M-0M6E-{G9|Jwv z`%7PDQ;#1iG&Cq~0j7+Wl4ly61U%(?Z@za}~XMRK*QUB&el7~tFe?57j&N6

m&Vm#OV?Fh3ojwg-df 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 %pW4*hW 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�cna!*mseQBJB*) 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

U#lPCW`{9#({BylBB`dyf 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

}0IU%p3@xW^XuEN~$GJhhrMMW@2OI)&@L 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

`n;EddT(WX=|x}A1U-%M2#-1xA=I%5 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

$>_u|8AijwWMwqJh9jfJuoy-wQ*#^lxaYR} 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

=dK~cclaFajnRY&{b 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 a{LSBJm_ctf!2SDg|Bc1(MJABr>;DIN{Z3T? literal 0 HcmV?d00001 diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/aes.h b/Hin2n/src/main/jniLibs/x86/include/openssl/aes.h new file mode 100644 index 00000000..245c552a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/aes.h @@ -0,0 +1,92 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_AES_H +# define HEADER_AES_H + +# include + +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/asn1.h b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1.h new file mode 100644 index 00000000..9522eec1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1.h @@ -0,0 +1,886 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include +# include +# include +# include +# include +# include + +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG /*compat*/ V_ASN1_PRIMITIVE_TAG + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_UNDEF -1 +/* ASN.1 tag values */ +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 + +/* + * NB the constants below are used internally by ASN1_INTEGER + * and ASN1_ENUMERATED to indicate the sign. They are *not* on + * the wire tag values. + */ + +# define V_ASN1_NEG 0x100 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) + +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DEFINE_STACK_OF(X509_ALGOR) + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* String is embedded and only content should be freed */ +# define ASN1_STRING_FLAG_EMBED 0x080 +/* String should be parsed in RFC 5280's time format */ +# define ASN1_STRING_FLAG_X509_TIME 0x100 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +/* + * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted + * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting + * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias + * STABLE_FLAGS_CLEAR to reflect this. + */ +# define STABLE_FLAGS_CLEAR STABLE_FLAGS_MALLOC +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DEFINE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * This flag specifies that RC2254 escaping shall be performed. + */ +#define ASN1_STRFLGS_ESC_2254 0x400 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DEFINE_STACK_OF(ASN1_INTEGER) + +DEFINE_STACK_OF(ASN1_GENERALSTRING) + +DEFINE_STACK_OF(ASN1_UTF8STRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DEFINE_STACK_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(const ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t); +void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DEFINE_STACK_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(const ASN1_STRING *x); +DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)) +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, + const unsigned char *flags, int flags_len); + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, + BIT_STRING_BITNAME *tbl); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(const ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); +int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str); +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_normalize(ASN1_TIME *s); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t); +int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b); + +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r); +int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r); + + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_STDIO +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags); +int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +const char *ASN1_tag2str(int tag); + +/* Used to load and write Netscape format cert */ + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); +void ASN1_add_stable_module(void); + +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +int ASN1_str2mask(const char *str, unsigned long *pmask); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)); +void ASN1_SCTX_free(ASN1_SCTX *p); +const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p); +const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p); +unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p); +void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data); +void *ASN1_SCTX_get_app_data(ASN1_SCTX *p); + +const BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +const ASN1_ITEM *ASN1_ITEM_lookup(const char *name); +const ASN1_ITEM *ASN1_ITEM_get(size_t i); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/asn1_mac.h b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1_mac.h new file mode 100644 index 00000000..7ac1782a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1_mac.h @@ -0,0 +1,10 @@ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#error "This file is obsolete; please update your software." diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/asn1err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1err.h new file mode 100644 index 00000000..faed5a55 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1err.h @@ -0,0 +1,256 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1ERR_H +# define HEADER_ASN1ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASN1_strings(void); + +/* + * ASN1 function codes. + */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIO_INIT 113 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DO_LOCK 233 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENC_SAVE 115 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_INT64 224 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_GET_UINT64 225 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EMBED_D2I 120 +# define ASN1_F_ASN1_ITEM_EMBED_NEW 121 +# define ASN1_F_ASN1_ITEM_FLAGS_I2D 118 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PRIMITIVE_NEW 119 +# define ASN1_F_ASN1_SCTX_NEW 221 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_GET_INT64 227 +# define ASN1_F_ASN1_STRING_GET_UINT64 230 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TO_BN 228 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_STRING 229 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_C2I_IBUF 226 +# define ASN1_F_C2I_UINT64_INT 101 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_DO_BUF 142 +# define ASN1_F_DO_CREATE 124 +# define ASN1_F_DO_DUMP 125 +# define ASN1_F_DO_TCREATE 222 +# define ASN1_F_I2A_ASN1_OBJECT 126 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_OBJECT 143 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_NDEF_PREFIX 127 +# define ASN1_F_NDEF_SUFFIX 136 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE2_SET_SCRYPT 231 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_PKCS5_SCRYPT_SET 232 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_STABLE_GET 138 +# define ASN1_F_STBL_MODULE_INIT 223 +# define ASN1_F_UINT32_C2I 105 +# define ASN1_F_UINT32_NEW 139 +# define ASN1_F_UINT64_C2I 112 +# define ASN1_F_UINT64_NEW 141 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_PKEY_NEW 173 + +/* + * ASN1 reason codes. + */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NEGATIVE_VALUE 226 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_PADDING 221 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_ILLEGAL_ZERO_CONTENT 222 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SCRYPT_PARAMETERS 227 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_STRING_TABLE_VALUE 218 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_INVALID_VALUE 219 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NESTED_TOO_DEEP 201 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LARGE 223 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TOO_SMALL 224 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 195 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 228 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_INTEGER_TYPE 225 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/asn1t.h b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1t.h new file mode 100644 index 00000000..a450ba0d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/asn1t.h @@ -0,0 +1,945 @@ +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +# define static_ASN1_ITEM_start(itname) \ + static const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define static_ASN1_ITEM_start(itname) \ + static ASN1_ITEM_start(itname) + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) +# define static_ASN1_BROKEN_SEQUENCE_END(stname) \ + static_ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) +# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) +/* Embedded simple type */ +# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) +# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) +# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ + const char *field_name; /* Field name */ + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + int (*adb_cb)(long *psel); /* Application callback */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT (ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT) + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT (ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT) + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* Field is embedded and not a pointer */ +# define ASN1_TFLG_EMBED (0x1 << 12) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ + const char *sname; /* Structure name */ +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \ + static stname *d2i_##stname(stname **a, \ + const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \ + ASN1_ITEM_rptr(stname)); \ + } \ + static int i2d_##stname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, \ + ASN1_ITEM_rptr(stname)); \ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(INT32) +DECLARE_ASN1_ITEM(ZINT32) +DECLARE_ASN1_ITEM(UINT32) +DECLARE_ASN1_ITEM(ZUINT32) +DECLARE_ASN1_ITEM(INT64) +DECLARE_ASN1_ITEM(ZINT64) +DECLARE_ASN1_ITEM(UINT64) +DECLARE_ASN1_ITEM(ZUINT64) + +# if OPENSSL_API_COMPAT < 0x10200000L +/* + * LONG and ZLONG are strongly discouraged for use as stored data, as the + * underlying C type (long) differs in size depending on the architecture. + * They are designed with 32-bit longs in mind. + */ +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) +# endif + +DEFINE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/async.h b/Hin2n/src/main/jniLibs/x86/include/openssl/async.h new file mode 100644 index 00000000..7052b890 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/async.h @@ -0,0 +1,76 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifndef HEADER_ASYNC_H +# define HEADER_ASYNC_H + +#if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include to use this */ +#define OSSL_ASYNC_FD HANDLE +#define OSSL_BAD_ASYNC_FD INVALID_HANDLE_VALUE +# endif +#else +#define OSSL_ASYNC_FD int +#define OSSL_BAD_ASYNC_FD -1 +#endif +# include + + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct async_job_st ASYNC_JOB; +typedef struct async_wait_ctx_st ASYNC_WAIT_CTX; + +#define ASYNC_ERR 0 +#define ASYNC_NO_JOBS 1 +#define ASYNC_PAUSE 2 +#define ASYNC_FINISH 3 + +int ASYNC_init_thread(size_t max_size, size_t init_size); +void ASYNC_cleanup_thread(void); + +#ifdef OSSL_ASYNC_FD +ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); +void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); +int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD fd, + void *custom_data, + void (*cleanup)(ASYNC_WAIT_CTX *, const void *, + OSSL_ASYNC_FD, void *)); +int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD *fd, void **custom_data); +int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, + size_t *numfds); +int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); +#endif + +int ASYNC_is_capable(void); + +int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret, + int (*func)(void *), void *args, size_t size); +int ASYNC_pause_job(void); + +ASYNC_JOB *ASYNC_get_current_job(void); +ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job); +void ASYNC_block_pause(void); +void ASYNC_unblock_pause(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/asyncerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/asyncerr.h new file mode 100644 index 00000000..91afbbb2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/asyncerr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASYNCERR_H +# define HEADER_ASYNCERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASYNC_strings(void); + +/* + * ASYNC function codes. + */ +# define ASYNC_F_ASYNC_CTX_NEW 100 +# define ASYNC_F_ASYNC_INIT_THREAD 101 +# define ASYNC_F_ASYNC_JOB_NEW 102 +# define ASYNC_F_ASYNC_PAUSE_JOB 103 +# define ASYNC_F_ASYNC_START_FUNC 104 +# define ASYNC_F_ASYNC_START_JOB 105 +# define ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD 106 + +/* + * ASYNC reason codes. + */ +# define ASYNC_R_FAILED_TO_SET_POOL 101 +# define ASYNC_R_FAILED_TO_SWAP_CONTEXT 102 +# define ASYNC_R_INIT_FAILED 105 +# define ASYNC_R_INVALID_POOL_SIZE 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/bio.h b/Hin2n/src/main/jniLibs/x86/include/openssl/bio.h new file mode 100644 index 00000000..ae559a51 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/bio.h @@ -0,0 +1,801 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* There are the classes of BIOs */ +# define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM ( 1|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_FILE ( 2|BIO_TYPE_SOURCE_SINK) + +# define BIO_TYPE_FD ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_SOCKET ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_NULL ( 6|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_SSL ( 7|BIO_TYPE_FILTER) +# define BIO_TYPE_MD ( 8|BIO_TYPE_FILTER) +# define BIO_TYPE_BUFFER ( 9|BIO_TYPE_FILTER) +# define BIO_TYPE_CIPHER (10|BIO_TYPE_FILTER) +# define BIO_TYPE_BASE64 (11|BIO_TYPE_FILTER) +# define BIO_TYPE_CONNECT (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ACCEPT (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) + +# define BIO_TYPE_NBIO_TEST (16|BIO_TYPE_FILTER)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|BIO_TYPE_FILTER) +# define BIO_TYPE_BIO (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|BIO_TYPE_FILTER) +# define BIO_TYPE_DGRAM (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ASN1 (22|BIO_TYPE_FILTER) +# define BIO_TYPE_COMP (23|BIO_TYPE_FILTER) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# endif + +#define BIO_TYPE_START 128 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_PEEK 29/* BIO_f_buffer special */ +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +/* Deliberately outside of OPENSSL_NO_SCTP - used in bss_dgram.c */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: + * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way; + * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 +# define BIO_FLAGS_NONCLEAR_RST 0x400 +# define BIO_FLAGS_IN_EOF 0x800 + +typedef union bio_addr_st BIO_ADDR; +typedef struct bio_addrinfo_st BIO_ADDRINFO; + +int BIO_get_new_index(void); +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi, + long argl, long ret); +typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp, + size_t len, int argi, + long argl, int ret, size_t *processed); +BIO_callback_fn BIO_get_callback(const BIO *b); +void BIO_set_callback(BIO *b, BIO_callback_fn callback); + +BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b); +void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback); + +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +typedef struct bio_method_st BIO_METHOD; + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef int BIO_info_cb(BIO *, int, int); +typedef BIO_info_cb bio_info_cb; /* backward compatibility */ + +DEFINE_STACK_OF(BIO) + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +/* # define BIO_C_SET_PROXY_PARAM 103 */ +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +/* # define BIO_C_GET_PROXY_PARAM 121 */ +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_C_SET_CONNECT_MODE 155 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +# ifndef OPENSSL_NO_SOCK +/* IP families we support, for BIO_s_connect() and BIO_s_accept() */ +/* Note: the underlying operating system may not support some of them */ +# define BIO_FAMILY_IPV4 4 +# define BIO_FAMILY_IPV6 6 +# define BIO_FAMILY_IPANY 256 + +/* BIO_s_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0, \ + (char *)(name)) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1, \ + (char *)(port)) +# define BIO_set_conn_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2, \ + (char *)(addr)) +# define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f) +# define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)) +# define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) +# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) +# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ + (char *)(name)) +# define BIO_set_accept_port(b,port) BIO_ctrl(b,BIO_C_SET_ACCEPT,1, \ + (char *)(port)) +# define BIO_get_accept_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)) +# define BIO_get_accept_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1)) +# define BIO_get_peer_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2)) +# define BIO_get_peer_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3)) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,3, \ + (char *)(bio)) +# define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) +# define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) + +/* Aliases kept for backward compatibility */ +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR +# define BIO_BIND_REUSEADDR_IF_UNUSED BIO_SOCK_REUSEADDR +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# endif /* OPENSSL_NO_SOCK */ + +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)(c)) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)(fp)) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)(fpp)) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)(name)) +# endif +# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)(ssl)) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)(sslp)) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)(md)) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)(pp)) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)(bm)) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0, \ + (char *)(pp)) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) +# define BIO_buffer_peek(b,s,l) BIO_ctrl(b,BIO_CTRL_PEEK,(l),(s)) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)(peer)) +# define BIO_ctrl_set_connected(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)(peer)) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef) +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +uint64_t BIO_number_read(BIO *bio); +uint64_t BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +const BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +# ifndef OPENSSL_NO_STDIO +BIO *BIO_new_fp(FILE *stream, int close_flag); +# endif +BIO *BIO_new(const BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_set_data(BIO *a, void *ptr); +void *BIO_get_data(BIO *a); +void BIO_set_init(BIO *a, int init); +int BIO_get_init(BIO *a); +void BIO_set_shutdown(BIO *a, int shut); +int BIO_get_shutdown(BIO *a); +void BIO_vfree(BIO *a); +int BIO_up_ref(BIO *a); +int BIO_read(BIO *b, void *data, int dlen); +int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int dlen); +int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); +void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +void BIO_set_next(BIO *b, BIO *next); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +void BIO_set_retry_reason(BIO *bio, int reason); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +const BIO_METHOD *BIO_s_mem(void); +const BIO_METHOD *BIO_s_secmem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +# ifndef OPENSSL_NO_SOCK +const BIO_METHOD *BIO_s_socket(void); +const BIO_METHOD *BIO_s_connect(void); +const BIO_METHOD *BIO_s_accept(void); +# endif +const BIO_METHOD *BIO_s_fd(void); +const BIO_METHOD *BIO_s_log(void); +const BIO_METHOD *BIO_s_bio(void); +const BIO_METHOD *BIO_s_null(void); +const BIO_METHOD *BIO_f_null(void); +const BIO_METHOD *BIO_f_buffer(void); +const BIO_METHOD *BIO_f_linebuffer(void); +const BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_datagram(void); +int BIO_dgram_non_fatal_error(int error); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +const BIO_METHOD *BIO_s_datagram_sctp(void); +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +# endif + +# ifndef OPENSSL_NO_SOCK +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +# endif + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_STDIO +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen); + +# ifndef OPENSSL_NO_SOCK +BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, + const void *where, size_t wherelen, unsigned short port); +void BIO_ADDR_free(BIO_ADDR *); +void BIO_ADDR_clear(BIO_ADDR *ap); +int BIO_ADDR_family(const BIO_ADDR *ap); +int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l); +unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap); +char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_path_string(const BIO_ADDR *ap); + +const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai); +const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai); +void BIO_ADDRINFO_free(BIO_ADDRINFO *bai); + +enum BIO_hostserv_priorities { + BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV +}; +int BIO_parse_hostserv(const char *hostserv, char **host, char **service, + enum BIO_hostserv_priorities hostserv_prio); +enum BIO_lookup_type { + BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER +}; +int BIO_lookup(const char *host, const char *service, + enum BIO_lookup_type lookup_type, + int family, int socktype, BIO_ADDRINFO **res); +int BIO_lookup_ex(const char *host, const char *service, + int lookup_type, int family, int socktype, int protocol, + BIO_ADDRINFO **res); +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_sock_init(void); +# if OPENSSL_API_COMPAT < 0x10100000L +# define BIO_sock_cleanup() while(0) continue +# endif +int BIO_set_tcp_ndelay(int sock, int turn_on); + +DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name)) +DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr)) +DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip)) +DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode)) +DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port)) + +union BIO_sock_info_u { + BIO_ADDR *addr; +}; +enum BIO_sock_info_type { + BIO_SOCK_INFO_ADDRESS +}; +int BIO_sock_info(int sock, + enum BIO_sock_info_type type, union BIO_sock_info_u *info); + +# define BIO_SOCK_REUSEADDR 0x01 +# define BIO_SOCK_V6_ONLY 0x02 +# define BIO_SOCK_KEEPALIVE 0x04 +# define BIO_SOCK_NONBLOCK 0x08 +# define BIO_SOCK_NODELAY 0x10 + +int BIO_socket(int domain, int socktype, int protocol, int options); +int BIO_connect(int sock, const BIO_ADDR *addr, int options); +int BIO_bind(int sock, const BIO_ADDR *addr, int options); +int BIO_listen(int sock, const BIO_ADDR *addr, int options); +int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options); +int BIO_closesocket(int sock); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); +# endif /* OPENSSL_NO_SOCK*/ + +BIO *BIO_new_fd(int fd, int close_flag); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# define ossl_bio__attr__(x) +# if defined(__GNUC__) && defined(__STDC_VERSION__) \ + && !defined(__APPLE__) + /* + * Because we support the 'z' modifier, which made its appearance in C99, + * we can't use __attribute__ with pre C99 dialects. + */ +# if __STDC_VERSION__ >= 199901L +# undef ossl_bio__attr__ +# define ossl_bio__attr__ __attribute__ +# if __GNUC__*10 + __GNUC_MINOR__ >= 44 +# define ossl_bio__printf__ __gnu_printf__ +# else +# define ossl_bio__printf__ __printf__ +# endif +# endif +# endif +int BIO_printf(BIO *bio, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 0))); +# undef ossl_bio__attr__ +# undef ossl_bio__printf__ + + +BIO_METHOD *BIO_meth_new(int type, const char *name); +void BIO_meth_free(BIO_METHOD *biom); +int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int); +int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t, + size_t *); +int BIO_meth_set_write(BIO_METHOD *biom, + int (*write) (BIO *, const char *, int)); +int BIO_meth_set_write_ex(BIO_METHOD *biom, + int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); +int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); +int BIO_meth_set_read(BIO_METHOD *biom, + int (*read) (BIO *, char *, int)); +int BIO_meth_set_read_ex(BIO_METHOD *biom, + int (*bread) (BIO *, char *, size_t, size_t *)); +int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); +int BIO_meth_set_puts(BIO_METHOD *biom, + int (*puts) (BIO *, const char *)); +int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); +int BIO_meth_set_gets(BIO_METHOD *biom, + int (*gets) (BIO *, char *, int)); +long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); +int BIO_meth_set_ctrl(BIO_METHOD *biom, + long (*ctrl) (BIO *, int, long, void *)); +int (*BIO_meth_get_create(const BIO_METHOD *bion)) (BIO *); +int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); +int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *); +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); +long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) + (BIO *, int, BIO_info_cb *); +int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl) (BIO *, int, + BIO_info_cb *)); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/bioerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/bioerr.h new file mode 100644 index 00000000..46e2c96e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/bioerr.h @@ -0,0 +1,124 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIOERR_H +# define HEADER_BIOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BIO_strings(void); + +/* + * BIO function codes. + */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_ADDRINFO_WRAP 148 +# define BIO_F_ADDR_STRINGS 134 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_ACCEPT_EX 137 +# define BIO_F_BIO_ACCEPT_NEW 152 +# define BIO_F_BIO_ADDR_NEW 144 +# define BIO_F_BIO_BIND 147 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CONNECT 138 +# define BIO_F_BIO_CONNECT_NEW 153 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_NEW_INDEX 102 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_LISTEN 139 +# define BIO_F_BIO_LOOKUP 135 +# define BIO_F_BIO_LOOKUP_EX 143 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_METH_NEW 146 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_DGRAM_SCTP 145 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PARSE_HOSTSERV 136 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_READ_EX 105 +# define BIO_F_BIO_READ_INTERN 120 +# define BIO_F_BIO_SOCKET 140 +# define BIO_F_BIO_SOCKET_NBIO 142 +# define BIO_F_BIO_SOCK_INFO 141 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BIO_WRITE_EX 119 +# define BIO_F_BIO_WRITE_INTERN 128 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_NEW 149 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_DOAPR_OUTCH 150 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_LINEBUFFER_NEW 151 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_NBIOF_NEW 154 +# define BIO_F_SLG_WRITE 155 +# define BIO_F_SSL_NEW 118 + +/* + * BIO reason codes. + */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET 141 +# define BIO_R_AMBIGUOUS_HOST_OR_SERVICE 129 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_GETSOCKNAME_ERROR 132 +# define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 +# define BIO_R_GETTING_SOCKTYPE 134 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_SOCKET 135 +# define BIO_R_IN_USE 123 +# define BIO_R_LENGTH_TOO_LONG 102 +# define BIO_R_LISTEN_V6_ONLY 136 +# define BIO_R_LOOKUP_RETURNED_NOTHING 142 +# define BIO_R_MALFORMED_HOST_OR_SERVICE 130 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 +# define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_KEEPALIVE 137 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNABLE_TO_NODELAY 138 +# define BIO_R_UNABLE_TO_REUSEADDR 139 +# define BIO_R_UNAVAILABLE_IP_FAMILY 145 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNKNOWN_INFO_TYPE 140 +# define BIO_R_UNSUPPORTED_IP_FAMILY 146 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/blowfish.h b/Hin2n/src/main/jniLibs/x86/include/openssl/blowfish.h new file mode 100644 index 00000000..cd3e460e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/blowfish.h @@ -0,0 +1,61 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include + +# ifndef OPENSSL_NO_BF +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define BF_LONG unsigned int + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/bn.h b/Hin2n/src/main/jniLibs/x86/include/openssl/bn.h new file mode 100644 index 00000000..8af05d00 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/bn.h @@ -0,0 +1,539 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 64-bit processor with LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULONG unsigned long +# define BN_BYTES 8 +# endif + +/* + * 64-bit processor other than LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT +# define BN_ULONG unsigned long long +# define BN_BYTES 8 +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_ULONG unsigned int +# define BN_BYTES 4 +# endif + +# define BN_BITS2 (BN_BYTES * 8) +# define BN_BITS (BN_BITS2 * 2) +# define BN_TBIT ((BN_ULONG)1 << (BN_BITS2 - 1)) + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 +# define BN_FLG_SECURE 0x08 + +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +# define BN_FLG_FREE 0x8000 /* used for debugging */ +# endif + +void BN_set_flags(BIGNUM *b, int n); +int BN_get_flags(const BIGNUM *b, int n); + +/* Values for |top| in BN_rand() */ +#define BN_RAND_TOP_ANY -1 +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +/* Values for |bottom| in BN_rand() */ +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot be used in parallel!). Also only for *read only* use. The + * value |dest| should be a newly allocated BIGNUM obtained via BN_new() that + * has not been otherwise initialised or used. + */ +void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags); + +/* Wrapper function to make using BN_GENCB easier */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); + +BN_GENCB *BN_GENCB_new(void); +void BN_GENCB_free(BN_GENCB *cb); + +/* Populate a BN_GENCB structure with an "old"-style callback */ +void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *), + void *cb_arg); + +/* Populate a BN_GENCB structure with a "new"-style callback */ +void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *), + void *cb_arg); + +void *BN_GENCB_get_arg(BN_GENCB *cb); + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations + * that will be done for checking that a random number is probably prime. The + * error rate for accepting a composite number as prime depends on the size of + * the prime |b|. The error rates used are for calculating an RSA key with 2 primes, + * and so the level is what you would expect for a key of double the size of the + * prime. + * + * This table is generated using the algorithm of FIPS PUB 186-4 + * Digital Signature Standard (DSS), section F.1, page 117. + * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) + * + * The following magma script was used to generate the output: + * securitybits:=125; + * k:=1024; + * for t:=1 to 65 do + * for M:=3 to Floor(2*Sqrt(k-1)-1) do + * S:=0; + * // Sum over m + * for m:=3 to M do + * s:=0; + * // Sum over j + * for j:=2 to m do + * s+:=(RealField(32)!2)^-(j+(k-1)/j); + * end for; + * S+:=2^(m-(m-1)*t)*s; + * end for; + * A:=2^(k-2-M*t); + * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; + * pkt:=2.00743*Log(2)*k*2^-k*(A+B); + * seclevel:=Floor(-Log(2,pkt)); + * if seclevel ge securitybits then + * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; + * break; + * end if; + * end for; + * if seclevel ge securitybits then break; end if; + * end for; + * + * It can be run online at: + * http://magma.maths.usyd.edu.au/calc + * + * And will output: + * k: 1024, security: 129 bits (t: 6, M: 23) + * + * k is the number of bits of the prime, securitybits is the level we want to + * reach. + * + * prime length | RSA key size | # MR tests | security level + * -------------+--------------|------------+--------------- + * (b) >= 6394 | >= 12788 | 3 | 256 bit + * (b) >= 3747 | >= 7494 | 3 | 192 bit + * (b) >= 1345 | >= 2690 | 4 | 128 bit + * (b) >= 1080 | >= 2160 | 5 | 128 bit + * (b) >= 852 | >= 1704 | 5 | 112 bit + * (b) >= 476 | >= 952 | 5 | 80 bit + * (b) >= 400 | >= 800 | 6 | 80 bit + * (b) >= 347 | >= 694 | 7 | 80 bit + * (b) >= 308 | >= 616 | 8 | 80 bit + * (b) >= 55 | >= 110 | 27 | 64 bit + * (b) >= 6 | >= 12 | 34 | 64 bit + */ + +# define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ + (b) >= 1345 ? 4 : \ + (b) >= 476 ? 5 : \ + (b) >= 400 ? 6 : \ + (b) >= 347 ? 7 : \ + (b) >= 308 ? 8 : \ + (b) >= 55 ? 27 : \ + /* b >= 6 */ 34) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_zero(const BIGNUM *a); +int BN_is_one(const BIGNUM *a); +int BN_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_odd(const BIGNUM *a); + +# define BN_one(a) (BN_set_word((a),1)) + +void BN_zero_ex(BIGNUM *a); + +# if OPENSSL_API_COMPAT >= 0x00908000L +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +BN_CTX *BN_CTX_secure_new(void); +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG l); +int BN_security_bits(int L, int N); +BIGNUM *BN_new(void); +BIGNUM *BN_secure_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param b pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +int BN_is_negative(const BIGNUM *b); + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_STDIO +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +int BN_print(BIO *bio, const BIGNUM *a); +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +DEPRECATEDIN_0_9_8(BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, + const BIGNUM *rem, + void (*callback) (int, int, + void *), + void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg, + int do_trial_division)) + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); + +int BN_BLINDING_is_current_thread(BN_BLINDING *b); +void BN_BLINDING_set_current_thread(BN_BLINDING *b); +int BN_BLINDING_lock(BN_BLINDING *b); +int BN_BLINDING_unlock(BN_BLINDING *b); + +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +DEPRECATEDIN_0_9_8(void BN_set_params(int mul, int high, int low, int mont)) +DEPRECATEDIN_0_9_8(int BN_get_params(int which)) /* 0, mul, 1 high, 2 low, 3 + * mont */ + +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a, + const BIGNUM *field, BN_CTX *ctx); + +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, const unsigned char *message, + size_t message_len, BN_CTX *ctx); + +/* Primes from RFC 2409 */ +BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define get_rfc2409_prime_768 BN_get_rfc2409_prime_768 +# define get_rfc2409_prime_1024 BN_get_rfc2409_prime_1024 +# define get_rfc3526_prime_1536 BN_get_rfc3526_prime_1536 +# define get_rfc3526_prime_2048 BN_get_rfc3526_prime_2048 +# define get_rfc3526_prime_3072 BN_get_rfc3526_prime_3072 +# define get_rfc3526_prime_4096 BN_get_rfc3526_prime_4096 +# define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144 +# define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192 +# endif + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/bnerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/bnerr.h new file mode 100644 index 00000000..9f3c7cfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/bnerr.h @@ -0,0 +1,100 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BNERR_H +# define HEADER_BNERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BN_strings(void); + +/* + * BN function codes. + */ +# define BN_F_BNRAND 127 +# define BN_F_BNRAND_RANGE 138 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_COMPUTE_WNAF 142 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GENCB_NEW 143 +# define BN_F_BN_GENERATE_DSA_NONCE 140 +# define BN_F_BN_GENERATE_PRIME_EX 141 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MONT_CTX_NEW 149 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_POOL_GET 147 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RECP_CTX_NEW 150 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_SET_WORDS 144 +# define BN_F_BN_STACK_PUSH 148 +# define BN_F_BN_USUB 115 + +/* + * BN reason codes. + */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_PRIVATE_KEY_TOO_LARGE 117 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/buffer.h b/Hin2n/src/main/jniLibs/x86/include/openssl/buffer.h new file mode 100644 index 00000000..d2765766 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/buffer.h @@ -0,0 +1,58 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include +# ifndef HEADER_CRYPTO_H +# include +# endif +# include + + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include + +/* + * These names are outdated as of OpenSSL 1.1; a future release + * will move them to be deprecated. + */ +# define BUF_strdup(s) OPENSSL_strdup(s) +# define BUF_strndup(s, size) OPENSSL_strndup(s, size) +# define BUF_memdup(data, size) OPENSSL_memdup(data, size) +# define BUF_strlcpy(dst, src, size) OPENSSL_strlcpy(dst, src, size) +# define BUF_strlcat(dst, src, size) OPENSSL_strlcat(dst, src, size) +# define BUF_strnlen(str, maxlen) OPENSSL_strnlen(str, maxlen) + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ + unsigned long flags; +}; + +# define BUF_MEM_FLAG_SECURE 0x01 + +BUF_MEM *BUF_MEM_new(void); +BUF_MEM *BUF_MEM_new_ex(unsigned long flags); +void BUF_MEM_free(BUF_MEM *a); +size_t BUF_MEM_grow(BUF_MEM *str, size_t len); +size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/buffererr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/buffererr.h new file mode 100644 index 00000000..04f6ff7a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/buffererr.h @@ -0,0 +1,34 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFERR_H +# define HEADER_BUFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BUF_strings(void); + +/* + * BUF function codes. + */ +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 + +/* + * BUF reason codes. + */ + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/camellia.h b/Hin2n/src/main/jniLibs/x86/include/openssl/camellia.h new file mode 100644 index 00000000..151f3c13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/camellia.h @@ -0,0 +1,83 @@ +/* + * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include + +# ifndef OPENSSL_NO_CAMELLIA +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cast.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cast.h new file mode 100644 index 00000000..2cc89ae0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cast.h @@ -0,0 +1,53 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +# include + +# ifndef OPENSSL_NO_CAST +# ifdef __cplusplus +extern "C" { +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cmac.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cmac.h new file mode 100644 index 00000000..3535a9ab --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cmac.h @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +# ifndef OPENSSL_NO_CMAC + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cms.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cms.h new file mode 100644 index 00000000..c7627968 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cms.h @@ -0,0 +1,339 @@ +/* + * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include + +# ifndef OPENSSL_NO_CMS +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DEFINE_STACK_OF(CMS_SignerInfo) +DEFINE_STACK_OF(CMS_RecipientEncryptedKey) +DEFINE_STACK_OF(CMS_RecipientInfo) +DEFINE_STACK_OF(CMS_RevocationInfoChoice) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 +# define CMS_ASCIICRLF 0x80000 + +const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + const unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* Backward compatibility for spelling errors. */ +# define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \ + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cmserr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cmserr.h new file mode 100644 index 00000000..7dbc13dc --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cmserr.h @@ -0,0 +1,202 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMSERR_H +# define HEADER_CMSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CMS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CMS_strings(void); + +/* + * CMS function codes. + */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT 179 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_ENV_ASN1_CTRL 171 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SD_ASN1_CTRL 170 +# define CMS_F_CMS_SET1_IAS 176 +# define CMS_F_CMS_SET1_KEYID 177 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_SI_CHECK_ATTRIBUTES 183 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 +# define CMS_F_KEK_UNWRAP_KEY 180 + +/* + * CMS reason codes. + */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_ATTRIBUTE_ERROR 161 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_AGREEMENT 181 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/comp.h b/Hin2n/src/main/jniLibs/x86/include/openssl/comp.h new file mode 100644 index 00000000..d814d3cf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/comp.h @@ -0,0 +1,53 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include + +# ifndef OPENSSL_NO_COMP +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx); +int COMP_CTX_get_type(const COMP_CTX* comp); +int COMP_get_type(const COMP_METHOD *meth); +const char *COMP_get_name(const COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); + +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); + +COMP_METHOD *COMP_zlib(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +#define COMP_zlib_cleanup() while(0) continue +#endif + +# ifdef HEADER_BIO_H +# ifdef ZLIB +const BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/comperr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/comperr.h new file mode 100644 index 00000000..90231e9a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/comperr.h @@ -0,0 +1,44 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMPERR_H +# define HEADER_COMPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_COMP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_COMP_strings(void); + +/* + * COMP function codes. + */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 +# define COMP_F_COMP_CTX_NEW 103 + +/* + * COMP reason codes. + */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/conf.h b/Hin2n/src/main/jniLibs/x86/include/openssl/conf.h new file mode 100644 index 00000000..7336cd2f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/conf.h @@ -0,0 +1,168 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DEFINE_STACK_OF(CONF_VALUE) +DEFINE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DEFINE_STACK_OF(CONF_MODULE) +DEFINE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_STDIO +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +#ifndef OPENSSL_NO_STDIO +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +#endif +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name)) + +#if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_no_config() \ + OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL) +#endif + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_STDIO +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +#ifndef OPENSSL_NO_STDIO +int NCONF_dump_fp(const CONF *conf, FILE *out); +#endif +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +#if OPENSSL_API_COMPAT < 0x10100000L +# define CONF_modules_free() while(0) continue +#endif +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/conf_api.h b/Hin2n/src/main/jniLibs/x86/include/openssl/conf_api.h new file mode 100644 index 00000000..a0275ad7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/conf_api.h @@ -0,0 +1,40 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/conferr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/conferr.h new file mode 100644 index 00000000..32b92291 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/conferr.h @@ -0,0 +1,76 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONFERR_H +# define HEADER_CONFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CONF_strings(void); + +/* + * CONF function codes. + */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_GET_NEXT_FILE 107 +# define CONF_F_MODULE_ADD 122 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_PROCESS_INCLUDE 116 +# define CONF_F_SSL_MODULE_INIT 123 +# define CONF_F_STR_COPY 101 + +/* + * CONF reason codes. + */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_NUMBER_TOO_LARGE 121 +# define CONF_R_RECURSIVE_DIRECTORY_INCLUDE 111 +# define CONF_R_SSL_COMMAND_SECTION_EMPTY 117 +# define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND 118 +# define CONF_R_SSL_SECTION_EMPTY 119 +# define CONF_R_SSL_SECTION_NOT_FOUND 120 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/crypto.h b/Hin2n/src/main/jniLibs/x86/include/openssl/crypto.h new file mode 100644 index 00000000..7d0b5262 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/crypto.h @@ -0,0 +1,445 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include +# include + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif + +# include +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSLeay OpenSSL_version_num +# define SSLeay_version OpenSSL_version +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION OPENSSL_VERSION +# define SSLEAY_CFLAGS OPENSSL_CFLAGS +# define SSLEAY_BUILT_ON OPENSSL_BUILT_ON +# define SSLEAY_PLATFORM OPENSSL_PLATFORM +# define SSLEAY_DIR OPENSSL_DIR + +/* + * Old type for allocating dynamic locks. No longer used. Use the new thread + * API instead. + */ +typedef struct { + int dummy; +} CRYPTO_dynlock; + +# endif /* OPENSSL_API_COMPAT */ + +typedef void CRYPTO_RWLOCK; + +CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); +int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); +void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); + +int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); + +/* + * The following can be used to detect memory leaks in the library. If + * used, it turns on malloc checking + */ +# define CRYPTO_MEM_CHECK_OFF 0x0 /* Control only */ +# define CRYPTO_MEM_CHECK_ON 0x1 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3 /* Control only */ + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; +DEFINE_STACK_OF(void) + +/* + * Per class, we have a STACK of function pointers. + */ +# define CRYPTO_EX_INDEX_SSL 0 +# define CRYPTO_EX_INDEX_SSL_CTX 1 +# define CRYPTO_EX_INDEX_SSL_SESSION 2 +# define CRYPTO_EX_INDEX_X509 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_DH 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_EC_KEY 8 +# define CRYPTO_EX_INDEX_RSA 9 +# define CRYPTO_EX_INDEX_ENGINE 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_BIO 12 +# define CRYPTO_EX_INDEX_APP 13 +# define CRYPTO_EX_INDEX_UI_METHOD 14 +# define CRYPTO_EX_INDEX_DRBG 15 +# define CRYPTO_EX_INDEX__COUNT 16 + +/* No longer needed, so this is a no-op */ +#define OPENSSL_malloc_init() while(0) continue + +int CRYPTO_mem_ctrl(int mode); + +# define OPENSSL_malloc(num) \ + CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_zalloc(num) \ + CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_realloc(addr, num) \ + CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_realloc(addr, old_num, num) \ + CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_free(addr, num) \ + CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_free(addr) \ + CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_memdup(str, s) \ + CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strdup(str) \ + CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strndup(str, n) \ + CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_malloc(num) \ + CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_zalloc(num) \ + CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_free(addr) \ + CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_clear_free(addr, num) \ + CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_actual_size(ptr) \ + CRYPTO_secure_actual_size(ptr) + +size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz); +size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz); +size_t OPENSSL_strnlen(const char *str, size_t maxlen); +char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); +unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); +int OPENSSL_hexchar2int(unsigned char c); + +# define OPENSSL_MALLOC_MAX_NELEMS(type) (((1U<<(sizeof(int)*8-1))-1)/sizeof(type)) + +unsigned long OpenSSL_version_num(void); +const char *OpenSSL_version(int type); +# define OPENSSL_VERSION 0 +# define OPENSSL_CFLAGS 1 +# define OPENSSL_BUILT_ON 2 +# define OPENSSL_PLATFORM 3 +# define OPENSSL_DIR 4 +# define OPENSSL_ENGINES_DIR 5 + +int OPENSSL_issetugid(void); + +typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* No longer use an index. */ +int CRYPTO_free_ex_index(int class_index, int idx); + +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + const CRYPTO_EX_DATA *from); + +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); + +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +# define CRYPTO_cleanup_all_ex_data() while(0) continue + +/* + * The old locking functions have been removed completely without compatibility + * macros. This is because the old functions either could not properly report + * errors, or the returned error values were not clearly documented. + * Replacing the locking functions with no-ops would cause race condition + * issues in the affected applications. It is far better for them to fail at + * compile time. + * On the other hand, the locking callbacks are no longer used. Consequently, + * the callback management functions can be safely replaced with no-op macros. + */ +# define CRYPTO_num_locks() (1) +# define CRYPTO_set_locking_callback(func) +# define CRYPTO_get_locking_callback() (NULL) +# define CRYPTO_set_add_lock_callback(func) +# define CRYPTO_get_add_lock_callback() (NULL) + +/* + * These defines where used in combination with the old locking callbacks, + * they are not called anymore, but old code that's not called might still + * use them. + */ +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +/* This structure is no longer used */ +typedef struct crypto_threadid_st { + int dummy; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +# define CRYPTO_THREADID_set_numeric(id, val) +# define CRYPTO_THREADID_set_pointer(id, ptr) +# define CRYPTO_THREADID_set_callback(threadid_func) (0) +# define CRYPTO_THREADID_get_callback() (NULL) +# define CRYPTO_THREADID_current(id) +# define CRYPTO_THREADID_cmp(a, b) (-1) +# define CRYPTO_THREADID_cpy(dest, src) +# define CRYPTO_THREADID_hash(id) (0UL) + +# if OPENSSL_API_COMPAT < 0x10000000L +# define CRYPTO_set_id_callback(func) +# define CRYPTO_get_id_callback() (NULL) +# define CRYPTO_thread_id() (0UL) +# endif /* OPENSSL_API_COMPAT < 0x10000000L */ + +# define CRYPTO_set_dynlock_create_callback(dyn_create_function) +# define CRYPTO_set_dynlock_lock_callback(dyn_lock_function) +# define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function) +# define CRYPTO_get_dynlock_create_callback() (NULL) +# define CRYPTO_get_dynlock_lock_callback() (NULL) +# define CRYPTO_get_dynlock_destroy_callback() (NULL) +# endif /* OPENSSL_API_COMPAT < 0x10100000L */ + +int CRYPTO_set_mem_functions( + void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, int), + void (*f) (void *, const char *, int)); +int CRYPTO_set_mem_debug(int flag); +void CRYPTO_get_mem_functions( + void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, int), + void (**f) (void *, const char *, int)); + +void *CRYPTO_malloc(size_t num, const char *file, int line); +void *CRYPTO_zalloc(size_t num, const char *file, int line); +void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line); +void CRYPTO_free(void *ptr, const char *file, int line); +void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line); +void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line); +void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, + const char *file, int line); + +int CRYPTO_secure_malloc_init(size_t sz, int minsize); +int CRYPTO_secure_malloc_done(void); +void *CRYPTO_secure_malloc(size_t num, const char *file, int line); +void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); +void CRYPTO_secure_free(void *ptr, const char *file, int line); +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); +int CRYPTO_secure_allocated(const void *ptr); +int CRYPTO_secure_malloc_initialized(void); +size_t CRYPTO_secure_actual_size(void *ptr); +size_t CRYPTO_secure_used(void); + +void OPENSSL_cleanse(void *ptr, size_t len); + +# ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_mem_debug_push(info) \ + CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_mem_debug_pop() \ + CRYPTO_mem_debug_pop() +int CRYPTO_mem_debug_push(const char *info, const char *file, int line); +int CRYPTO_mem_debug_pop(void); +void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount); + +/*- + * Debugging functions (enabled by CRYPTO_set_mem_debug(1)) + * The flag argument has the following significance: + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line); + +int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +int CRYPTO_mem_leaks_fp(FILE *); +# endif +int CRYPTO_mem_leaks(BIO *bio); +# endif + +/* die if we have to */ +ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line); +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l)) +# endif +# define OPENSSL_assert(e) \ + (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1)) + +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); +# ifdef OPENSSL_SYS_UNIX +void OPENSSL_fork_prepare(void); +void OPENSSL_fork_parent(void); +void OPENSSL_fork_child(void); +# endif + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to); + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len); + +/* Standard initialisation options */ +# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L +# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L +# define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L +# define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L +# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0x00000010L +# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0x00000020L +# define OPENSSL_INIT_LOAD_CONFIG 0x00000040L +# define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000080L +# define OPENSSL_INIT_ASYNC 0x00000100L +# define OPENSSL_INIT_ENGINE_RDRAND 0x00000200L +# define OPENSSL_INIT_ENGINE_DYNAMIC 0x00000400L +# define OPENSSL_INIT_ENGINE_OPENSSL 0x00000800L +# define OPENSSL_INIT_ENGINE_CRYPTODEV 0x00001000L +# define OPENSSL_INIT_ENGINE_CAPI 0x00002000L +# define OPENSSL_INIT_ENGINE_PADLOCK 0x00004000L +# define OPENSSL_INIT_ENGINE_AFALG 0x00008000L +/* OPENSSL_INIT_ZLIB 0x00010000L */ +# define OPENSSL_INIT_ATFORK 0x00020000L +/* OPENSSL_INIT_BASE_ONLY 0x00040000L */ +# define OPENSSL_INIT_NO_ATEXIT 0x00080000L +/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */ +/* Max OPENSSL_INIT flag value is 0x80000000 */ + +/* openssl and dasync not counted as builtin */ +# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \ + (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \ + | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \ + OPENSSL_INIT_ENGINE_PADLOCK) + + +/* Library initialisation functions */ +void OPENSSL_cleanup(void); +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_atexit(void (*handler)(void)); +void OPENSSL_thread_stop(void); + +/* Low-level control of initialization */ +OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); +# ifndef OPENSSL_NO_STDIO +int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, + const char *config_filename); +void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, + unsigned long flags); +int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, + const char *config_appname); +# endif +void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); + +# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +# if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include in order to use this */ +typedef DWORD CRYPTO_THREAD_LOCAL; +typedef DWORD CRYPTO_THREAD_ID; + +typedef LONG CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif +# else +# include +typedef pthread_once_t CRYPTO_ONCE; +typedef pthread_key_t CRYPTO_THREAD_LOCAL; +typedef pthread_t CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif +# endif + +# if !defined(CRYPTO_ONCE_STATIC_INIT) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif + +int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + +int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); +void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); +int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); +int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); + +CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); +int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cryptoerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cryptoerr.h new file mode 100644 index 00000000..3db5a4ee --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cryptoerr.h @@ -0,0 +1,57 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTOERR_H +# define HEADER_CRYPTOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CRYPTO_strings(void); + +/* + * CRYPTO function codes. + */ +# define CRYPTO_F_CMAC_CTX_NEW 120 +# define CRYPTO_F_CRYPTO_DUP_EX_DATA 110 +# define CRYPTO_F_CRYPTO_FREE_EX_DATA 111 +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_MEMDUP 115 +# define CRYPTO_F_CRYPTO_NEW_EX_DATA 112 +# define CRYPTO_F_CRYPTO_OCB128_COPY_CTX 121 +# define CRYPTO_F_CRYPTO_OCB128_INIT 122 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_GET_AND_LOCK 113 +# define CRYPTO_F_OPENSSL_ATEXIT 114 +# define CRYPTO_F_OPENSSL_BUF2HEXSTR 117 +# define CRYPTO_F_OPENSSL_FOPEN 119 +# define CRYPTO_F_OPENSSL_HEXSTR2BUF 118 +# define CRYPTO_F_OPENSSL_INIT_CRYPTO 116 +# define CRYPTO_F_OPENSSL_LH_NEW 126 +# define CRYPTO_F_OPENSSL_SK_DEEP_COPY 127 +# define CRYPTO_F_OPENSSL_SK_DUP 128 +# define CRYPTO_F_PKEY_HMAC_INIT 123 +# define CRYPTO_F_PKEY_POLY1305_INIT 124 +# define CRYPTO_F_PKEY_SIPHASH_INIT 125 +# define CRYPTO_F_SK_RESERVE 129 + +/* + * CRYPTO reason codes. + */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 +# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ct.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ct.h new file mode 100644 index 00000000..ebdba34d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ct.h @@ -0,0 +1,474 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CT_H +# define HEADER_CT_H + +# include + +# ifndef OPENSSL_NO_CT +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + +/* Minimum RSA key size, from RFC6962 */ +# define SCT_MIN_RSA_BITS 2048 + +/* All hashes are SHA256 in v1 of Certificate Transparency */ +# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH + +typedef enum { + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1 +} ct_log_entry_type_t; + +typedef enum { + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0 +} sct_version_t; + +typedef enum { + SCT_SOURCE_UNKNOWN, + SCT_SOURCE_TLS_EXTENSION, + SCT_SOURCE_X509V3_EXTENSION, + SCT_SOURCE_OCSP_STAPLED_RESPONSE +} sct_source_t; + +typedef enum { + SCT_VALIDATION_STATUS_NOT_SET, + SCT_VALIDATION_STATUS_UNKNOWN_LOG, + SCT_VALIDATION_STATUS_VALID, + SCT_VALIDATION_STATUS_INVALID, + SCT_VALIDATION_STATUS_UNVERIFIED, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION +} sct_validation_status_t; + +DEFINE_STACK_OF(SCT) +DEFINE_STACK_OF(CTLOG) + +/****************************************** + * CT policy evaluation context functions * + ******************************************/ + +/* + * Creates a new, empty policy evaluation context. + * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished + * with the CT_POLICY_EVAL_CTX. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); + +/* Deletes a policy evaluation context and anything it owns. */ +void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); + +/* Gets the peer certificate that the SCTs are for */ +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the certificate associated with the received SCTs. + * Increments the reference count of cert. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); + +/* Gets the issuer of the aforementioned certificate */ +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the issuer of the certificate associated with the received SCTs. + * Increments the reference count of issuer. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); + +/* Gets the CT logs that are trusted sources of SCTs */ +const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); + +/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */ +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store); + +/* + * Gets the time, in milliseconds since the Unix epoch, that will be used as the + * current time when checking whether an SCT was issued in the future. + * Such SCTs will fail validation, as required by RFC6962. + */ +uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch. + * If an SCT's timestamp is after this time, it will be interpreted as having + * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs + * whose timestamp is in the future", so an SCT will not validate in this case. + */ +void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); + +/***************** + * SCT functions * + *****************/ + +/* + * Creates a new, blank SCT. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new(void); + +/* + * Creates a new SCT from some base64-encoded strings. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new_from_base64(unsigned char version, + const char *logid_base64, + ct_log_entry_type_t entry_type, + uint64_t timestamp, + const char *extensions_base64, + const char *signature_base64); + +/* + * Frees the SCT and the underlying data structures. + */ +void SCT_free(SCT *sct); + +/* + * Free a stack of SCTs, and the underlying SCTs themselves. + * Intended to be compatible with X509V3_EXT_FREE. + */ +void SCT_LIST_free(STACK_OF(SCT) *a); + +/* + * Returns the version of the SCT. + */ +sct_version_t SCT_get_version(const SCT *sct); + +/* + * Set the version of an SCT. + * Returns 1 on success, 0 if the version is unrecognized. + */ +__owur int SCT_set_version(SCT *sct, sct_version_t version); + +/* + * Returns the log entry type of the SCT. + */ +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct); + +/* + * Set the log entry type of an SCT. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type); + +/* + * Gets the ID of the log that an SCT came from. + * Ownership of the log ID remains with the SCT. + * Returns the length of the log ID. + */ +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id); + +/* + * Set the log ID of an SCT to point directly to the *log_id specified. + * The SCT takes ownership of the specified pointer. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len); + +/* + * Set the log ID of an SCT. + * This makes a copy of the log_id. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, + size_t log_id_len); + +/* + * Returns the timestamp for the SCT (epoch time in milliseconds). + */ +uint64_t SCT_get_timestamp(const SCT *sct); + +/* + * Set the timestamp of an SCT (epoch time in milliseconds). + */ +void SCT_set_timestamp(SCT *sct, uint64_t timestamp); + +/* + * Return the NID for the signature used by the SCT. + * For CT v1, this will be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset). + */ +int SCT_get_signature_nid(const SCT *sct); + +/* + * Set the signature type of an SCT + * For CT v1, this should be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_signature_nid(SCT *sct, int nid); + +/* + * Set *ext to point to the extension data for the SCT. ext must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext); + +/* + * Set the extensions of an SCT to point directly to the *ext specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len); + +/* + * Set the extensions of an SCT. + * This takes a copy of the ext. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext, + size_t ext_len); + +/* + * Set *sig to point to the signature for the SCT. sig must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig); + +/* + * Set the signature of an SCT to point directly to the *sig specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len); + +/* + * Set the signature of an SCT to be a copy of the *sig specified. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig, + size_t sig_len); + +/* + * The origin of this SCT, e.g. TLS extension, OCSP response, etc. + */ +sct_source_t SCT_get_source(const SCT *sct); + +/* + * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_source(SCT *sct, sct_source_t source); + +/* + * Returns a text string describing the validation status of |sct|. + */ +const char *SCT_validation_status_string(const SCT *sct); + +/* + * Pretty-prints an |sct| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came + * from, so that the log name can be printed. + */ +void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs); + +/* + * Pretty-prints an |sct_list| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * SCTs will be delimited by |separator|. + * If |logs| is not NULL, it will be used to lookup the CT log that each SCT + * came from, so that the log names can be printed. + */ +void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *logs); + +/* + * Gets the last result of validating this SCT. + * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET. + */ +sct_validation_status_t SCT_get_validation_status(const SCT *sct); + +/* + * Validates the given SCT with the provided context. + * Sets the "validation_status" field of the SCT. + * Returns 1 if the SCT is valid and the signature verifies. + * Returns 0 if the SCT is invalid or could not be verified. + * Returns -1 if an error occurs. + */ +__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); + +/* + * Validates the given list of SCTs with the provided context. + * Sets the "validation_status" field of each SCT. + * Returns 1 if there are no invalid SCTs and all signatures verify. + * Returns 0 if at least one SCT is invalid or could not be verified. + * Returns a negative integer if an error occurs. + */ +__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts, + CT_POLICY_EVAL_CTX *ctx); + + +/********************************* + * SCT parsing and serialisation * + *********************************/ + +/* + * Serialize (to TLS format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just return the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Convert TLS format SCT list to a stack of SCTs. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + size_t len); + +/* + * Serialize (to DER format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just returns the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Parses an SCT list in DER format and returns it. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + long len); + +/* + * Serialize (to TLS format) an |sct| and write it to |out|. + * If |out| is null, no SCT will be output but the length will still be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format SCT. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the TLS-format SCT will be written + * to it. + * The length of the SCT in TLS format will be returned. + */ +__owur int i2o_SCT(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT in TLS format and returns it. + * If |psct| is not null, it will end up pointing to the parsed SCT. If it + * already points to a non-null pointer, the pointer will be free'd. + * |in| should be a pointer to a string containing the TLS-format SCT. + * |in| will be advanced to the end of the SCT if parsing succeeds. + * |len| should be the length of the SCT in |in|. + * Returns NULL if an error occurs. + * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len' + * fields will be populated (with |in| and |len| respectively). + */ +SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); + +/******************** + * CT log functions * + ********************/ + +/* + * Creates a new CT log instance with the given |public_key| and |name|. + * Takes ownership of |public_key| but copies |name|. + * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); + +/* + * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER + * in |pkey_base64|. The |name| is a string to help users identify this log. + * Returns 1 on success, 0 on failure. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +int CTLOG_new_from_base64(CTLOG ** ct_log, + const char *pkey_base64, const char *name); + +/* + * Deletes a CT log instance and its fields. + */ +void CTLOG_free(CTLOG *log); + +/* Gets the name of the CT log */ +const char *CTLOG_get0_name(const CTLOG *log); +/* Gets the ID of the CT log */ +void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, + size_t *log_id_len); +/* Gets the public key of the CT log */ +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); + +/************************** + * CT log store functions * + **************************/ + +/* + * Creates a new CT log store. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new(void); + +/* + * Deletes a CT log store and all of the CT log instances held within. + */ +void CTLOG_STORE_free(CTLOG_STORE *store); + +/* + * Finds a CT log in the store based on its log ID. + * Returns the CT log, or NULL if no match is found. + */ +const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, + const uint8_t *log_id, + size_t log_id_len); + +/* + * Loads a CT log list into a |store| from a |file|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file); + +/* + * Loads the default CT log list into a |store|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/cterr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/cterr.h new file mode 100644 index 00000000..feb7bc56 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/cterr.h @@ -0,0 +1,80 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CTERR_H +# define HEADER_CTERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CT + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CT_strings(void); + +/* + * CT function codes. + */ +# define CT_F_CTLOG_NEW 117 +# define CT_F_CTLOG_NEW_FROM_BASE64 118 +# define CT_F_CTLOG_NEW_FROM_CONF 119 +# define CT_F_CTLOG_STORE_LOAD_CTX_NEW 122 +# define CT_F_CTLOG_STORE_LOAD_FILE 123 +# define CT_F_CTLOG_STORE_LOAD_LOG 130 +# define CT_F_CTLOG_STORE_NEW 131 +# define CT_F_CT_BASE64_DECODE 124 +# define CT_F_CT_POLICY_EVAL_CTX_NEW 133 +# define CT_F_CT_V1_LOG_ID_FROM_PKEY 125 +# define CT_F_I2O_SCT 107 +# define CT_F_I2O_SCT_LIST 108 +# define CT_F_I2O_SCT_SIGNATURE 109 +# define CT_F_O2I_SCT 110 +# define CT_F_O2I_SCT_LIST 111 +# define CT_F_O2I_SCT_SIGNATURE 112 +# define CT_F_SCT_CTX_NEW 126 +# define CT_F_SCT_CTX_VERIFY 128 +# define CT_F_SCT_NEW 100 +# define CT_F_SCT_NEW_FROM_BASE64 127 +# define CT_F_SCT_SET0_LOG_ID 101 +# define CT_F_SCT_SET1_EXTENSIONS 114 +# define CT_F_SCT_SET1_LOG_ID 115 +# define CT_F_SCT_SET1_SIGNATURE 116 +# define CT_F_SCT_SET_LOG_ENTRY_TYPE 102 +# define CT_F_SCT_SET_SIGNATURE_NID 103 +# define CT_F_SCT_SET_VERSION 104 + +/* + * CT reason codes. + */ +# define CT_R_BASE64_DECODE_ERROR 108 +# define CT_R_INVALID_LOG_ID_LENGTH 100 +# define CT_R_LOG_CONF_INVALID 109 +# define CT_R_LOG_CONF_INVALID_KEY 110 +# define CT_R_LOG_CONF_MISSING_DESCRIPTION 111 +# define CT_R_LOG_CONF_MISSING_KEY 112 +# define CT_R_LOG_KEY_INVALID 113 +# define CT_R_SCT_FUTURE_TIMESTAMP 116 +# define CT_R_SCT_INVALID 104 +# define CT_R_SCT_INVALID_SIGNATURE 107 +# define CT_R_SCT_LIST_INVALID 105 +# define CT_R_SCT_LOG_ID_MISMATCH 114 +# define CT_R_SCT_NOT_SET 106 +# define CT_R_SCT_UNSUPPORTED_VERSION 115 +# define CT_R_UNRECOGNIZED_SIGNATURE_NID 101 +# define CT_R_UNSUPPORTED_ENTRY_TYPE 102 +# define CT_R_UNSUPPORTED_VERSION 103 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/des.h b/Hin2n/src/main/jniLibs/x86/include/openssl/des.h new file mode 100644 index 00000000..be4abbdf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/des.h @@ -0,0 +1,174 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include + +# ifndef OPENSSL_NO_DES +# ifdef __cplusplus +extern "C" { +# endif +# include + +typedef unsigned int DES_LONG; + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +# define DES_fixup_key_parity DES_set_odd_parity + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/dh.h b/Hin2n/src/main/jniLibs/x86/include/openssl/dh.h new file mode 100644 index 00000000..3527540c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/dh.h @@ -0,0 +1,340 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include + +# ifndef OPENSSL_NO_DH +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + +# define DH_FLAG_CACHE_MONT_P 0x01 + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +DECLARE_ASN1_ITEM(DHparams) + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 +# define DH_CHECK_Q_NOT_PRIME 0x10 +# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_PUBKEY_INVALID 0x04 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_bits(const DH *dh); +int DH_size(const DH *dh); +int DH_security_bits(const DH *dh); +#define DH_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, l, p, newf, dupf, freef) +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check_params_ex(const DH *dh); +int DH_check_ex(const DH *dh); +int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key); +int DH_check_params(const DH *dh, int *ret); +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); +int i2d_DHxparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_STDIO +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +int DHparams_print(BIO *bp, const DH *x); + +/* RFC 5114 parameters */ +DH *DH_get_1024_160(void); +DH *DH_get_2048_224(void); +DH *DH_get_2048_256(void); + +/* Named parameters, currently RFC7919 */ +DH *DH_new_by_nid(int nid); +int DH_get_nid(const DH *dh); + +# ifndef OPENSSL_NO_CMS +/* RFC2631 KDF */ +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif + +void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DH_get0_p(const DH *dh); +const BIGNUM *DH_get0_q(const DH *dh); +const BIGNUM *DH_get0_g(const DH *dh); +const BIGNUM *DH_get0_priv_key(const DH *dh); +const BIGNUM *DH_get0_pub_key(const DH *dh); +void DH_clear_flags(DH *dh, int flags); +int DH_test_flags(const DH *dh, int flags); +void DH_set_flags(DH *dh, int flags); +ENGINE *DH_get0_engine(DH *d); +long DH_get_length(const DH *dh); +int DH_set_length(DH *dh, long length); + +DH_METHOD *DH_meth_new(const char *name, int flags); +void DH_meth_free(DH_METHOD *dhm); +DH_METHOD *DH_meth_dup(const DH_METHOD *dhm); +const char *DH_meth_get0_name(const DH_METHOD *dhm); +int DH_meth_set1_name(DH_METHOD *dhm, const char *name); +int DH_meth_get_flags(const DH_METHOD *dhm); +int DH_meth_set_flags(DH_METHOD *dhm, int flags); +void *DH_meth_get0_app_data(const DH_METHOD *dhm); +int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data); +int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *)); +int (*DH_meth_get_compute_key(const DH_METHOD *dhm)) + (unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_meth_set_compute_key(DH_METHOD *dhm, + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh)); +int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm)) + (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DH_meth_set_bn_mod_exp(DH_METHOD *dhm, + int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *); +int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *)); +int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *)); +int (*DH_meth_get_generate_params(const DH_METHOD *dhm)) + (DH *, int, int, BN_GENCB *); +int DH_meth_set_generate_params(DH_METHOD *dhm, + int (*generate_params) (DH *, int, int, BN_GENCB *)); + + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, \ + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_DH_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_dh_pad(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_PAD, pad, NULL) + +# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)) + +# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(poid)) + +# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)(plen)) + +# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(p)) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) +# define EVP_PKEY_CTRL_DH_NID (EVP_PKEY_ALG_CTRL + 15) +# define EVP_PKEY_CTRL_DH_PAD (EVP_PKEY_ALG_CTRL + 16) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# ifndef OPENSSL_NO_CMS +# define EVP_PKEY_DH_KDF_X9_42 2 +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/dherr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/dherr.h new file mode 100644 index 00000000..916b3bed --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/dherr.h @@ -0,0 +1,88 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DHERR_H +# define HEADER_DHERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DH + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DH_strings(void); + +/* + * DH function codes. + */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_CHECK_EX 121 +# define DH_F_DH_CHECK_PARAMS_EX 122 +# define DH_F_DH_CHECK_PUB_KEY_EX 123 +# define DH_F_DH_CMS_DECRYPT 114 +# define DH_F_DH_CMS_SET_PEERKEY 115 +# define DH_F_DH_CMS_SET_SHARED_INFO 116 +# define DH_F_DH_METH_DUP 117 +# define DH_F_DH_METH_NEW 118 +# define DH_F_DH_METH_SET1_NAME 119 +# define DH_F_DH_NEW_BY_NID 104 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PKEY_PUBLIC_CHECK 124 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_PKEY_DH_CTRL_STR 120 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_INIT 125 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* + * DH reason codes. + */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_CHECK_INVALID_J_VALUE 115 +# define DH_R_CHECK_INVALID_Q_VALUE 116 +# define DH_R_CHECK_PUBKEY_INVALID 122 +# define DH_R_CHECK_PUBKEY_TOO_LARGE 123 +# define DH_R_CHECK_PUBKEY_TOO_SMALL 124 +# define DH_R_CHECK_P_NOT_PRIME 117 +# define DH_R_CHECK_P_NOT_SAFE_PRIME 118 +# define DH_R_CHECK_Q_NOT_PRIME 119 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PARAMETER_NAME 110 +# define DH_R_INVALID_PARAMETER_NID 114 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KDF_PARAMETER_ERROR 112 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_MISSING_PUBKEY 125 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NOT_SUITABLE_GENERATOR 120 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 +# define DH_R_PEER_KEY_ERROR 111 +# define DH_R_SHARED_INFO_ERROR 113 +# define DH_R_UNABLE_TO_CHECK_GENERATOR 121 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/dsa.h b/Hin2n/src/main/jniLibs/x86/include/openssl/dsa.h new file mode 100644 index 00000000..6d8a18a4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/dsa.h @@ -0,0 +1,244 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include + +# ifndef OPENSSL_NO_DSA +# ifdef __cplusplus +extern "C" { +# endif +# include +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + +# define DSA_FLAG_CACHE_MONT_P 0x01 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 +# define DSA_FLAG_FIPS_CHECKED 0x0800 + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st DSA_SIG; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); +const DSA_METHOD *DSA_get_method(DSA *d); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); +int DSA_bits(const DSA *d); +int DSA_security_bits(const DSA *d); + /* next 4 return -1 on error */ +DEPRECATEDIN_1_2_0(int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)) +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +#define DSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, l, p, newf, dupf, freef) +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DSA *DSA_generate_parameters(int bits, + unsigned char *seed, + int seed_len, + int *counter_ret, + unsigned long *h_ret, void + (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# ifndef OPENSSL_NO_STDIO +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 64 +/* + * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only + * have one value here we set the number of checks to 64 which is the 128 bit + * security level that is the highest level and valid for creating a 3072 bit + * DSA key. + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DSA_get0_p(const DSA *d); +const BIGNUM *DSA_get0_q(const DSA *d); +const BIGNUM *DSA_get0_g(const DSA *d); +const BIGNUM *DSA_get0_pub_key(const DSA *d); +const BIGNUM *DSA_get0_priv_key(const DSA *d); +void DSA_clear_flags(DSA *d, int flags); +int DSA_test_flags(const DSA *d, int flags); +void DSA_set_flags(DSA *d, int flags); +ENGINE *DSA_get0_engine(DSA *d); + +DSA_METHOD *DSA_meth_new(const char *name, int flags); +void DSA_meth_free(DSA_METHOD *dsam); +DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam); +const char *DSA_meth_get0_name(const DSA_METHOD *dsam); +int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name); +int DSA_meth_get_flags(const DSA_METHOD *dsam); +int DSA_meth_set_flags(DSA_METHOD *dsam, int flags); +void *DSA_meth_get0_app_data(const DSA_METHOD *dsam); +int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data); +DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA *); +int DSA_meth_set_sign(DSA_METHOD *dsam, + DSA_SIG *(*sign) (const unsigned char *, int, DSA *)); +int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam)) + (DSA *, BN_CTX *, BIGNUM **, BIGNUM **); +int DSA_meth_set_sign_setup(DSA_METHOD *dsam, + int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **)); +int (*DSA_meth_get_verify(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA_SIG *, DSA *); +int DSA_meth_set_verify(DSA_METHOD *dsam, + int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *)); +int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_mod_exp(DSA_METHOD *dsam, + int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, + BN_MONT_CTX *)); +int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam, + int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *); +int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *)); +int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *)); +int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam)) + (DSA *, int, const unsigned char *, int, int *, unsigned long *, + BN_GENCB *); +int DSA_meth_set_paramgen(DSA_METHOD *dsam, + int (*paramgen) (DSA *, int, const unsigned char *, int, int *, + unsigned long *, BN_GENCB *)); +int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *)); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/dsaerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/dsaerr.h new file mode 100644 index 00000000..495a1ac8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/dsaerr.h @@ -0,0 +1,72 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSAERR_H +# define HEADER_DSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DSA + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DSA_strings(void); + +/* + * DSA function codes. + */ +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_BUILTIN_PARAMGEN 125 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_METH_DUP 127 +# define DSA_F_DSA_METH_NEW 128 +# define DSA_F_DSA_METH_SET1_NAME 129 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 102 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_CTRL_STR 104 +# define DSA_F_PKEY_DSA_KEYGEN 121 + +/* + * DSA reason codes. + */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MISSING_PRIVATE_KEY 111 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 +# define DSA_R_Q_NOT_PRIME 113 +# define DSA_R_SEED_LEN_SMALL 110 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/dtls1.h b/Hin2n/src/main/jniLibs/x86/include/openssl/dtls1.h new file mode 100644 index 00000000..d55ca9c3 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/dtls1.h @@ -0,0 +1,55 @@ +/* + * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS1_2_VERSION 0xFEFD +# define DTLS_MIN_VERSION DTLS1_VERSION +# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +/* Special value for method supporting multiple versions */ +# define DTLS_ANY_VERSION 0x1FFFF + +/* lengths of messages */ +/* + * Actually the max cookie length in DTLS is 255. But we can't change this now + * due to compatibility concerns. + */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# define DTLS1_AL_HEADER_LENGTH 2 + +/* Timeout multipliers */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/e_os2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/e_os2.h new file mode 100644 index 00000000..97a776cd --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/e_os2.h @@ -0,0 +1,300 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYS_MSDOS) +# undef OPENSSL_SYS_UNIX +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +/* + * UEFI lives here because it might be built with a Microsoft toolchain and + * we need to avoid the false positive match on Windows. + */ +# if defined(OPENSSL_SYS_UEFI) +# undef OPENSSL_SYS_UNIX +# elif defined(OPENSSL_SYS_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN__) || defined(OPENSSL_SYS_CYGWIN) +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYS_WIN32) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN32) +# define OPENSSL_SYS_WIN32 +# endif +# endif +# if defined(_WIN64) || defined(OPENSSL_SYS_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYS_WINNT) +# undef OPENSSL_SYS_UNIX +# endif +# if defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYS_VMS) +# if !defined(OPENSSL_SYS_VMS) +# undef OPENSSL_SYS_UNIX +# endif +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) && !defined(OPENSSL_SYS_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# if defined(_AIX) && !defined(OPENSSL_SYS_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) && !defined(OPENSSL_SYS_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * OPENSSL_EXTERN is normally used to declare a symbol with possible extra + * attributes to handle its presence in a shared library. + * OPENSSL_EXPORT is used to define a symbol with extra possible attributes + * to make it visible in a shared library. + * Care needs to be taken when a header file is used both to declare and + * define symbols. Basically, for any library that exports some global + * variables, the following code must be present in the header file that + * declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT and OPENSSL_EXTERN + * have some generally sensible values. + */ + +# if defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_EXTERN extern __declspec(dllimport) +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_EXTERN extern +# endif + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# ifdef _WIN32 +# ifdef _WIN64 +# define ossl_ssize_t __int64 +# define OSSL_SSIZE_MAX _I64_MAX +# else +# define ossl_ssize_t int +# define OSSL_SSIZE_MAX INT_MAX +# endif +# endif + +# if defined(OPENSSL_SYS_UEFI) && !defined(ossl_ssize_t) +# define ossl_ssize_t INTN +# define OSSL_SSIZE_MAX MAX_INTN +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# if defined(SSIZE_MAX) +# define OSSL_SSIZE_MAX SSIZE_MAX +# elif defined(_POSIX_SSIZE_MAX) +# define OSSL_SSIZE_MAX _POSIX_SSIZE_MAX +# else +# define OSSL_SSIZE_MAX ((ssize_t)(SIZE_MAX>>1)) +# endif +# endif + +# ifdef DEBUG_UNUSED +# define __owur __attribute__((__warn_unused_result__)) +# else +# define __owur +# endif + +/* Standard integer types */ +# if defined(OPENSSL_SYS_UEFI) +typedef INT8 int8_t; +typedef UINT8 uint8_t; +typedef INT16 int16_t; +typedef UINT16 uint16_t; +typedef INT32 int32_t; +typedef UINT32 uint32_t; +typedef INT64 int64_t; +typedef UINT64 uint64_t; +# elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + defined(__osf__) || defined(__sgi) || defined(__hpux) || \ + defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__) +# include +# elif defined(_MSC_VER) && _MSC_VER<=1500 +/* + * minimally required typdefs for systems not supporting inttypes.h or + * stdint.h: currently just older VC++ + */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +# else +# include +# endif + +/* ossl_inline: portable inline definition usable in public headers */ +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* just use inline */ +# define ossl_inline inline +# elif defined(__GNUC__) && __GNUC__>=2 +# define ossl_inline __inline__ +# elif defined(_MSC_VER) + /* + * Visual Studio: inline is available in C++ only, however + * __inline is available for C, see + * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + */ +# define ossl_inline __inline +# else +# define ossl_inline +# endif +# else +# define ossl_inline inline +# endif + +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define ossl_noreturn _Noreturn +# elif defined(__GNUC__) && __GNUC__ >= 2 +# define ossl_noreturn __attribute__((noreturn)) +# else +# define ossl_noreturn +# endif + +/* ossl_unused: portable unused attribute for use in public headers */ +# if defined(__GNUC__) +# define ossl_unused __attribute__((unused)) +# else +# define ossl_unused +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ebcdic.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ebcdic.h new file mode 100644 index 00000000..aa012855 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ebcdic.h @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ec.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ec.h new file mode 100644 index 00000000..5af9ebdc --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ec.h @@ -0,0 +1,1479 @@ +/* + * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include + +# ifndef OPENSSL_NO_EC +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_point_st EC_POINT; +typedef struct ecpk_parameters_st ECPKPARAMETERS; +typedef struct ec_parameters_st ECPARAMETERS; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and its order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used montgomery data (possibly NULL). +*/ +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the order of an EC_GROUP + * \param group EC_GROUP object + * \return the group order + */ +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +/** Gets the number of bits of the order of an EC_GROUP + * \param group EC_GROUP object + * \return number of bits of group order. + */ +int EC_GROUP_order_bits(const EC_GROUP *group); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Gets the cofactor of an EC_GROUP + * \param group EC_GROUP object + * \return the group cofactor + */ +const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameters of a ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameters of the ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx); + +/** Sets the parameters of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if the groups are equal, 1 if not, or -1 on error + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif + +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/** Creates a new EC_GROUP object from an ECPARAMETERS object + * \param params pointer to the ECPARAMETERS object + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params); + +/** Creates an ECPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPARAMETERS object or NULL + * \return pointer to the new ECPARAMETERS object or NULL + * if an error occurred. + */ +ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, + ECPARAMETERS *params); + +/** Creates a new EC_GROUP object from an ECPKPARAMETERS object + * \param params pointer to an existing ECPKPARAMETERS object, or NULL + * \return newly created EC_GROUP object with specified curve, or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params); + +/** Creates an ECPKPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPKPARAMETERS object or NULL + * \return pointer to the new ECPKPARAMETERS object or NULL + * if an error occurred. + */ +ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, + ECPKPARAMETERS *params); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r is not zero, + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of an EC_POINT. + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, + BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Encodes an EC_POINT object to an allocated octet string + * \param group underlying EC_GROUP object + * \param point EC_POINT object + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if the point is on the curve, 0 if not, or -1 on error + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 if the points are not equal, 0 if they are, or -1 on error + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number further summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +DECLARE_ASN1_ITEM(ECPKPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPKPARAMETERS) +DECLARE_ASN1_ITEM(ECPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_EXPLICIT_CURVE 0x000 +# define OPENSSL_EC_NAMED_CURVE 0x001 + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# ifndef OPENSSL_NO_STDIO +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 +# define EC_FLAG_COFACTOR_ECDH 0x1000 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the ENGINE object of a EC_KEY object + * \param eckey EC_KEY object + * \return the ENGINE object (possibly NULL). + */ +ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); + +#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef) +int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg); +void *EC_KEY_get_ex_data(const EC_KEY *key, int idx); + +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Indicates if an EC_KEY can be used for signing. + * \param eckey the EC_KEY object + * \return 1 if can can sign and 0 otherwise. + */ +int EC_KEY_can_sign(const EC_KEY *eckey); + +/** Sets a public key from affine coordinates performing + * necessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/** Encodes an EC_KEY public key to an allocated octet string + * \param key key to encode + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/** Decodes a EC_KEY public key from a octet string + * \param key key to decode + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, + BN_CTX *ctx); + +/** Decodes an EC_KEY private key from an octet string + * \param key key to decode + * \param buf memory buffer with the encoded private key + * \param len length of the encoded key + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2priv(EC_KEY *key, const unsigned char *buf, size_t len); + +/** Encodes a EC_KEY private key to an octet string + * \param key key to encode + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len); + +/** Encodes an EC_KEY private key to an allocated octet string + * \param eckey key to encode + * \param pbuf returns pointer to allocated buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec parameters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out); + +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# ifndef OPENSSL_NO_STDIO +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +const EC_KEY_METHOD *EC_KEY_OpenSSL(void); +const EC_KEY_METHOD *EC_KEY_get_default_method(void); +void EC_KEY_set_default_method(const EC_KEY_METHOD *meth); +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key); +int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); +EC_KEY *EC_KEY_new_method(ENGINE *engine); + +/** The old name for ecdh_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + const EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +typedef struct ECDSA_SIG_st ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or a negative value + * on error + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Accessor for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param pr pointer to BIGNUM pointer for r (may be NULL) + * \param ps pointer to BIGNUM pointer for s (may be NULL) + */ +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); + +/** Accessor for r field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); + +/** Accessor for s field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); + +/** Setter for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param r pointer to BIGNUM for r (may be NULL) + * \param s pointer to BIGNUM for s (may be NULL) + */ +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/********************************************************************/ +/* EC_KEY_METHOD constructors, destructors, writers and accessors */ +/********************************************************************/ + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth); +void EC_KEY_METHOD_free(EC_KEY_METHOD *meth); +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, + int (*keygen)(EC_KEY *key)); + +void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, + int (**pinit)(EC_KEY *key), + void (**pfinish)(EC_KEY *key), + int (**pcopy)(EC_KEY *dest, const EC_KEY *src), + int (**pset_group)(EC_KEY *key, + const EC_GROUP *grp), + int (**pset_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (**pset_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)); + +void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, + int (**pck)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, + int (**psign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \ + (void *)(plen)) + +# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p)) + +/* SM2 will skip the operation check so no need to pass operation here */ +# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id(ctx, id) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) +/* KDF types */ +# define EVP_PKEY_ECDH_KDF_NONE 1 +# define EVP_PKEY_ECDH_KDF_X9_63 2 +/** The old name for EVP_PKEY_ECDH_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +# define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63 + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ecdh.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ecdh.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ecdh.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ecdsa.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ecdsa.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ecdsa.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ecerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ecerr.h new file mode 100644 index 00000000..f7b91834 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ecerr.h @@ -0,0 +1,275 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ECERR_H +# define HEADER_ECERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_EC + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EC_strings(void); + +/* + * EC function codes. + */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECDH_CMS_DECRYPT 238 +# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 +# define EC_F_ECDH_COMPUTE_KEY 246 +# define EC_F_ECDH_SIMPLE_COMPUTE_KEY 257 +# define EC_F_ECDSA_DO_SIGN_EX 251 +# define EC_F_ECDSA_DO_VERIFY 252 +# define EC_F_ECDSA_SIGN_EX 254 +# define EC_F_ECDSA_SIGN_SETUP 248 +# define EC_F_ECDSA_SIG_NEW 265 +# define EC_F_ECDSA_VERIFY 253 +# define EC_F_ECD_ITEM_VERIFY 270 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NISTZ256_GET_AFFINE 240 +# define EC_F_ECP_NISTZ256_INV_MOD_ORD 275 +# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +# define EC_F_ECP_NISTZ256_POINTS_MUL 241 +# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +# define EC_F_ECX_KEY_OP 266 +# define EC_F_ECX_PRIV_ENCODE 267 +# define EC_F_ECX_PUB_ENCODE 268 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_FIELD_INV 296 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_LADDER_POST 285 +# define EC_F_EC_GF2M_SIMPLE_LADDER_PRE 288 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINTS_MUL 289 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_INV 297 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES 287 +# define EC_F_EC_GFP_SIMPLE_FIELD_INV 298 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET_CURVE 291 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ECPARAMETERS 261 +# define EC_F_EC_GROUP_GET_ECPKPARAMETERS 262 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS 263 +# define EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS 264 +# define EC_F_EC_GROUP_SET_CURVE 292 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_GROUP_SET_SEED 286 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_NEW_METHOD 245 +# define EC_F_EC_KEY_OCT2PRIV 255 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_PRIV2BUF 279 +# define EC_F_EC_KEY_PRIV2OCT 256 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_KEY_SIMPLE_CHECK_KEY 258 +# define EC_F_EC_KEY_SIMPLE_OCT2PRIV 259 +# define EC_F_EC_KEY_SIMPLE_PRIV2OCT 260 +# define EC_F_EC_PKEY_CHECK 273 +# define EC_F_EC_PKEY_PARAM_CHECK 274 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINTS_MUL 290 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_BN2POINT 280 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES 293 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2BUF 281 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES 294 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES 295 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_SCALAR_MUL_LADDER 284 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_OSSL_ECDH_COMPUTE_KEY 247 +# define EC_F_OSSL_ECDSA_SIGN_SIG 249 +# define EC_F_OSSL_ECDSA_VERIFY_SIG 250 +# define EC_F_PKEY_ECD_CTRL 271 +# define EC_F_PKEY_ECD_DIGESTSIGN 272 +# define EC_F_PKEY_ECD_DIGESTSIGN25519 276 +# define EC_F_PKEY_ECD_DIGESTSIGN448 277 +# define EC_F_PKEY_ECX_DERIVE 269 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_INIT 282 +# define EC_F_PKEY_EC_KDF_DERIVE 283 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 +# define EC_F_VALIDATE_ECX_DERIVE 278 + +/* + * EC reason codes. + */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_BAD_SIGNATURE 156 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_CANNOT_INVERT 165 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 +# define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST 151 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_KEY 116 +# define EC_R_INVALID_OUTPUT_LENGTH 161 +# define EC_R_INVALID_PEER_KEY 133 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KDF_PARAMETER_ERROR 148 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_LADDER_POST_FAILURE 136 +# define EC_R_LADDER_PRE_FAILURE 153 +# define EC_R_LADDER_STEP_FAILURE 162 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NEED_NEW_SETUP_VALUES 157 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_NO_PRIVATE_VALUE 154 +# define EC_R_OPERATION_NOT_SUPPORTED 152 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PEER_KEY_ERROR 149 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_ARITHMETIC_FAILURE 155 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_COORDINATES_BLIND_FAILURE 163 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_RANDOM_NUMBER_GENERATION_FAILED 158 +# define EC_R_SHARED_INFO_ERROR 150 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_COFACTOR 164 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/engine.h b/Hin2n/src/main/jniLibs/x86/include/openssl/engine.h new file mode 100644 index 00000000..0780f0fb --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/engine.h @@ -0,0 +1,751 @@ +/* + * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include + +# ifndef OPENSSL_NO_ENGINE +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# include +# include +# include +# include +# include +# endif +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +# define ENGINE_METHOD_EC (unsigned int)0x0800 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ENGINE_load_openssl() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_OPENSSL, NULL) +# define ENGINE_load_dynamic() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_DYNAMIC, NULL) +# ifndef OPENSSL_NO_STATIC_ENGINE +# define ENGINE_load_padlock() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_PADLOCK, NULL) +# define ENGINE_load_capi() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CAPI, NULL) +# define ENGINE_load_afalg() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_AFALG, NULL) +# endif +# define ENGINE_load_cryptodev() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL) +# define ENGINE_load_rdrand() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL) +#endif +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_EC(ENGINE *e); +void ENGINE_unregister_EC(ENGINE *e); +void ENGINE_register_all_EC(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parameterised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +#define ENGINE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, l, p, newf, dupf, freef) +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function previously cleaned up anything that needs it. Auto-deinit will + * now take care of it so it is no longer required to call this function. + */ +# define ENGINE_cleanup() while(0) continue +#endif + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_EC(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_EC(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00030000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00030000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_fn) (size_t, const char *, int); +typedef void *(*dyn_MEM_realloc_fn) (void *, size_t, const char *, int); +typedef void (*dyn_MEM_free_fn) (void *, const char *, int); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_fn malloc_fn; + dyn_MEM_realloc_fn realloc_fn; + dyn_MEM_free_fn free_fn; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependent code) can simplify a bit?? + */ +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + dynamic_MEM_fns mem_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if (v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if (ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \ + fns->mem_fns.realloc_fn, \ + fns->mem_fns.free_fn); \ + skip_cbs: \ + if (!fn(e, id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) +DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void)) +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/engineerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/engineerr.h new file mode 100644 index 00000000..05e84bd2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/engineerr.h @@ -0,0 +1,111 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINEERR_H +# define HEADER_ENGINEERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_ENGINE + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ENGINE_strings(void); + +/* + * ENGINE function codes. + */ +# define ENGINE_F_DIGEST_UPDATE 198 +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_FIRST 195 +# define ENGINE_F_ENGINE_GET_LAST 196 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR 197 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CLEANUP_ITEM 199 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_OSSL_HMAC_INIT 200 + +/* + * ENGINE reason codes. + */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/err.h new file mode 100644 index 00000000..b49f8812 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/err.h @@ -0,0 +1,274 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# include +# endif + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 +# define ERR_FLAG_CLEAR 0x02 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_OSSL_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +/* # define ERR_LIB_JPAKE 49 */ +# define ERR_LIB_CT 50 +# define ERR_LIB_ASYNC 51 +# define ERR_LIB_KDF 52 +# define ERR_LIB_SM2 53 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) + +# define ERR_PACK(l,f,r) ( \ + (((unsigned int)(l) & 0x0FF) << 24L) | \ + (((unsigned int)(f) & 0xFFF) << 12L) | \ + (((unsigned int)(r) & 0xFFF) ) ) +# define ERR_GET_LIB(l) (int)(((l) >> 24L) & 0x0FFL) +# define ERR_GET_FUNC(l) (int)(((l) >> 12L) & 0xFFFL) +# define ERR_GET_REASON(l) (int)( (l) & 0xFFFL) +# define ERR_FATAL_ERROR(l) (int)( (l) & ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 +# define SYS_F_GETADDRINFO 12 +# define SYS_F_GETNAMEINFO 13 +# define SYS_F_SETSOCKOPT 14 +# define SYS_F_GETSOCKOPT 15 +# define SYS_F_GETSOCKNAME 16 +# define SYS_F_GETHOSTBYNAME 17 +# define SYS_F_FFLUSH 18 +# define SYS_F_OPEN 19 +# define SYS_F_CLOSE 20 +# define SYS_F_IOCTL 21 +# define SYS_F_STAT 22 +# define SYS_F_FCNTL 23 +# define SYS_F_FSTAT 24 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_OSSL_STORE_LIB ERR_LIB_OSSL_STORE/* 44 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) +# define ERR_R_INIT_FAIL (6|ERR_R_FATAL) +# define ERR_R_PASSED_INVALID_ARGUMENT (7) +# define ERR_R_OPERATION_FAIL (8|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +DEFINE_LHASH_OF(ERR_STRING_DATA); + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +void ERR_print_errors_fp(FILE *fp); +# endif +void ERR_print_errors(BIO *bp); +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +int ERR_load_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_strings_const(const ERR_STRING_DATA *str); +int ERR_unload_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_ERR_strings(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ERR_load_crypto_strings() \ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# define ERR_free_strings() while(0) continue +#endif + +DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *)) +DEPRECATEDIN_1_0_0(void ERR_remove_state(unsigned long pid)) +ERR_STATE *ERR_get_state(void); + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); +int ERR_clear_last_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/evp.h b/Hin2n/src/main/jniLibs/x86/include/openssl/evp.h new file mode 100644 index 00000000..a411f3f2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/evp.h @@ -0,0 +1,1666 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# include +# include +# include +# include +# include + +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_RSA_PSS NID_rsassaPss +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_DHX NID_dhpublicnumber +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_SM2 NID_sm2 +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac +# define EVP_PKEY_SCRYPT NID_id_scrypt +# define EVP_PKEY_TLS1_PRF NID_tls1_prf +# define EVP_PKEY_HKDF NID_hkdf +# define EVP_PKEY_POLY1305 NID_poly1305 +# define EVP_PKEY_SIPHASH NID_siphash +# define EVP_PKEY_X25519 NID_X25519 +# define EVP_PKEY_ED25519 NID_ED25519 +# define EVP_PKEY_X448 NID_X448 +# define EVP_PKEY_ED448 NID_ED448 + +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type); +EVP_MD *EVP_MD_meth_dup(const EVP_MD *md); +void EVP_MD_meth_free(EVP_MD *md); + +int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize); +int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize); +int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize); +int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags); +int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx, + const void *data, + size_t count)); +int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx, + unsigned char *md)); +int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to, + const EVP_MD_CTX *from)); +int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2)); + +int EVP_MD_meth_get_input_blocksize(const EVP_MD *md); +int EVP_MD_meth_get_result_size(const EVP_MD *md); +int EVP_MD_meth_get_app_datasize(const EVP_MD *md); +unsigned long EVP_MD_meth_get_flags(const EVP_MD *md); +int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx, + const void *data, + size_t count); +int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx, + unsigned char *md); +int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to, + const EVP_MD_CTX *from); +int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* digest is extensible-output function, XOF */ +# define EVP_MD_FLAG_XOF 0x0002 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 +# define EVP_MD_CTRL_XOF_LEN 0x3 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# endif /* !EVP_MD */ + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_reset */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ +/* + * Some functions such as EVP_DigestSign only finalise copies of internal + * contexts so additional data can be included after the finalisation call. + * This is inefficient if this functionality is not required: it is disabled + * if the following flag is set. + */ +# define EVP_MD_CTX_FLAG_FINALISE 0x0200 +/* NOTE: 0x0400 is reserved for internal usage */ + +EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); +EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); +void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); + +int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); +int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); +int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); +int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc)); +int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher) (EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl)); +int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup) (EVP_CIPHER_CTX *)); +int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl) (EVP_CIPHER_CTX *, int type, + int arg, void *ptr)); + +int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc); +int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl); +int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); +int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + int type, int arg, + void *ptr); + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_WRAP_MODE 0x10002 +# define EVP_CIPH_OCB_MODE 0x10003 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Don't use standard iv length function */ +# define EVP_CIPH_CUSTOM_IV_LENGTH 0x800 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 +/* Cipher can handle pipeline operations */ +# define EVP_CIPH_FLAG_PIPELINE 0X800000 + +/* + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. + */ + +# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_AEAD_SET_IVLEN 0x9 +# define EVP_CTRL_AEAD_GET_TAG 0x10 +# define EVP_CTRL_AEAD_SET_TAG 0x11 +# define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_CCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 +# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a +# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b +# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c + +# define EVP_CTRL_SSL3_MASTER_SECRET 0x1d + +/* EVP_CTRL_SET_SBOX takes the char * specifying S-boxes */ +# define EVP_CTRL_SET_SBOX 0x1e +/* + * EVP_CTRL_SBOX_USED takes a 'size_t' and 'char *', pointing at a + * pre-allocated buffer with specified size + */ +# define EVP_CTRL_SBOX_USED 0x1f +/* EVP_CTRL_KEY_MESH takes 'size_t' number of bytes to mesh the key after, + * 0 switches meshing off + */ +# define EVP_CTRL_KEY_MESH 0x20 +/* EVP_CTRL_BLOCK_PADDING_MODE takes the padding mode */ +# define EVP_CTRL_BLOCK_PADDING_MODE 0x21 + +/* Set the output buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS 0x22 +/* Set the input buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_BUFS 0x23 +/* Set the input buffer lengths to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 + +# define EVP_CTRL_GET_IVLEN 0x25 + +/* Padding modes */ +#define EVP_PADDING_PKCS7 1 +#define EVP_PADDING_ISO7816_4 2 +#define EVP_PADDING_ANSI923 3 +#define EVP_PADDING_ISO10126 4 +#define EVP_PADDING_ZERO 5 + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +typedef struct { + unsigned char *out; + const unsigned char *inp; + size_t len; + unsigned int interleave; +} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +/* CCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_CCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 +/* Total length of CCM IV length for TLS */ +# define EVP_CCM_TLS_IV_LEN 12 +/* Length of tag for TLS */ +# define EVP_CCM_TLS_TAG_LEN 16 +/* Length of CCM8 tag for TLS */ +# define EVP_CCM8_TLS_TAG_LEN 8 + +/* Length of tag for TLS */ +# define EVP_CHACHAPOLY_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif +# ifndef OPENSSL_NO_SIPHASH +# define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),EVP_PKEY_SIPHASH,\ + (char *)(shkey)) +# endif + +# ifndef OPENSSL_NO_POLY1305 +# define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),EVP_PKEY_POLY1305,\ + (char *)(polykey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx, + const void *data, size_t count); +void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx, + int (*update) (EVP_MD_CTX *ctx, + const void *data, size_t count)); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) +EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); +void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); +void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx); +void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_flags(c) EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(c)) +# endif +# define EVP_CIPHER_CTX_mode(c) EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(c)) + +# define EVP_ENCODE_LENGTH(l) ((((l)+2)/3*4)+((l)/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) (((l)+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)(md)) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)(mdp)) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0, \ + (char *)(c_pp)) + +/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, + const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +EVP_MD_CTX *EVP_MD_CTX_new(void); +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +# define EVP_MD_CTX_create() EVP_MD_CTX_new() +# define EVP_MD_CTX_init(ctx) EVP_MD_CTX_reset((ctx)) +# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx)) +__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +__owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); +__owur int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, + size_t cnt); +__owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, + const EVP_MD *type, ENGINE *impl); + +__owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +__owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +__owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, + size_t len); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +__owur int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, + const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); +/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); + +__owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv, int enc); +__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +__owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, + size_t tbslen); + +__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +__owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + +/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen); + +__owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen); + +# ifndef OPENSSL_NO_RSA +__owur int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, + const unsigned char *iv, EVP_PKEY *priv); +__owur int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +__owur int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +__owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +# endif + +EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void); +void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx); +int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx); +int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx); +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_init(c) EVP_CIPHER_CTX_reset(c) +# define EVP_CIPHER_CTX_cleanup(c) EVP_CIPHER_CTX_reset(c) +# endif +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +const BIO_METHOD *BIO_f_md(void); +const BIO_METHOD *BIO_f_base64(void); +const BIO_METHOD *BIO_f_cipher(void); +const BIO_METHOD *BIO_f_reliable(void); +__owur int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +const EVP_MD *EVP_md5_sha1(void); +# endif +# ifndef OPENSSL_NO_BLAKE2 +const EVP_MD *EVP_blake2b512(void); +const EVP_MD *EVP_blake2s256(void); +# endif +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +const EVP_MD *EVP_sha512_224(void); +const EVP_MD *EVP_sha512_256(void); +const EVP_MD *EVP_sha3_224(void); +const EVP_MD *EVP_sha3_256(void); +const EVP_MD *EVP_sha3_384(void); +const EVP_MD *EVP_sha3_512(void); +const EVP_MD *EVP_shake128(void); +const EVP_MD *EVP_shake256(void); +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RMD160 +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +# ifndef OPENSSL_NO_SM3 +const EVP_MD *EVP_sm3(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +const EVP_CIPHER *EVP_des_ede3_wrap(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_128_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_128_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_192_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_192_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +const EVP_CIPHER *EVP_aes_256_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_256_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); +# ifndef OPENSSL_NO_ARIA +const EVP_CIPHER *EVP_aria_128_ecb(void); +const EVP_CIPHER *EVP_aria_128_cbc(void); +const EVP_CIPHER *EVP_aria_128_cfb1(void); +const EVP_CIPHER *EVP_aria_128_cfb8(void); +const EVP_CIPHER *EVP_aria_128_cfb128(void); +# define EVP_aria_128_cfb EVP_aria_128_cfb128 +const EVP_CIPHER *EVP_aria_128_ctr(void); +const EVP_CIPHER *EVP_aria_128_ofb(void); +const EVP_CIPHER *EVP_aria_128_gcm(void); +const EVP_CIPHER *EVP_aria_128_ccm(void); +const EVP_CIPHER *EVP_aria_192_ecb(void); +const EVP_CIPHER *EVP_aria_192_cbc(void); +const EVP_CIPHER *EVP_aria_192_cfb1(void); +const EVP_CIPHER *EVP_aria_192_cfb8(void); +const EVP_CIPHER *EVP_aria_192_cfb128(void); +# define EVP_aria_192_cfb EVP_aria_192_cfb128 +const EVP_CIPHER *EVP_aria_192_ctr(void); +const EVP_CIPHER *EVP_aria_192_ofb(void); +const EVP_CIPHER *EVP_aria_192_gcm(void); +const EVP_CIPHER *EVP_aria_192_ccm(void); +const EVP_CIPHER *EVP_aria_256_ecb(void); +const EVP_CIPHER *EVP_aria_256_cbc(void); +const EVP_CIPHER *EVP_aria_256_cfb1(void); +const EVP_CIPHER *EVP_aria_256_cfb8(void); +const EVP_CIPHER *EVP_aria_256_cfb128(void); +# define EVP_aria_256_cfb EVP_aria_256_cfb128 +const EVP_CIPHER *EVP_aria_256_ctr(void); +const EVP_CIPHER *EVP_aria_256_ofb(void); +const EVP_CIPHER *EVP_aria_256_gcm(void); +const EVP_CIPHER *EVP_aria_256_ccm(void); +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_128_ctr(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ctr(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ctr(void); +# endif +# ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +# ifndef OPENSSL_NO_POLY1305 +const EVP_CIPHER *EVP_chacha20_poly1305(void); +# endif +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +# ifndef OPENSSL_NO_SM4 +const EVP_CIPHER *EVP_sm4_ecb(void); +const EVP_CIPHER *EVP_sm4_cbc(void); +const EVP_CIPHER *EVP_sm4_cfb128(void); +# define EVP_sm4_cfb EVP_sm4_cfb128 +const EVP_CIPHER *EVP_sm4_ofb(void); +const EVP_CIPHER *EVP_sm4_ctr(void); +# endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_add_all_algorithms_conf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS \ + | OPENSSL_INIT_LOAD_CONFIG, NULL) +# define OPENSSL_add_all_algorithms_noconf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf() +# endif + +# define OpenSSL_add_all_ciphers() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL) +# define OpenSSL_add_all_digests() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# define EVP_cleanup() while(0) continue +# endif + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(const EVP_PKEY *pkey); +int EVP_PKEY_security_bits(const EVP_PKEY *pkey); +int EVP_PKEY_size(const EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); +# ifndef OPENSSL_NO_ENGINE +int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e); +ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); +# endif +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(const EVP_PKEY *pkey); +const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); +# ifndef OPENSSL_NO_POLY1305 +const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); +# endif +# ifndef OPENSSL_NO_SIPHASH +const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len); +# endif + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +int EVP_PKEY_up_ref(EVP_PKEY *pkey); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const unsigned char *pt, size_t ptlen); +size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_SCRYPT +int EVP_PBE_scrypt(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); + +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de); +#endif + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 +/* Is a PKCS#5 v2.0 KDF */ +# define EVP_PBE_TYPE_KDF 0x2 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); +int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 +# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + const PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)); + +void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth, + int (*siginf_set) (X509_SIG_INFO *siginf, + const X509_ALGOR *alg, + const ASN1_STRING *sig)); + +void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_pub_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_param_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_priv_key) (EVP_PKEY *pk, + const unsigned char + *priv, + size_t len)); +void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_pub_key) (EVP_PKEY *pk, + const unsigned char *pub, + size_t len)); +void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_priv_key) (const EVP_PKEY *pk, + unsigned char *priv, + size_t *len)); +void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_pub_key) (const EVP_PKEY *pk, + unsigned char *pub, + size_t *len)); + +void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_security_bits) (const EVP_PKEY + *pk)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key)) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_CTRL_GET_MD 13 + +# define EVP_PKEY_CTRL_SET_DIGEST_SIZE 14 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth); +size_t EVP_PKEY_meth_get_count(void); +const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); +int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, uint64_t value); + +int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str); +int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex); + +int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, + const unsigned char *priv, + size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, + const unsigned char *pub, + size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len); + +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth, + int (*digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth, + int (*digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth, + int (*digest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, + int (**digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth, + int (**digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, + int (**pdigest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); +void EVP_add_alg_module(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/evperr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/evperr.h new file mode 100644 index 00000000..d2b26ea5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/evperr.h @@ -0,0 +1,205 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EVPERR_H +# define HEADER_EVPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EVP_strings(void); + +/* + * EVP function codes. + */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_INIT_KEY 207 +# define EVP_F_AES_GCM_CTRL 196 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_OCB_CIPHER 169 +# define EVP_F_AES_T4_INIT_KEY 178 +# define EVP_F_AES_T4_XTS_INIT_KEY 208 +# define EVP_F_AES_WRAP_CIPHER 170 +# define EVP_F_AES_XTS_INIT_KEY 209 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_ARIA_CCM_INIT_KEY 175 +# define EVP_F_ARIA_GCM_CTRL 197 +# define EVP_F_ARIA_GCM_INIT_KEY 176 +# define EVP_F_ARIA_INIT_KEY 185 +# define EVP_F_B64_NEW 198 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CHACHA20_POLY1305_CTRL 182 +# define EVP_F_CMLL_T4_INIT_KEY 179 +# define EVP_F_DES_EDE3_WRAP_CIPHER 171 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_ENC_NEW 199 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_ASN1_TO_PARAM 204 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_CIPHER_PARAM_TO_ASN1 205 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DECRYPTUPDATE 166 +# define EVP_F_EVP_DIGESTFINALXOF 174 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_ENCRYPTUPDATE 167 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PBE_SCRYPT 181 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKEY2PKCS8 113 +# define EVP_F_EVP_PKEY_ASN1_ADD0 188 +# define EVP_F_EVP_PKEY_CHECK 186 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_CTX_MD 168 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET0_DH 119 +# define EVP_F_EVP_PKEY_GET0_DSA 120 +# define EVP_F_EVP_PKEY_GET0_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET0_HMAC 183 +# define EVP_F_EVP_PKEY_GET0_POLY1305 184 +# define EVP_F_EVP_PKEY_GET0_RSA 121 +# define EVP_F_EVP_PKEY_GET0_SIPHASH 172 +# define EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY 202 +# define EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY 203 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_METH_ADD0 194 +# define EVP_F_EVP_PKEY_METH_NEW 195 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_NEW_CMAC_KEY 193 +# define EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY 191 +# define EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY 192 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_PARAM_CHECK 189 +# define EVP_F_EVP_PKEY_PUBLIC_CHECK 190 +# define EVP_F_EVP_PKEY_SET1_ENGINE 187 +# define EVP_F_EVP_PKEY_SET_ALIAS_TYPE 206 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_OK_NEW 200 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 +# define EVP_F_R_32_12_16_INIT_KEY 242 +# define EVP_F_S390X_AES_GCM_CTRL 201 +# define EVP_F_UPDATE 173 + +/* + * EVP reason codes. + */ +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ARIA_KEY_SETUP_FAILED 176 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 195 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_COPY_ERROR 173 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EXPECTING_AN_HMAC_KEY 174 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_EXPECTING_A_POLY1305_KEY 164 +# define EVP_R_EXPECTING_A_SIPHASH_KEY 175 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_GET_RAW_KEY_FAILED 182 +# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_IV_LENGTH 194 +# define EVP_R_INVALID_KEY 163 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_KEY_SETUP_FAILED 180 +# define EVP_R_MEMORY_LIMIT_EXCEEDED 172 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NOT_XOF_OR_INVALID_LENGTH 178 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_ONLY_ONESHOT_SUPPORTED 177 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PARTIALLY_OVERLAPPING 162 +# define EVP_R_PBKDF2_ERROR 181 +# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_XTS_DUPLICATED_KEYS 183 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/hmac.h b/Hin2n/src/main/jniLibs/x86/include/openssl/hmac.h new file mode 100644 index 00000000..458efc1d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/hmac.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include + +# include + +# if OPENSSL_API_COMPAT < 0x10200000L +# define HMAC_MAX_MD_CBLOCK 128 /* Deprecated */ +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +size_t HMAC_size(const HMAC_CTX *e); +HMAC_CTX *HMAC_CTX_new(void); +int HMAC_CTX_reset(HMAC_CTX *ctx); +void HMAC_CTX_free(HMAC_CTX *ctx); + +DEPRECATEDIN_1_1_0(__owur int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md)) + +/*__owur*/ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +/*__owur*/ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, + size_t len); +/*__owur*/ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, + unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +__owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); +const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/idea.h b/Hin2n/src/main/jniLibs/x86/include/openssl/idea.h new file mode 100644 index 00000000..4334f3ea --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/idea.h @@ -0,0 +1,64 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include + +# ifndef OPENSSL_NO_IDEA +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int IDEA_INT; + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *IDEA_options(void); +void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void IDEA_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define idea_options IDEA_options +# define idea_ecb_encrypt IDEA_ecb_encrypt +# define idea_set_encrypt_key IDEA_set_encrypt_key +# define idea_set_decrypt_key IDEA_set_decrypt_key +# define idea_cbc_encrypt IDEA_cbc_encrypt +# define idea_cfb64_encrypt IDEA_cfb64_encrypt +# define idea_ofb64_encrypt IDEA_ofb64_encrypt +# define idea_encrypt IDEA_encrypt +# endif + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/kdf.h b/Hin2n/src/main/jniLibs/x86/include/openssl/kdf.h new file mode 100644 index 00000000..5abd4c37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/kdf.h @@ -0,0 +1,97 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDF_H +# define HEADER_KDF_H + +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL) +# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_PASS (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_SCRYPT_SALT (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_SCRYPT_N (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SCRYPT_R (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_SCRYPT_P (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES (EVP_PKEY_ALG_CTRL + 13) + +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)(sec)) + +# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)(seed)) + +# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) + +# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) + +# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL) + +# define EVP_PKEY_CTX_set1_pbe_pass(pctx, pass, passlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_PASS, passlen, (void *)(pass)) + +# define EVP_PKEY_CTX_set1_scrypt_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set_scrypt_N(pctx, n) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_N, n) + +# define EVP_PKEY_CTX_set_scrypt_r(pctx, r) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_R, r) + +# define EVP_PKEY_CTX_set_scrypt_p(pctx, p) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_P, p) + +# define EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, maxmem_bytes) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/kdferr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/kdferr.h new file mode 100644 index 00000000..3f51bd02 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/kdferr.h @@ -0,0 +1,55 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDFERR_H +# define HEADER_KDFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_KDF_strings(void); + +/* + * KDF function codes. + */ +# define KDF_F_PKEY_HKDF_CTRL_STR 103 +# define KDF_F_PKEY_HKDF_DERIVE 102 +# define KDF_F_PKEY_HKDF_INIT 108 +# define KDF_F_PKEY_SCRYPT_CTRL_STR 104 +# define KDF_F_PKEY_SCRYPT_CTRL_UINT64 105 +# define KDF_F_PKEY_SCRYPT_DERIVE 109 +# define KDF_F_PKEY_SCRYPT_INIT 106 +# define KDF_F_PKEY_SCRYPT_SET_MEMBUF 107 +# define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 +# define KDF_F_PKEY_TLS1_PRF_DERIVE 101 +# define KDF_F_PKEY_TLS1_PRF_INIT 110 +# define KDF_F_TLS1_PRF_ALG 111 + +/* + * KDF reason codes. + */ +# define KDF_R_INVALID_DIGEST 100 +# define KDF_R_MISSING_ITERATION_COUNT 109 +# define KDF_R_MISSING_KEY 104 +# define KDF_R_MISSING_MESSAGE_DIGEST 105 +# define KDF_R_MISSING_PARAMETER 101 +# define KDF_R_MISSING_PASS 110 +# define KDF_R_MISSING_SALT 111 +# define KDF_R_MISSING_SECRET 107 +# define KDF_R_MISSING_SEED 106 +# define KDF_R_UNKNOWN_PARAMETER_TYPE 103 +# define KDF_R_VALUE_ERROR 108 +# define KDF_R_VALUE_MISSING 102 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/lhash.h b/Hin2n/src/main/jniLibs/x86/include/openssl/lhash.h new file mode 100644 index 00000000..2e42d727 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/lhash.h @@ -0,0 +1,241 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st OPENSSL_LH_NODE; +typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); +typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); +typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); +typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); +typedef struct lhash_st OPENSSL_LHASH; + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + + +# define LH_LOAD_MULT 256 + +int OPENSSL_LH_error(OPENSSL_LHASH *lh); +OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); +void OPENSSL_LH_free(OPENSSL_LHASH *lh); +void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); +void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); +void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); +void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); +void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); +unsigned long OPENSSL_LH_strhash(const char *c); +unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); +unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); +void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); + +# ifndef OPENSSL_NO_STDIO +void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); +# endif +void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _LHASH OPENSSL_LHASH +# define LHASH_NODE OPENSSL_LH_NODE +# define lh_error OPENSSL_LH_error +# define lh_new OPENSSL_LH_new +# define lh_free OPENSSL_LH_free +# define lh_insert OPENSSL_LH_insert +# define lh_delete OPENSSL_LH_delete +# define lh_retrieve OPENSSL_LH_retrieve +# define lh_doall OPENSSL_LH_doall +# define lh_doall_arg OPENSSL_LH_doall_arg +# define lh_strhash OPENSSL_LH_strhash +# define lh_num_items OPENSSL_LH_num_items +# ifndef OPENSSL_NO_STDIO +# define lh_stats OPENSSL_LH_stats +# define lh_node_stats OPENSSL_LH_node_stats +# define lh_node_usage_stats OPENSSL_LH_node_usage_stats +# endif +# define lh_stats_bio OPENSSL_LH_stats_bio +# define lh_node_stats_bio OPENSSL_LH_node_stats_bio +# define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DEFINE_LHASH_OF(type) \ + LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ + static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ + int (*cfn)(const type *, const type *)) \ + { \ + return (LHASH_OF(type) *) \ + OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ + } \ + static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ + { \ + OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ + { \ + return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ + { \ + OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ + } \ + static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ + void (*doall)(type *)) \ + { \ + OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ + } \ + LHASH_OF(type) + +#define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ + int_implement_lhash_doall(type, argtype, const type) + +#define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ + int_implement_lhash_doall(type, argtype, type) + +#define int_implement_lhash_doall(type, argtype, cbargtype) \ + static ossl_unused ossl_inline void \ + lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ + void (*fn)(cbargtype *, argtype *), \ + argtype *arg) \ + { \ + OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ + } \ + LHASH_OF(type) + +DEFINE_LHASH_OF(OPENSSL_STRING); +# ifdef _MSC_VER +/* + * push and pop this warning: + * warning C4090: 'function': different 'const' qualifiers + */ +# pragma warning (push) +# pragma warning (disable: 4090) +# endif + +DEFINE_LHASH_OF(OPENSSL_CSTRING); + +# ifdef _MSC_VER +# pragma warning (pop) +# endif + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_LH_new +# pragma weak OPENSSL_LH_free +# pragma weak OPENSSL_LH_insert +# pragma weak OPENSSL_LH_delete +# pragma weak OPENSSL_LH_retrieve +# pragma weak OPENSSL_LH_error +# pragma weak OPENSSL_LH_num_items +# pragma weak OPENSSL_LH_node_stats_bio +# pragma weak OPENSSL_LH_node_usage_stats_bio +# pragma weak OPENSSL_LH_stats_bio +# pragma weak OPENSSL_LH_get_down_load +# pragma weak OPENSSL_LH_set_down_load +# pragma weak OPENSSL_LH_doall +# pragma weak OPENSSL_LH_doall_arg +# endif /* __SUNPRO_C */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/md2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/md2.h new file mode 100644 index 00000000..7faf8e3d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/md2.h @@ -0,0 +1,44 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD2_H +# define HEADER_MD2_H + +# include + +# ifndef OPENSSL_NO_MD2 +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned char MD2_INT; + +# define MD2_DIGEST_LENGTH 16 +# define MD2_BLOCK 16 + +typedef struct MD2state_st { + unsigned int num; + unsigned char data[MD2_BLOCK]; + MD2_INT cksm[MD2_BLOCK]; + MD2_INT state[MD2_BLOCK]; +} MD2_CTX; + +const char *MD2_options(void); +int MD2_Init(MD2_CTX *c); +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); +int MD2_Final(unsigned char *md, MD2_CTX *c); +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/md4.h b/Hin2n/src/main/jniLibs/x86/include/openssl/md4.h new file mode 100644 index 00000000..940e29db --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/md4.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include + +# ifndef OPENSSL_NO_MD4 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD4_LONG unsigned int + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/md5.h b/Hin2n/src/main/jniLibs/x86/include/openssl/md5.h new file mode 100644 index 00000000..2deb7721 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/md5.h @@ -0,0 +1,50 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include + +# ifndef OPENSSL_NO_MD5 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD5_LONG unsigned int + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/mdc2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/mdc2.h new file mode 100644 index 00000000..aabd2bfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/mdc2.h @@ -0,0 +1,42 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include + +#ifndef OPENSSL_NO_MDC2 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/modes.h b/Hin2n/src/main/jniLibs/x86/include/openssl/modes.h new file mode 100644 index 00000000..d544f98d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/modes.h @@ -0,0 +1,208 @@ +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MODES_H +# define HEADER_MODES_H + +# include + +# ifdef __cplusplus +extern "C" { +# endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); +size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); +size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); + +# ifndef OPENSSL_NO_OCB +typedef struct ocb128_context OCB128_CONTEXT; + +typedef void (*ocb128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); + +OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, + void *keyenc, void *keydec); +int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv, + size_t len, size_t taglen); +int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx); +# endif /* OPENSSL_NO_OCB */ + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/obj_mac.h b/Hin2n/src/main/jniLibs/x86/include/openssl/obj_mac.h new file mode 100644 index 00000000..483fc050 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/obj_mac.h @@ -0,0 +1,5198 @@ +/* + * WARNING: do not edit! + * Generated by crypto/objects/objects.pl + * + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_x509ExtAdmission "x509ExtAdmission" +#define LN_x509ExtAdmission "Professional Information or basis for Admission" +#define NID_x509ExtAdmission 1093 +#define OBJ_x509ExtAdmission OBJ_identified_organization,36L,8L,3L,3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_ieee "ieee" +#define NID_ieee 1170 +#define OBJ_ieee OBJ_identified_organization,111L + +#define SN_ieee_siswg "ieee-siswg" +#define LN_ieee_siswg "IEEE Security in Storage Working Group" +#define NID_ieee_siswg 1171 +#define OBJ_ieee_siswg OBJ_ieee,2L,1619L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_ISO_CN "ISO-CN" +#define LN_ISO_CN "ISO CN Member Body" +#define NID_ISO_CN 1140 +#define OBJ_ISO_CN OBJ_member_body,156L + +#define SN_oscca "oscca" +#define NID_oscca 1141 +#define OBJ_oscca OBJ_ISO_CN,10197L + +#define SN_sm_scheme "sm-scheme" +#define NID_sm_scheme 1142 +#define OBJ_sm_scheme OBJ_oscca,1L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_sha512_224WithRSAEncryption "RSA-SHA512/224" +#define LN_sha512_224WithRSAEncryption "sha512-224WithRSAEncryption" +#define NID_sha512_224WithRSAEncryption 1145 +#define OBJ_sha512_224WithRSAEncryption OBJ_pkcs1,15L + +#define SN_sha512_256WithRSAEncryption "RSA-SHA512/256" +#define LN_sha512_256WithRSAEncryption "sha512-256WithRSAEncryption" +#define NID_sha512_256WithRSAEncryption 1146 +#define OBJ_sha512_256WithRSAEncryption OBJ_pkcs1,16L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_smime_ct_contentCollection "id-smime-ct-contentCollection" +#define NID_id_smime_ct_contentCollection 1058 +#define OBJ_id_smime_ct_contentCollection OBJ_id_smime_ct,19L + +#define SN_id_smime_ct_authEnvelopedData "id-smime-ct-authEnvelopedData" +#define NID_id_smime_ct_authEnvelopedData 1059 +#define OBJ_id_smime_ct_authEnvelopedData OBJ_id_smime_ct,23L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_ct_xml "id-ct-xml" +#define NID_id_ct_xml 1060 +#define OBJ_id_ct_xml OBJ_id_smime_ct,28L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" +#define NID_id_smime_aa_signingCertificateV2 1086 +#define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define SN_sm2 "SM2" +#define LN_sm2 "sm2" +#define NID_sm2 1172 +#define OBJ_sm2 OBJ_sm_scheme,301L + +#define SN_sm3 "SM3" +#define LN_sm3 "sm3" +#define NID_sm3 1143 +#define OBJ_sm3 OBJ_sm_scheme,401L + +#define SN_sm3WithRSAEncryption "RSA-SM3" +#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" +#define NID_sm3WithRSAEncryption 1144 +#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define LN_hmacWithSHA512_224 "hmacWithSHA512-224" +#define NID_hmacWithSHA512_224 1193 +#define OBJ_hmacWithSHA512_224 OBJ_rsadsi,2L,12L + +#define LN_hmacWithSHA512_256 "hmacWithSHA512-256" +#define NID_hmacWithSHA512_256 1194 +#define OBJ_hmacWithSHA512_256 OBJ_rsadsi,2L,13L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcard Login" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft User Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_tlsfeature "tlsfeature" +#define LN_tlsfeature "TLS Feature" +#define NID_tlsfeature 1020 +#define OBJ_tlsfeature OBJ_id_pe,24L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_ipsec_IKE "ipsecIKE" +#define LN_ipsec_IKE "ipsec Internet Key Exchange" +#define NID_ipsec_IKE 1022 +#define OBJ_ipsec_IKE OBJ_id_kp,17L + +#define SN_capwapAC "capwapAC" +#define LN_capwapAC "Ctrl/provision WAP Access" +#define NID_capwapAC 1023 +#define OBJ_capwapAC OBJ_id_kp,18L + +#define SN_capwapWTP "capwapWTP" +#define LN_capwapWTP "Ctrl/Provision WAP Termination" +#define NID_capwapWTP 1024 +#define OBJ_capwapWTP OBJ_id_kp,19L + +#define SN_sshClient "secureShellClient" +#define LN_sshClient "SSH Client" +#define NID_sshClient 1025 +#define OBJ_sshClient OBJ_id_kp,21L + +#define SN_sshServer "secureShellServer" +#define LN_sshServer "SSH Server" +#define NID_sshServer 1026 +#define OBJ_sshServer OBJ_id_kp,22L + +#define SN_sendRouter "sendRouter" +#define LN_sendRouter "Send Router" +#define NID_sendRouter 1027 +#define OBJ_sendRouter OBJ_id_kp,23L + +#define SN_sendProxiedRouter "sendProxiedRouter" +#define LN_sendProxiedRouter "Send Proxied Router" +#define NID_sendProxiedRouter 1028 +#define OBJ_sendProxiedRouter OBJ_id_kp,24L + +#define SN_sendOwner "sendOwner" +#define LN_sendOwner "Send Owner" +#define NID_sendOwner 1029 +#define OBJ_sendOwner OBJ_id_kp,25L + +#define SN_sendProxiedOwner "sendProxiedOwner" +#define LN_sendProxiedOwner "Send Proxied Owner" +#define NID_sendProxiedOwner 1030 +#define OBJ_sendProxiedOwner OBJ_id_kp,26L + +#define SN_cmcCA "cmcCA" +#define LN_cmcCA "CMC Certificate Authority" +#define NID_cmcCA 1131 +#define OBJ_cmcCA OBJ_id_kp,27L + +#define SN_cmcRA "cmcRA" +#define LN_cmcRA "CMC Registration Authority" +#define NID_cmcRA 1132 +#define OBJ_cmcRA OBJ_id_kp,28L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_blake2b512 "BLAKE2b512" +#define LN_blake2b512 "blake2b512" +#define NID_blake2b512 1056 +#define OBJ_blake2b512 1L,3L,6L,1L,4L,1L,1722L,12L,2L,1L,16L + +#define SN_blake2s256 "BLAKE2s256" +#define LN_blake2s256 "blake2s256" +#define NID_blake2s256 1057 +#define OBJ_blake2s256 1L,3L,6L,1L,4L,1L,1722L,12L,2L,2L,8L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define LN_organizationIdentifier "organizationIdentifier" +#define NID_organizationIdentifier 1089 +#define OBJ_organizationIdentifier OBJ_X509,97L + +#define SN_countryCode3c "c3" +#define LN_countryCode3c "countryCode3c" +#define NID_countryCode3c 1090 +#define OBJ_countryCode3c OBJ_X509,98L + +#define SN_countryCode3n "n3" +#define LN_countryCode3n "countryCode3n" +#define NID_countryCode3n 1091 +#define OBJ_countryCode3n OBJ_X509,99L + +#define LN_dnsName "dnsName" +#define NID_dnsName 1092 +#define OBJ_dnsName OBJ_X509,100L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 +#define OBJ_aes_128_xts OBJ_ieee_siswg,0L,1L,1L + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 +#define OBJ_aes_256_xts OBJ_ieee_siswg,0L,1L,2L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_ocb "AES-128-OCB" +#define LN_aes_128_ocb "aes-128-ocb" +#define NID_aes_128_ocb 958 + +#define SN_aes_192_ocb "AES-192-OCB" +#define LN_aes_192_ocb "aes-192-ocb" +#define NID_aes_192_ocb 959 + +#define SN_aes_256_ocb "AES-256-OCB" +#define LN_aes_256_ocb "aes-256-ocb" +#define NID_aes_256_ocb 960 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define SN_sha512_224 "SHA512-224" +#define LN_sha512_224 "sha512-224" +#define NID_sha512_224 1094 +#define OBJ_sha512_224 OBJ_nist_hashalgs,5L + +#define SN_sha512_256 "SHA512-256" +#define LN_sha512_256 "sha512-256" +#define NID_sha512_256 1095 +#define OBJ_sha512_256 OBJ_nist_hashalgs,6L + +#define SN_sha3_224 "SHA3-224" +#define LN_sha3_224 "sha3-224" +#define NID_sha3_224 1096 +#define OBJ_sha3_224 OBJ_nist_hashalgs,7L + +#define SN_sha3_256 "SHA3-256" +#define LN_sha3_256 "sha3-256" +#define NID_sha3_256 1097 +#define OBJ_sha3_256 OBJ_nist_hashalgs,8L + +#define SN_sha3_384 "SHA3-384" +#define LN_sha3_384 "sha3-384" +#define NID_sha3_384 1098 +#define OBJ_sha3_384 OBJ_nist_hashalgs,9L + +#define SN_sha3_512 "SHA3-512" +#define LN_sha3_512 "sha3-512" +#define NID_sha3_512 1099 +#define OBJ_sha3_512 OBJ_nist_hashalgs,10L + +#define SN_shake128 "SHAKE128" +#define LN_shake128 "shake128" +#define NID_shake128 1100 +#define OBJ_shake128 OBJ_nist_hashalgs,11L + +#define SN_shake256 "SHAKE256" +#define LN_shake256 "shake256" +#define NID_shake256 1101 +#define OBJ_shake256 OBJ_nist_hashalgs,12L + +#define SN_hmac_sha3_224 "id-hmacWithSHA3-224" +#define LN_hmac_sha3_224 "hmac-sha3-224" +#define NID_hmac_sha3_224 1102 +#define OBJ_hmac_sha3_224 OBJ_nist_hashalgs,13L + +#define SN_hmac_sha3_256 "id-hmacWithSHA3-256" +#define LN_hmac_sha3_256 "hmac-sha3-256" +#define NID_hmac_sha3_256 1103 +#define OBJ_hmac_sha3_256 OBJ_nist_hashalgs,14L + +#define SN_hmac_sha3_384 "id-hmacWithSHA3-384" +#define LN_hmac_sha3_384 "hmac-sha3-384" +#define NID_hmac_sha3_384 1104 +#define OBJ_hmac_sha3_384 OBJ_nist_hashalgs,15L + +#define SN_hmac_sha3_512 "id-hmacWithSHA3-512" +#define LN_hmac_sha3_512 "hmac-sha3-512" +#define NID_hmac_sha3_512 1105 +#define OBJ_hmac_sha3_512 OBJ_nist_hashalgs,16L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define OBJ_sigAlgs OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA384 "id-dsa-with-sha384" +#define LN_dsa_with_SHA384 "dsa_with_SHA384" +#define NID_dsa_with_SHA384 1106 +#define OBJ_dsa_with_SHA384 OBJ_sigAlgs,3L + +#define SN_dsa_with_SHA512 "id-dsa-with-sha512" +#define LN_dsa_with_SHA512 "dsa_with_SHA512" +#define NID_dsa_with_SHA512 1107 +#define OBJ_dsa_with_SHA512 OBJ_sigAlgs,4L + +#define SN_dsa_with_SHA3_224 "id-dsa-with-sha3-224" +#define LN_dsa_with_SHA3_224 "dsa_with_SHA3-224" +#define NID_dsa_with_SHA3_224 1108 +#define OBJ_dsa_with_SHA3_224 OBJ_sigAlgs,5L + +#define SN_dsa_with_SHA3_256 "id-dsa-with-sha3-256" +#define LN_dsa_with_SHA3_256 "dsa_with_SHA3-256" +#define NID_dsa_with_SHA3_256 1109 +#define OBJ_dsa_with_SHA3_256 OBJ_sigAlgs,6L + +#define SN_dsa_with_SHA3_384 "id-dsa-with-sha3-384" +#define LN_dsa_with_SHA3_384 "dsa_with_SHA3-384" +#define NID_dsa_with_SHA3_384 1110 +#define OBJ_dsa_with_SHA3_384 OBJ_sigAlgs,7L + +#define SN_dsa_with_SHA3_512 "id-dsa-with-sha3-512" +#define LN_dsa_with_SHA3_512 "dsa_with_SHA3-512" +#define NID_dsa_with_SHA3_512 1111 +#define OBJ_dsa_with_SHA3_512 OBJ_sigAlgs,8L + +#define SN_ecdsa_with_SHA3_224 "id-ecdsa-with-sha3-224" +#define LN_ecdsa_with_SHA3_224 "ecdsa_with_SHA3-224" +#define NID_ecdsa_with_SHA3_224 1112 +#define OBJ_ecdsa_with_SHA3_224 OBJ_sigAlgs,9L + +#define SN_ecdsa_with_SHA3_256 "id-ecdsa-with-sha3-256" +#define LN_ecdsa_with_SHA3_256 "ecdsa_with_SHA3-256" +#define NID_ecdsa_with_SHA3_256 1113 +#define OBJ_ecdsa_with_SHA3_256 OBJ_sigAlgs,10L + +#define SN_ecdsa_with_SHA3_384 "id-ecdsa-with-sha3-384" +#define LN_ecdsa_with_SHA3_384 "ecdsa_with_SHA3-384" +#define NID_ecdsa_with_SHA3_384 1114 +#define OBJ_ecdsa_with_SHA3_384 OBJ_sigAlgs,11L + +#define SN_ecdsa_with_SHA3_512 "id-ecdsa-with-sha3-512" +#define LN_ecdsa_with_SHA3_512 "ecdsa_with_SHA3-512" +#define NID_ecdsa_with_SHA3_512 1115 +#define OBJ_ecdsa_with_SHA3_512 OBJ_sigAlgs,12L + +#define SN_RSA_SHA3_224 "id-rsassa-pkcs1-v1_5-with-sha3-224" +#define LN_RSA_SHA3_224 "RSA-SHA3-224" +#define NID_RSA_SHA3_224 1116 +#define OBJ_RSA_SHA3_224 OBJ_sigAlgs,13L + +#define SN_RSA_SHA3_256 "id-rsassa-pkcs1-v1_5-with-sha3-256" +#define LN_RSA_SHA3_256 "RSA-SHA3-256" +#define NID_RSA_SHA3_256 1117 +#define OBJ_RSA_SHA3_256 OBJ_sigAlgs,14L + +#define SN_RSA_SHA3_384 "id-rsassa-pkcs1-v1_5-with-sha3-384" +#define LN_RSA_SHA3_384 "RSA-SHA3-384" +#define NID_RSA_SHA3_384 1118 +#define OBJ_RSA_SHA3_384 OBJ_sigAlgs,15L + +#define SN_RSA_SHA3_512 "id-rsassa-pkcs1-v1_5-with-sha3-512" +#define LN_RSA_SHA3_512 "RSA-SHA3-512" +#define NID_RSA_SHA3_512 1119 +#define OBJ_RSA_SHA3_512 OBJ_sigAlgs,16L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define SN_uniqueIdentifier "uid" +#define LN_uniqueIdentifier "uniqueIdentifier" +#define NID_uniqueIdentifier 102 +#define OBJ_uniqueIdentifier OBJ_pilotAttributeType,44L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_tc26 "id-tc26" +#define NID_id_tc26 974 +#define OBJ_id_tc26 OBJ_member_body,643L,7L,1L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_gost89_cnt_12 "gost89-cnt-12" +#define NID_gost89_cnt_12 975 + +#define SN_gost89_cbc "gost89-cbc" +#define NID_gost89_cbc 1009 + +#define SN_gost89_ecb "gost89-ecb" +#define NID_gost89_ecb 1010 + +#define SN_gost89_ctr "gost89-ctr" +#define NID_gost89_ctr 1011 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_gost_mac_12 "gost-mac-12" +#define NID_gost_mac_12 976 + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_id_tc26_algorithms "id-tc26-algorithms" +#define NID_id_tc26_algorithms 977 +#define OBJ_id_tc26_algorithms OBJ_id_tc26,1L + +#define SN_id_tc26_sign "id-tc26-sign" +#define NID_id_tc26_sign 978 +#define OBJ_id_tc26_sign OBJ_id_tc26_algorithms,1L + +#define SN_id_GostR3410_2012_256 "gost2012_256" +#define LN_id_GostR3410_2012_256 "GOST R 34.10-2012 with 256 bit modulus" +#define NID_id_GostR3410_2012_256 979 +#define OBJ_id_GostR3410_2012_256 OBJ_id_tc26_sign,1L + +#define SN_id_GostR3410_2012_512 "gost2012_512" +#define LN_id_GostR3410_2012_512 "GOST R 34.10-2012 with 512 bit modulus" +#define NID_id_GostR3410_2012_512 980 +#define OBJ_id_GostR3410_2012_512 OBJ_id_tc26_sign,2L + +#define SN_id_tc26_digest "id-tc26-digest" +#define NID_id_tc26_digest 981 +#define OBJ_id_tc26_digest OBJ_id_tc26_algorithms,2L + +#define SN_id_GostR3411_2012_256 "md_gost12_256" +#define LN_id_GostR3411_2012_256 "GOST R 34.11-2012 with 256 bit hash" +#define NID_id_GostR3411_2012_256 982 +#define OBJ_id_GostR3411_2012_256 OBJ_id_tc26_digest,2L + +#define SN_id_GostR3411_2012_512 "md_gost12_512" +#define LN_id_GostR3411_2012_512 "GOST R 34.11-2012 with 512 bit hash" +#define NID_id_GostR3411_2012_512 983 +#define OBJ_id_GostR3411_2012_512 OBJ_id_tc26_digest,3L + +#define SN_id_tc26_signwithdigest "id-tc26-signwithdigest" +#define NID_id_tc26_signwithdigest 984 +#define OBJ_id_tc26_signwithdigest OBJ_id_tc26_algorithms,3L + +#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" +#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_256 985 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_id_tc26_signwithdigest,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" +#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_512 986 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_id_tc26_signwithdigest,3L + +#define SN_id_tc26_mac "id-tc26-mac" +#define NID_id_tc26_mac 987 +#define OBJ_id_tc26_mac OBJ_id_tc26_algorithms,4L + +#define SN_id_tc26_hmac_gost_3411_2012_256 "id-tc26-hmac-gost-3411-2012-256" +#define LN_id_tc26_hmac_gost_3411_2012_256 "HMAC GOST 34.11-2012 256 bit" +#define NID_id_tc26_hmac_gost_3411_2012_256 988 +#define OBJ_id_tc26_hmac_gost_3411_2012_256 OBJ_id_tc26_mac,1L + +#define SN_id_tc26_hmac_gost_3411_2012_512 "id-tc26-hmac-gost-3411-2012-512" +#define LN_id_tc26_hmac_gost_3411_2012_512 "HMAC GOST 34.11-2012 512 bit" +#define NID_id_tc26_hmac_gost_3411_2012_512 989 +#define OBJ_id_tc26_hmac_gost_3411_2012_512 OBJ_id_tc26_mac,2L + +#define SN_id_tc26_cipher "id-tc26-cipher" +#define NID_id_tc26_cipher 990 +#define OBJ_id_tc26_cipher OBJ_id_tc26_algorithms,5L + +#define SN_id_tc26_cipher_gostr3412_2015_magma "id-tc26-cipher-gostr3412-2015-magma" +#define NID_id_tc26_cipher_gostr3412_2015_magma 1173 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma OBJ_id_tc26_cipher,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm "id-tc26-cipher-gostr3412-2015-magma-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1174 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_magma,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1175 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_magma,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik "id-tc26-cipher-gostr3412-2015-kuznyechik" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik 1176 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik OBJ_id_tc26_cipher,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1177 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1178 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,2L + +#define SN_id_tc26_agreement "id-tc26-agreement" +#define NID_id_tc26_agreement 991 +#define OBJ_id_tc26_agreement OBJ_id_tc26_algorithms,6L + +#define SN_id_tc26_agreement_gost_3410_2012_256 "id-tc26-agreement-gost-3410-2012-256" +#define NID_id_tc26_agreement_gost_3410_2012_256 992 +#define OBJ_id_tc26_agreement_gost_3410_2012_256 OBJ_id_tc26_agreement,1L + +#define SN_id_tc26_agreement_gost_3410_2012_512 "id-tc26-agreement-gost-3410-2012-512" +#define NID_id_tc26_agreement_gost_3410_2012_512 993 +#define OBJ_id_tc26_agreement_gost_3410_2012_512 OBJ_id_tc26_agreement,2L + +#define SN_id_tc26_wrap "id-tc26-wrap" +#define NID_id_tc26_wrap 1179 +#define OBJ_id_tc26_wrap OBJ_id_tc26_algorithms,7L + +#define SN_id_tc26_wrap_gostr3412_2015_magma "id-tc26-wrap-gostr3412-2015-magma" +#define NID_id_tc26_wrap_gostr3412_2015_magma 1180 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma OBJ_id_tc26_wrap,1L + +#define SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 "id-tc26-wrap-gostr3412-2015-magma-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 1181 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_magma,1L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik "id-tc26-wrap-gostr3412-2015-kuznyechik" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik 1182 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik OBJ_id_tc26_wrap,2L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1183 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_constants "id-tc26-constants" +#define NID_id_tc26_constants 994 +#define OBJ_id_tc26_constants OBJ_id_tc26,2L + +#define SN_id_tc26_sign_constants "id-tc26-sign-constants" +#define NID_id_tc26_sign_constants 995 +#define OBJ_id_tc26_sign_constants OBJ_id_tc26_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_constants "id-tc26-gost-3410-2012-256-constants" +#define NID_id_tc26_gost_3410_2012_256_constants 1147 +#define OBJ_id_tc26_gost_3410_2012_256_constants OBJ_id_tc26_sign_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetA "id-tc26-gost-3410-2012-256-paramSetA" +#define LN_id_tc26_gost_3410_2012_256_paramSetA "GOST R 34.10-2012 (256 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_256_paramSetA 1148 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetA OBJ_id_tc26_gost_3410_2012_256_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetB "id-tc26-gost-3410-2012-256-paramSetB" +#define LN_id_tc26_gost_3410_2012_256_paramSetB "GOST R 34.10-2012 (256 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_256_paramSetB 1184 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetB OBJ_id_tc26_gost_3410_2012_256_constants,2L + +#define SN_id_tc26_gost_3410_2012_256_paramSetC "id-tc26-gost-3410-2012-256-paramSetC" +#define LN_id_tc26_gost_3410_2012_256_paramSetC "GOST R 34.10-2012 (256 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_256_paramSetC 1185 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetC OBJ_id_tc26_gost_3410_2012_256_constants,3L + +#define SN_id_tc26_gost_3410_2012_256_paramSetD "id-tc26-gost-3410-2012-256-paramSetD" +#define LN_id_tc26_gost_3410_2012_256_paramSetD "GOST R 34.10-2012 (256 bit) ParamSet D" +#define NID_id_tc26_gost_3410_2012_256_paramSetD 1186 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetD OBJ_id_tc26_gost_3410_2012_256_constants,4L + +#define SN_id_tc26_gost_3410_2012_512_constants "id-tc26-gost-3410-2012-512-constants" +#define NID_id_tc26_gost_3410_2012_512_constants 996 +#define OBJ_id_tc26_gost_3410_2012_512_constants OBJ_id_tc26_sign_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetTest "id-tc26-gost-3410-2012-512-paramSetTest" +#define LN_id_tc26_gost_3410_2012_512_paramSetTest "GOST R 34.10-2012 (512 bit) testing parameter set" +#define NID_id_tc26_gost_3410_2012_512_paramSetTest 997 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetTest OBJ_id_tc26_gost_3410_2012_512_constants,0L + +#define SN_id_tc26_gost_3410_2012_512_paramSetA "id-tc26-gost-3410-2012-512-paramSetA" +#define LN_id_tc26_gost_3410_2012_512_paramSetA "GOST R 34.10-2012 (512 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_512_paramSetA 998 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetA OBJ_id_tc26_gost_3410_2012_512_constants,1L + +#define SN_id_tc26_gost_3410_2012_512_paramSetB "id-tc26-gost-3410-2012-512-paramSetB" +#define LN_id_tc26_gost_3410_2012_512_paramSetB "GOST R 34.10-2012 (512 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_512_paramSetB 999 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetB OBJ_id_tc26_gost_3410_2012_512_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetC "id-tc26-gost-3410-2012-512-paramSetC" +#define LN_id_tc26_gost_3410_2012_512_paramSetC "GOST R 34.10-2012 (512 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_512_paramSetC 1149 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetC OBJ_id_tc26_gost_3410_2012_512_constants,3L + +#define SN_id_tc26_digest_constants "id-tc26-digest-constants" +#define NID_id_tc26_digest_constants 1000 +#define OBJ_id_tc26_digest_constants OBJ_id_tc26_constants,2L + +#define SN_id_tc26_cipher_constants "id-tc26-cipher-constants" +#define NID_id_tc26_cipher_constants 1001 +#define OBJ_id_tc26_cipher_constants OBJ_id_tc26_constants,5L + +#define SN_id_tc26_gost_28147_constants "id-tc26-gost-28147-constants" +#define NID_id_tc26_gost_28147_constants 1002 +#define OBJ_id_tc26_gost_28147_constants OBJ_id_tc26_cipher_constants,1L + +#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" +#define LN_id_tc26_gost_28147_param_Z "GOST 28147-89 TC26 parameter set" +#define NID_id_tc26_gost_28147_param_Z 1003 +#define OBJ_id_tc26_gost_28147_param_Z OBJ_id_tc26_gost_28147_constants,1L + +#define SN_INN "INN" +#define LN_INN "INN" +#define NID_INN 1004 +#define OBJ_INN OBJ_member_body,643L,3L,131L,1L,1L + +#define SN_OGRN "OGRN" +#define LN_OGRN "OGRN" +#define NID_OGRN 1005 +#define OBJ_OGRN OBJ_member_body,643L,100L,1L + +#define SN_SNILS "SNILS" +#define LN_SNILS "SNILS" +#define NID_SNILS 1006 +#define OBJ_SNILS OBJ_member_body,643L,100L,3L + +#define SN_subjectSignTool "subjectSignTool" +#define LN_subjectSignTool "Signing Tool of Subject" +#define NID_subjectSignTool 1007 +#define OBJ_subjectSignTool OBJ_member_body,643L,100L,111L + +#define SN_issuerSignTool "issuerSignTool" +#define LN_issuerSignTool "Signing Tool of Issuer" +#define NID_issuerSignTool 1008 +#define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L + +#define SN_grasshopper_ecb "grasshopper-ecb" +#define NID_grasshopper_ecb 1012 + +#define SN_grasshopper_ctr "grasshopper-ctr" +#define NID_grasshopper_ctr 1013 + +#define SN_grasshopper_ofb "grasshopper-ofb" +#define NID_grasshopper_ofb 1014 + +#define SN_grasshopper_cbc "grasshopper-cbc" +#define NID_grasshopper_cbc 1015 + +#define SN_grasshopper_cfb "grasshopper-cfb" +#define NID_grasshopper_cfb 1016 + +#define SN_grasshopper_mac "grasshopper-mac" +#define NID_grasshopper_mac 1017 + +#define SN_magma_ecb "magma-ecb" +#define NID_magma_ecb 1187 + +#define SN_magma_ctr "magma-ctr" +#define NID_magma_ctr 1188 + +#define SN_magma_ofb "magma-ofb" +#define NID_magma_ofb 1189 + +#define SN_magma_cbc "magma-cbc" +#define NID_magma_cbc 1190 + +#define SN_magma_cfb "magma-cfb" +#define NID_magma_cfb 1191 + +#define SN_magma_mac "magma-mac" +#define NID_magma_mac 1192 + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_128_gcm "CAMELLIA-128-GCM" +#define LN_camellia_128_gcm "camellia-128-gcm" +#define NID_camellia_128_gcm 961 +#define OBJ_camellia_128_gcm OBJ_camellia,6L + +#define SN_camellia_128_ccm "CAMELLIA-128-CCM" +#define LN_camellia_128_ccm "camellia-128-ccm" +#define NID_camellia_128_ccm 962 +#define OBJ_camellia_128_ccm OBJ_camellia,7L + +#define SN_camellia_128_ctr "CAMELLIA-128-CTR" +#define LN_camellia_128_ctr "camellia-128-ctr" +#define NID_camellia_128_ctr 963 +#define OBJ_camellia_128_ctr OBJ_camellia,9L + +#define SN_camellia_128_cmac "CAMELLIA-128-CMAC" +#define LN_camellia_128_cmac "camellia-128-cmac" +#define NID_camellia_128_cmac 964 +#define OBJ_camellia_128_cmac OBJ_camellia,10L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_192_gcm "CAMELLIA-192-GCM" +#define LN_camellia_192_gcm "camellia-192-gcm" +#define NID_camellia_192_gcm 965 +#define OBJ_camellia_192_gcm OBJ_camellia,26L + +#define SN_camellia_192_ccm "CAMELLIA-192-CCM" +#define LN_camellia_192_ccm "camellia-192-ccm" +#define NID_camellia_192_ccm 966 +#define OBJ_camellia_192_ccm OBJ_camellia,27L + +#define SN_camellia_192_ctr "CAMELLIA-192-CTR" +#define LN_camellia_192_ctr "camellia-192-ctr" +#define NID_camellia_192_ctr 967 +#define OBJ_camellia_192_ctr OBJ_camellia,29L + +#define SN_camellia_192_cmac "CAMELLIA-192-CMAC" +#define LN_camellia_192_cmac "camellia-192-cmac" +#define NID_camellia_192_cmac 968 +#define OBJ_camellia_192_cmac OBJ_camellia,30L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_256_gcm "CAMELLIA-256-GCM" +#define LN_camellia_256_gcm "camellia-256-gcm" +#define NID_camellia_256_gcm 969 +#define OBJ_camellia_256_gcm OBJ_camellia,46L + +#define SN_camellia_256_ccm "CAMELLIA-256-CCM" +#define LN_camellia_256_ccm "camellia-256-ccm" +#define NID_camellia_256_ccm 970 +#define OBJ_camellia_256_ccm OBJ_camellia,47L + +#define SN_camellia_256_ctr "CAMELLIA-256-CTR" +#define LN_camellia_256_ctr "camellia-256-ctr" +#define NID_camellia_256_ctr 971 +#define OBJ_camellia_256_ctr OBJ_camellia,49L + +#define SN_camellia_256_cmac "CAMELLIA-256-CMAC" +#define LN_camellia_256_cmac "camellia-256-cmac" +#define NID_camellia_256_cmac 972 +#define OBJ_camellia_256_cmac OBJ_camellia,50L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define OBJ_aria 1L,2L,410L,200046L,1L,1L + +#define SN_aria_128_ecb "ARIA-128-ECB" +#define LN_aria_128_ecb "aria-128-ecb" +#define NID_aria_128_ecb 1065 +#define OBJ_aria_128_ecb OBJ_aria,1L + +#define SN_aria_128_cbc "ARIA-128-CBC" +#define LN_aria_128_cbc "aria-128-cbc" +#define NID_aria_128_cbc 1066 +#define OBJ_aria_128_cbc OBJ_aria,2L + +#define SN_aria_128_cfb128 "ARIA-128-CFB" +#define LN_aria_128_cfb128 "aria-128-cfb" +#define NID_aria_128_cfb128 1067 +#define OBJ_aria_128_cfb128 OBJ_aria,3L + +#define SN_aria_128_ofb128 "ARIA-128-OFB" +#define LN_aria_128_ofb128 "aria-128-ofb" +#define NID_aria_128_ofb128 1068 +#define OBJ_aria_128_ofb128 OBJ_aria,4L + +#define SN_aria_128_ctr "ARIA-128-CTR" +#define LN_aria_128_ctr "aria-128-ctr" +#define NID_aria_128_ctr 1069 +#define OBJ_aria_128_ctr OBJ_aria,5L + +#define SN_aria_192_ecb "ARIA-192-ECB" +#define LN_aria_192_ecb "aria-192-ecb" +#define NID_aria_192_ecb 1070 +#define OBJ_aria_192_ecb OBJ_aria,6L + +#define SN_aria_192_cbc "ARIA-192-CBC" +#define LN_aria_192_cbc "aria-192-cbc" +#define NID_aria_192_cbc 1071 +#define OBJ_aria_192_cbc OBJ_aria,7L + +#define SN_aria_192_cfb128 "ARIA-192-CFB" +#define LN_aria_192_cfb128 "aria-192-cfb" +#define NID_aria_192_cfb128 1072 +#define OBJ_aria_192_cfb128 OBJ_aria,8L + +#define SN_aria_192_ofb128 "ARIA-192-OFB" +#define LN_aria_192_ofb128 "aria-192-ofb" +#define NID_aria_192_ofb128 1073 +#define OBJ_aria_192_ofb128 OBJ_aria,9L + +#define SN_aria_192_ctr "ARIA-192-CTR" +#define LN_aria_192_ctr "aria-192-ctr" +#define NID_aria_192_ctr 1074 +#define OBJ_aria_192_ctr OBJ_aria,10L + +#define SN_aria_256_ecb "ARIA-256-ECB" +#define LN_aria_256_ecb "aria-256-ecb" +#define NID_aria_256_ecb 1075 +#define OBJ_aria_256_ecb OBJ_aria,11L + +#define SN_aria_256_cbc "ARIA-256-CBC" +#define LN_aria_256_cbc "aria-256-cbc" +#define NID_aria_256_cbc 1076 +#define OBJ_aria_256_cbc OBJ_aria,12L + +#define SN_aria_256_cfb128 "ARIA-256-CFB" +#define LN_aria_256_cfb128 "aria-256-cfb" +#define NID_aria_256_cfb128 1077 +#define OBJ_aria_256_cfb128 OBJ_aria,13L + +#define SN_aria_256_ofb128 "ARIA-256-OFB" +#define LN_aria_256_ofb128 "aria-256-ofb" +#define NID_aria_256_ofb128 1078 +#define OBJ_aria_256_ofb128 OBJ_aria,14L + +#define SN_aria_256_ctr "ARIA-256-CTR" +#define LN_aria_256_ctr "aria-256-ctr" +#define NID_aria_256_ctr 1079 +#define OBJ_aria_256_ctr OBJ_aria,15L + +#define SN_aria_128_cfb1 "ARIA-128-CFB1" +#define LN_aria_128_cfb1 "aria-128-cfb1" +#define NID_aria_128_cfb1 1080 + +#define SN_aria_192_cfb1 "ARIA-192-CFB1" +#define LN_aria_192_cfb1 "aria-192-cfb1" +#define NID_aria_192_cfb1 1081 + +#define SN_aria_256_cfb1 "ARIA-256-CFB1" +#define LN_aria_256_cfb1 "aria-256-cfb1" +#define NID_aria_256_cfb1 1082 + +#define SN_aria_128_cfb8 "ARIA-128-CFB8" +#define LN_aria_128_cfb8 "aria-128-cfb8" +#define NID_aria_128_cfb8 1083 + +#define SN_aria_192_cfb8 "ARIA-192-CFB8" +#define LN_aria_192_cfb8 "aria-192-cfb8" +#define NID_aria_192_cfb8 1084 + +#define SN_aria_256_cfb8 "ARIA-256-CFB8" +#define LN_aria_256_cfb8 "aria-256-cfb8" +#define NID_aria_256_cfb8 1085 + +#define SN_aria_128_ccm "ARIA-128-CCM" +#define LN_aria_128_ccm "aria-128-ccm" +#define NID_aria_128_ccm 1120 +#define OBJ_aria_128_ccm OBJ_aria,37L + +#define SN_aria_192_ccm "ARIA-192-CCM" +#define LN_aria_192_ccm "aria-192-ccm" +#define NID_aria_192_ccm 1121 +#define OBJ_aria_192_ccm OBJ_aria,38L + +#define SN_aria_256_ccm "ARIA-256-CCM" +#define LN_aria_256_ccm "aria-256-ccm" +#define NID_aria_256_ccm 1122 +#define OBJ_aria_256_ccm OBJ_aria,39L + +#define SN_aria_128_gcm "ARIA-128-GCM" +#define LN_aria_128_gcm "aria-128-gcm" +#define NID_aria_128_gcm 1123 +#define OBJ_aria_128_gcm OBJ_aria,34L + +#define SN_aria_192_gcm "ARIA-192-GCM" +#define LN_aria_192_gcm "aria-192-gcm" +#define NID_aria_192_gcm 1124 +#define OBJ_aria_192_gcm OBJ_aria,35L + +#define SN_aria_256_gcm "ARIA-256-GCM" +#define LN_aria_256_gcm "aria-256-gcm" +#define NID_aria_256_gcm 1125 +#define OBJ_aria_256_gcm OBJ_aria,36L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_sm4_ecb "SM4-ECB" +#define LN_sm4_ecb "sm4-ecb" +#define NID_sm4_ecb 1133 +#define OBJ_sm4_ecb OBJ_sm_scheme,104L,1L + +#define SN_sm4_cbc "SM4-CBC" +#define LN_sm4_cbc "sm4-cbc" +#define NID_sm4_cbc 1134 +#define OBJ_sm4_cbc OBJ_sm_scheme,104L,2L + +#define SN_sm4_ofb128 "SM4-OFB" +#define LN_sm4_ofb128 "sm4-ofb" +#define NID_sm4_ofb128 1135 +#define OBJ_sm4_ofb128 OBJ_sm_scheme,104L,3L + +#define SN_sm4_cfb128 "SM4-CFB" +#define LN_sm4_cfb128 "sm4-cfb" +#define NID_sm4_cfb128 1137 +#define OBJ_sm4_cfb128 OBJ_sm_scheme,104L,4L + +#define SN_sm4_cfb1 "SM4-CFB1" +#define LN_sm4_cfb1 "sm4-cfb1" +#define NID_sm4_cfb1 1136 +#define OBJ_sm4_cfb1 OBJ_sm_scheme,104L,5L + +#define SN_sm4_cfb8 "SM4-CFB8" +#define LN_sm4_cfb8 "sm4-cfb8" +#define NID_sm4_cfb8 1138 +#define OBJ_sm4_cfb8 OBJ_sm_scheme,104L,6L + +#define SN_sm4_ctr "SM4-CTR" +#define LN_sm4_ctr "sm4-ctr" +#define NID_sm4_ctr 1139 +#define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" +#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" +#define NID_aes_128_cbc_hmac_sha256 948 + +#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" +#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" +#define NID_aes_192_cbc_hmac_sha256 949 + +#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" +#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" +#define NID_aes_256_cbc_hmac_sha256 950 + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 1018 + +#define SN_chacha20 "ChaCha20" +#define LN_chacha20 "chacha20" +#define NID_chacha20 1019 + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 951 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 952 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 953 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 954 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_jurisdictionLocalityName "jurisdictionL" +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 955 +#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L + +#define SN_jurisdictionStateOrProvinceName "jurisdictionST" +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 956 +#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L + +#define SN_jurisdictionCountryName "jurisdictionC" +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 957 +#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L + +#define SN_id_scrypt "id-scrypt" +#define LN_id_scrypt "scrypt" +#define NID_id_scrypt 973 +#define OBJ_id_scrypt 1L,3L,6L,1L,4L,1L,11591L,4L,11L + +#define SN_tls1_prf "TLS1-PRF" +#define LN_tls1_prf "tls1-prf" +#define NID_tls1_prf 1021 + +#define SN_hkdf "HKDF" +#define LN_hkdf "hkdf" +#define NID_hkdf 1036 + +#define SN_id_pkinit "id-pkinit" +#define NID_id_pkinit 1031 +#define OBJ_id_pkinit 1L,3L,6L,1L,5L,2L,3L + +#define SN_pkInitClientAuth "pkInitClientAuth" +#define LN_pkInitClientAuth "PKINIT Client Auth" +#define NID_pkInitClientAuth 1032 +#define OBJ_pkInitClientAuth OBJ_id_pkinit,4L + +#define SN_pkInitKDC "pkInitKDC" +#define LN_pkInitKDC "Signing KDC Response" +#define NID_pkInitKDC 1033 +#define OBJ_pkInitKDC OBJ_id_pkinit,5L + +#define SN_X25519 "X25519" +#define NID_X25519 1034 +#define OBJ_X25519 1L,3L,101L,110L + +#define SN_X448 "X448" +#define NID_X448 1035 +#define OBJ_X448 1L,3L,101L,111L + +#define SN_ED25519 "ED25519" +#define NID_ED25519 1087 +#define OBJ_ED25519 1L,3L,101L,112L + +#define SN_ED448 "ED448" +#define NID_ED448 1088 +#define OBJ_ED448 1L,3L,101L,113L + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 1037 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 1038 + +#define SN_kx_dhe "KxDHE" +#define LN_kx_dhe "kx-dhe" +#define NID_kx_dhe 1039 + +#define SN_kx_ecdhe_psk "KxECDHE-PSK" +#define LN_kx_ecdhe_psk "kx-ecdhe-psk" +#define NID_kx_ecdhe_psk 1040 + +#define SN_kx_dhe_psk "KxDHE-PSK" +#define LN_kx_dhe_psk "kx-dhe-psk" +#define NID_kx_dhe_psk 1041 + +#define SN_kx_rsa_psk "KxRSA_PSK" +#define LN_kx_rsa_psk "kx-rsa-psk" +#define NID_kx_rsa_psk 1042 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 1043 + +#define SN_kx_srp "KxSRP" +#define LN_kx_srp "kx-srp" +#define NID_kx_srp 1044 + +#define SN_kx_gost "KxGOST" +#define LN_kx_gost "kx-gost" +#define NID_kx_gost 1045 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 1063 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 1046 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 1047 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 1048 + +#define SN_auth_dss "AuthDSS" +#define LN_auth_dss "auth-dss" +#define NID_auth_dss 1049 + +#define SN_auth_gost01 "AuthGOST01" +#define LN_auth_gost01 "auth-gost01" +#define NID_auth_gost01 1050 + +#define SN_auth_gost12 "AuthGOST12" +#define LN_auth_gost12 "auth-gost12" +#define NID_auth_gost12 1051 + +#define SN_auth_srp "AuthSRP" +#define LN_auth_srp "auth-srp" +#define NID_auth_srp 1052 + +#define SN_auth_null "AuthNULL" +#define LN_auth_null "auth-null" +#define NID_auth_null 1053 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 1064 + +#define SN_poly1305 "Poly1305" +#define LN_poly1305 "poly1305" +#define NID_poly1305 1061 + +#define SN_siphash "SipHash" +#define LN_siphash "siphash" +#define NID_siphash 1062 + +#define SN_ffdhe2048 "ffdhe2048" +#define NID_ffdhe2048 1126 + +#define SN_ffdhe3072 "ffdhe3072" +#define NID_ffdhe3072 1127 + +#define SN_ffdhe4096 "ffdhe4096" +#define NID_ffdhe4096 1128 + +#define SN_ffdhe6144 "ffdhe6144" +#define NID_ffdhe6144 1129 + +#define SN_ffdhe8192 "ffdhe8192" +#define NID_ffdhe8192 1130 + +#define SN_ISO_UA "ISO-UA" +#define NID_ISO_UA 1150 +#define OBJ_ISO_UA OBJ_member_body,804L + +#define SN_ua_pki "ua-pki" +#define NID_ua_pki 1151 +#define OBJ_ua_pki OBJ_ISO_UA,2L,1L,1L,1L + +#define SN_dstu28147 "dstu28147" +#define LN_dstu28147 "DSTU Gost 28147-2009" +#define NID_dstu28147 1152 +#define OBJ_dstu28147 OBJ_ua_pki,1L,1L,1L + +#define SN_dstu28147_ofb "dstu28147-ofb" +#define LN_dstu28147_ofb "DSTU Gost 28147-2009 OFB mode" +#define NID_dstu28147_ofb 1153 +#define OBJ_dstu28147_ofb OBJ_dstu28147,2L + +#define SN_dstu28147_cfb "dstu28147-cfb" +#define LN_dstu28147_cfb "DSTU Gost 28147-2009 CFB mode" +#define NID_dstu28147_cfb 1154 +#define OBJ_dstu28147_cfb OBJ_dstu28147,3L + +#define SN_dstu28147_wrap "dstu28147-wrap" +#define LN_dstu28147_wrap "DSTU Gost 28147-2009 key wrap" +#define NID_dstu28147_wrap 1155 +#define OBJ_dstu28147_wrap OBJ_dstu28147,5L + +#define SN_hmacWithDstu34311 "hmacWithDstu34311" +#define LN_hmacWithDstu34311 "HMAC DSTU Gost 34311-95" +#define NID_hmacWithDstu34311 1156 +#define OBJ_hmacWithDstu34311 OBJ_ua_pki,1L,1L,2L + +#define SN_dstu34311 "dstu34311" +#define LN_dstu34311 "DSTU Gost 34311-95" +#define NID_dstu34311 1157 +#define OBJ_dstu34311 OBJ_ua_pki,1L,2L,1L + +#define SN_dstu4145le "dstu4145le" +#define LN_dstu4145le "DSTU 4145-2002 little endian" +#define NID_dstu4145le 1158 +#define OBJ_dstu4145le OBJ_ua_pki,1L,3L,1L,1L + +#define SN_dstu4145be "dstu4145be" +#define LN_dstu4145be "DSTU 4145-2002 big endian" +#define NID_dstu4145be 1159 +#define OBJ_dstu4145be OBJ_dstu4145le,1L,1L + +#define SN_uacurve0 "uacurve0" +#define LN_uacurve0 "DSTU curve 0" +#define NID_uacurve0 1160 +#define OBJ_uacurve0 OBJ_dstu4145le,2L,0L + +#define SN_uacurve1 "uacurve1" +#define LN_uacurve1 "DSTU curve 1" +#define NID_uacurve1 1161 +#define OBJ_uacurve1 OBJ_dstu4145le,2L,1L + +#define SN_uacurve2 "uacurve2" +#define LN_uacurve2 "DSTU curve 2" +#define NID_uacurve2 1162 +#define OBJ_uacurve2 OBJ_dstu4145le,2L,2L + +#define SN_uacurve3 "uacurve3" +#define LN_uacurve3 "DSTU curve 3" +#define NID_uacurve3 1163 +#define OBJ_uacurve3 OBJ_dstu4145le,2L,3L + +#define SN_uacurve4 "uacurve4" +#define LN_uacurve4 "DSTU curve 4" +#define NID_uacurve4 1164 +#define OBJ_uacurve4 OBJ_dstu4145le,2L,4L + +#define SN_uacurve5 "uacurve5" +#define LN_uacurve5 "DSTU curve 5" +#define NID_uacurve5 1165 +#define OBJ_uacurve5 OBJ_dstu4145le,2L,5L + +#define SN_uacurve6 "uacurve6" +#define LN_uacurve6 "DSTU curve 6" +#define NID_uacurve6 1166 +#define OBJ_uacurve6 OBJ_dstu4145le,2L,6L + +#define SN_uacurve7 "uacurve7" +#define LN_uacurve7 "DSTU curve 7" +#define NID_uacurve7 1167 +#define OBJ_uacurve7 OBJ_dstu4145le,2L,7L + +#define SN_uacurve8 "uacurve8" +#define LN_uacurve8 "DSTU curve 8" +#define NID_uacurve8 1168 +#define OBJ_uacurve8 OBJ_dstu4145le,2L,8L + +#define SN_uacurve9 "uacurve9" +#define LN_uacurve9 "DSTU curve 9" +#define NID_uacurve9 1169 +#define OBJ_uacurve9 OBJ_dstu4145le,2L,9L diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/objects.h b/Hin2n/src/main/jniLibs/x86/include/openssl/objects.h new file mode 100644 index 00000000..5e8b5762 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/objects.h @@ -0,0 +1,175 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# include +# include +# include +# include + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignment discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, declare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +#if OPENSSL_API_COMPAT < 0x10100000L +# define OBJ_cleanup() while(0) continue +#endif +int OBJ_create_objects(BIO *in); + +size_t OBJ_length(const ASN1_OBJECT *obj); +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/objectserr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/objectserr.h new file mode 100644 index 00000000..02e166f1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/objectserr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJERR_H +# define HEADER_OBJERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OBJ_strings(void); + +/* + * OBJ function codes. + */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_ADD_SIGID 107 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 +# define OBJ_F_OBJ_TXT2OBJ 108 + +/* + * OBJ reason codes. + */ +# define OBJ_R_OID_EXISTS 102 +# define OBJ_R_UNKNOWN_NID 101 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ocsp.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ocsp.h new file mode 100644 index 00000000..4d759a49 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ocsp.h @@ -0,0 +1,352 @@ +/* + * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +#include + +/* + * These definitions are outside the OPENSSL_NO_OCSP guard because although for + * historical reasons they have OCSP_* names, they can actually be used + * independently of OCSP. E.g. see RFC5280 + */ +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + + +# ifndef OPENSSL_NO_OCSP + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +typedef struct ocsp_cert_id_st OCSP_CERTID; + +DEFINE_STACK_OF(OCSP_CERTID) + +typedef struct ocsp_one_request_st OCSP_ONEREQ; + +DEFINE_STACK_OF(OCSP_ONEREQ) + +typedef struct ocsp_req_info_st OCSP_REQINFO; +typedef struct ocsp_signature_st OCSP_SIGNATURE; +typedef struct ocsp_request_st OCSP_REQUEST; + +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; + +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 + +DEFINE_STACK_OF(OCSP_RESPID) + +typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; + +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 + +typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; +typedef struct ocsp_single_response_st OCSP_SINGLERESP; + +DEFINE_STACK_OF(OCSP_SINGLERESP) + +typedef struct ocsp_response_data_st OCSP_RESPDATA; + +typedef struct ocsp_basic_response_st OCSP_BASICRESP; + +typedef struct ocsp_crl_id_st OCSP_CRLID; +typedef struct ocsp_service_locator_st OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST, \ + bp,(char **)(x),cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) (OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE, \ + bp,(char **)(x),cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, + const X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, + const ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs); +const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs); +const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs); +const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, + const ASN1_OCTET_STRING **pid, + const X509_NAME **pname); +int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, + ASN1_OCTET_STRING **pid, + X509_NAME **pname); + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); +int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, + X509 *signer, EVP_MD_CTX *ctx, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert); + +X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); +const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ocsperr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ocsperr.h new file mode 100644 index 00000000..8dd9e01a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ocsperr.h @@ -0,0 +1,78 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSPERR_H +# define HEADER_OCSPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_OCSP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OCSP_strings(void); + +/* + * OCSP function codes. + */ +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_SIGN_CTX 119 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_PARSE_HTTP_LINE1 118 + +/* + * OCSP reason codes. + */ +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_NO_SIGNER_KEY 130 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/opensslconf.h b/Hin2n/src/main/jniLibs/x86/include/openssl/opensslconf.h new file mode 100644 index 00000000..52bc2c62 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/opensslconf.h @@ -0,0 +1,195 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/opensslconf.h.in + * + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_ALGORITHM_DEFINES +# error OPENSSL_ALGORITHM_DEFINES no longer supported +#endif + +/* + * OpenSSL was configured with the following options: + */ + +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_RAND_SEED_OS +# define OPENSSL_RAND_SEED_OS +#endif +#ifndef OPENSSL_NO_AFALGENG +# define OPENSSL_NO_AFALGENG +#endif +#ifndef OPENSSL_NO_ASAN +# define OPENSSL_NO_ASAN +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_NO_CRYPTO_MDEBUG +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +#endif +#ifndef OPENSSL_NO_DEVCRYPTOENG +# define OPENSSL_NO_DEVCRYPTOENG +#endif +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_EGD +# define OPENSSL_NO_EGD +#endif +#ifndef OPENSSL_NO_EXTERNAL_TESTS +# define OPENSSL_NO_EXTERNAL_TESTS +#endif +#ifndef OPENSSL_NO_FUZZ_AFL +# define OPENSSL_NO_FUZZ_AFL +#endif +#ifndef OPENSSL_NO_FUZZ_LIBFUZZER +# define OPENSSL_NO_FUZZ_LIBFUZZER +#endif +#ifndef OPENSSL_NO_HEARTBEATS +# define OPENSSL_NO_HEARTBEATS +#endif +#ifndef OPENSSL_NO_MSAN +# define OPENSSL_NO_MSAN +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL3 +# define OPENSSL_NO_SSL3 +#endif +#ifndef OPENSSL_NO_SSL3_METHOD +# define OPENSSL_NO_SSL3_METHOD +#endif +#ifndef OPENSSL_NO_UBSAN +# define OPENSSL_NO_UBSAN +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif +#ifndef OPENSSL_NO_STATIC_ENGINE +# define OPENSSL_NO_STATIC_ENGINE +#endif + + +/* + * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers + * don't like that. This will hopefully silence them. + */ +#define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy; + +/* + * Applications should use -DOPENSSL_API_COMPAT= to suppress the + * declarations of functions deprecated in or before . Otherwise, they + * still won't see them if the library has been built to disable deprecated + * functions. + */ +#ifndef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f; +# ifdef __GNUC__ +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) +# undef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); +# endif +# endif +#endif + +#ifndef OPENSSL_FILE +# ifdef OPENSSL_NO_FILENAMES +# define OPENSSL_FILE "" +# define OPENSSL_LINE 0 +# else +# define OPENSSL_FILE __FILE__ +# define OPENSSL_LINE __LINE__ +# endif +#endif + +#ifndef OPENSSL_MIN_API +# define OPENSSL_MIN_API 0 +#endif + +#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API +# undef OPENSSL_API_COMPAT +# define OPENSSL_API_COMPAT OPENSSL_MIN_API +#endif + +/* + * Do not deprecate things to be deprecated in version 1.2.0 before the + * OpenSSL version number matches. + */ +#if OPENSSL_VERSION_NUMBER < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) f; +#elif OPENSSL_API_COMPAT < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_2_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10100000L +# define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_1_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10000000L +# define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_0_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x00908000L +# define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_0_9_8(f) +#endif + +/* Generate 80386 code? */ +#undef I386_ONLY + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* + * The following are cipher-specific, but are part of the public API. + */ +#if !defined(OPENSSL_SYS_UEFI) +# define BN_LLONG +/* Only one for the following should be defined */ +# undef SIXTY_FOUR_BIT_LONG +# undef SIXTY_FOUR_BIT +# define THIRTY_TWO_BIT +#endif + +#define RC4_INT unsigned int + +#ifdef __cplusplus +} +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/opensslv.h b/Hin2n/src/main/jniLibs/x86/include/openssl/opensslv.h new file mode 100644 index 00000000..17d271f5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/opensslv.h @@ -0,0 +1,101 @@ +/* + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1010107fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1g 21 Apr 2020" + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major version number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.1" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ossl_typ.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ossl_typ.h new file mode 100644 index 00000000..e0edfaaf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ossl_typ.h @@ -0,0 +1,197 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_sctx_st ASN1_SCTX; + +# ifdef _WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +struct dane_st; +typedef struct bio_st BIO; +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_md_st EVP_MD; +typedef struct evp_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; + +typedef struct hmac_ctx_st HMAC_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_pss_params_st RSA_PSS_PARAMS; + +typedef struct ec_key_st EC_KEY; +typedef struct ec_key_method_st EC_KEY_METHOD; + +typedef struct rand_meth_st RAND_METHOD; +typedef struct rand_drbg_st RAND_DRBG; + +typedef struct ssl_dane_st SSL_DANE; +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + +typedef struct x509_sig_info_st X509_SIG_INFO; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct comp_ctx_st COMP_CTX; +typedef struct comp_method_st COMP_METHOD; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +typedef struct sct_st SCT; +typedef struct sct_ctx_st SCT_CTX; +typedef struct ctlog_st CTLOG; +typedef struct ctlog_store_st CTLOG_STORE; +typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; + +typedef struct ossl_store_info_st OSSL_STORE_INFO; +typedef struct ossl_store_search_st OSSL_STORE_SEARCH; + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ + defined(INTMAX_MAX) && defined(UINTMAX_MAX) +typedef intmax_t ossl_intmax_t; +typedef uintmax_t ossl_uintmax_t; +#else +/* + * Not long long, because the C-library can only be expected to provide + * strtoll(), strtoull() at the same time as intmax_t and strtoimax(), + * strtoumax(). Since we use these for parsing arguments, we need the + * conversion functions, not just the sizes. + */ +typedef long ossl_intmax_t; +typedef unsigned long ossl_uintmax_t; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pem.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pem.h new file mode 100644 index 00000000..2ef5b5d0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pem.h @@ -0,0 +1,378 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_STDIO) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_fp_const(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +# define PEM_FLAG_SECURE 0x1 +# define PEM_FLAG_EAY_COMPATIBLE 0x2 +# define PEM_FLAG_ONLY_B64 0x4 +int PEM_read_bio_ex(BIO *bp, char **name, char **header, + unsigned char **data, long *len, unsigned int flags); +int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); + +#ifndef OPENSSL_NO_STDIO +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +#endif + +int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +/* The default pem_password_cb that's used internally */ +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +DECLARE_PEM_write_const(DHxparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); +# endif +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +# ifndef OPENSSL_NO_DSA +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif +# endif + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pem2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pem2.h new file mode 100644 index 00000000..038fe790 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pem2.h @@ -0,0 +1,13 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM2_H +# define HEADER_PEM2_H +# include +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pemerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pemerr.h new file mode 100644 index 00000000..0c45918f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pemerr.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEMERR_H +# define HEADER_PEMERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PEM_strings(void); + +/* + * PEM function codes. + */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_I2B 146 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_GET_HEADER_AND_DATA 143 +# define PEM_F_GET_NAME 144 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_DHPARAMS 141 +# define PEM_F_PEM_READ_BIO_EX 145 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_DHPARAMS 142 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* + * PEM reason codes. + */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_HEADER_TOO_LONG 128 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_MISSING_DEK_IV 129 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNEXPECTED_DEK_IV 130 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12.h new file mode 100644 index 00000000..3f43dad6 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12.h @@ -0,0 +1,223 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* It's not clear if these are actually needed... */ +# define PKCS12_key_gen PKCS12_key_gen_utf8 +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_utf8 + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA; + +typedef struct PKCS12_st PKCS12; + +typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; + +DEFINE_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +#if OPENSSL_API_COMPAT < 0x10100000L + +# define M_PKCS12_bag_type PKCS12_bag_type +# define M_PKCS12_cert_bag_type PKCS12_cert_bag_type +# define M_PKCS12_crl_bag_type PKCS12_cert_bag_type + +# define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert +# define PKCS12_certbag2scrl PKCS12_SAFEBAG_get1_crl +# define PKCS12_bag_type PKCS12_SAFEBAG_get_nid +# define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid +# define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert +# define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl +# define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf +# define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt + +#endif + +DEPRECATEDIN_1_1_0(ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)) + +ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid); +int PKCS12_mac_present(const PKCS12 *p12); +void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, + const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, + const ASN1_INTEGER **piter, + const PKCS12 *p12); + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, + int attr_nid); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); + +X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); +const STACK_OF(PKCS12_SAFEBAG) * +PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); +const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); +const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, + int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +const STACK_OF(X509_ATTRIBUTE) * +PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(const unsigned char *uni, int unilen); +unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, const char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, const char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +# endif +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +# ifndef OPENSSL_NO_STDIO +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +# endif +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12err.h new file mode 100644 index 00000000..eff5eb26 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs12err.h @@ -0,0 +1,81 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12ERR_H +# define HEADER_PKCS12ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS12_strings(void); + +/* + * PKCS12 function codes. + */ +# define PKCS12_F_OPENSSL_ASC2UNI 121 +# define PKCS12_F_OPENSSL_UNI2ASC 124 +# define PKCS12_F_OPENSSL_UNI2UTF8 127 +# define PKCS12_F_OPENSSL_UTF82UNI 129 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_KEY_GEN_UTF8 116 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF 112 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 113 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT 133 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ENCRYPT 125 +# define PKCS12_F_PKCS8_SET0_PBE 132 + +/* + * PKCS12 reason codes. + */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7.h new file mode 100644 index 00000000..9b66e002 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7.h @@ -0,0 +1,319 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DEFINE_STACK_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DEFINE_STACK_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DEFINE_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 +# define PKCS7_NO_DUAL_CONTENT 0x10000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +/* CRLF ASCII canonicalisation */ +# define SMIME_ASCIICRLF 0x80000 + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_STDIO +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7err.h new file mode 100644 index 00000000..02e0299a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/pkcs7err.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7ERR_H +# define HEADER_PKCS7ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS7_strings(void); + +/* + * PKCS7 function codes. + */ +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 + +/* + * PKCS7 reason codes. + */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rand.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rand.h new file mode 100644 index 00000000..38a2a271 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rand.h @@ -0,0 +1,77 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct rand_meth_st { + int (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + int (*add) (const void *buf, int num, double randomness); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif + +RAND_METHOD *RAND_OpenSSL(void); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define RAND_cleanup() while(0) continue +# endif +int RAND_bytes(unsigned char *buf, int num); +int RAND_priv_bytes(unsigned char *buf, int num); +DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num)) + +void RAND_seed(const void *buf, int num); +void RAND_keep_random_devices_open(int keep); + +# if defined(__ANDROID__) && defined(__NDK_FPABI__) +__NDK_FPABI__ /* __attribute__((pcs("aapcs"))) on ARM */ +# endif +void RAND_add(const void *buf, int num, double randomness); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); + +# ifndef OPENSSL_NO_EGD +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +# endif + +int RAND_poll(void); + +# if defined(_WIN32) && (defined(BASETYPES) || defined(_WINDEF_H)) +/* application has to include in order to use these */ +DEPRECATEDIN_1_1_0(void RAND_screen(void)) +DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM)) +# endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rand_drbg.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rand_drbg.h new file mode 100644 index 00000000..45b731b7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rand_drbg.h @@ -0,0 +1,130 @@ +/* + * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DRBG_RAND_H +# define HEADER_DRBG_RAND_H + +# include +# include +# include + +/* + * RAND_DRBG flags + * + * Note: if new flags are added, the constant `rand_drbg_used_flags` + * in drbg_lib.c needs to be updated accordingly. + */ + +/* In CTR mode, disable derivation function ctr_df */ +# define RAND_DRBG_FLAG_CTR_NO_DF 0x1 + + +# if OPENSSL_API_COMPAT < 0x10200000L +/* This #define was replaced by an internal constant and should not be used. */ +# define RAND_DRBG_USED_FLAGS (RAND_DRBG_FLAG_CTR_NO_DF) +# endif + +/* + * Default security strength (in the sense of [NIST SP 800-90Ar1]) + * + * NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that + * of the cipher by collecting less entropy. The current DRBG implementation + * does not take RAND_DRBG_STRENGTH into account and sets the strength of the + * DRBG to that of the cipher. + * + * RAND_DRBG_STRENGTH is currently only used for the legacy RAND + * implementation. + * + * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and + * NID_aes_256_ctr + */ +# define RAND_DRBG_STRENGTH 256 +/* Default drbg type */ +# define RAND_DRBG_TYPE NID_aes_256_ctr +/* Default drbg flags */ +# define RAND_DRBG_FLAGS 0 + + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * Object lifetime functions. + */ +RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent); +RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent); +int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags); +int RAND_DRBG_set_defaults(int type, unsigned int flags); +int RAND_DRBG_instantiate(RAND_DRBG *drbg, + const unsigned char *pers, size_t perslen); +int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); +void RAND_DRBG_free(RAND_DRBG *drbg); + +/* + * Object "use" functions. + */ +int RAND_DRBG_reseed(RAND_DRBG *drbg, + const unsigned char *adin, size_t adinlen, + int prediction_resistance); +int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); +int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen); + +int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval); +int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval); + +int RAND_DRBG_set_reseed_defaults( + unsigned int master_reseed_interval, + unsigned int slave_reseed_interval, + time_t master_reseed_time_interval, + time_t slave_reseed_time_interval + ); + +RAND_DRBG *RAND_DRBG_get0_master(void); +RAND_DRBG *RAND_DRBG_get0_public(void); +RAND_DRBG *RAND_DRBG_get0_private(void); + +/* + * EXDATA + */ +# define RAND_DRBG_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DRBG, l, p, newf, dupf, freef) +int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg); +void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); + +/* + * Callback function typedefs + */ +typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *drbg, + unsigned char **pout, + int entropy, size_t min_len, + size_t max_len, + int prediction_resistance); +typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx, + unsigned char *out, size_t outlen); +typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *drbg, unsigned char **pout, + int entropy, size_t min_len, + size_t max_len); +typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + +int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, + RAND_DRBG_get_entropy_fn get_entropy, + RAND_DRBG_cleanup_entropy_fn cleanup_entropy, + RAND_DRBG_get_nonce_fn get_nonce, + RAND_DRBG_cleanup_nonce_fn cleanup_nonce); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/randerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/randerr.h new file mode 100644 index 00000000..79d57905 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/randerr.h @@ -0,0 +1,94 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RANDERR_H +# define HEADER_RANDERR_H + +# include + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RAND_strings(void); + +/* + * RAND function codes. + */ +# define RAND_F_DATA_COLLECT_METHOD 127 +# define RAND_F_DRBG_BYTES 101 +# define RAND_F_DRBG_GET_ENTROPY 105 +# define RAND_F_DRBG_SETUP 117 +# define RAND_F_GET_ENTROPY 106 +# define RAND_F_RAND_BYTES 100 +# define RAND_F_RAND_DRBG_ENABLE_LOCKING 119 +# define RAND_F_RAND_DRBG_GENERATE 107 +# define RAND_F_RAND_DRBG_GET_ENTROPY 120 +# define RAND_F_RAND_DRBG_GET_NONCE 123 +# define RAND_F_RAND_DRBG_INSTANTIATE 108 +# define RAND_F_RAND_DRBG_NEW 109 +# define RAND_F_RAND_DRBG_RESEED 110 +# define RAND_F_RAND_DRBG_RESTART 102 +# define RAND_F_RAND_DRBG_SET 104 +# define RAND_F_RAND_DRBG_SET_DEFAULTS 121 +# define RAND_F_RAND_DRBG_UNINSTANTIATE 118 +# define RAND_F_RAND_LOAD_FILE 111 +# define RAND_F_RAND_POOL_ACQUIRE_ENTROPY 122 +# define RAND_F_RAND_POOL_ADD 103 +# define RAND_F_RAND_POOL_ADD_BEGIN 113 +# define RAND_F_RAND_POOL_ADD_END 114 +# define RAND_F_RAND_POOL_ATTACH 124 +# define RAND_F_RAND_POOL_BYTES_NEEDED 115 +# define RAND_F_RAND_POOL_GROW 125 +# define RAND_F_RAND_POOL_NEW 116 +# define RAND_F_RAND_PSEUDO_BYTES 126 +# define RAND_F_RAND_WRITE_FILE 112 + +/* + * RAND reason codes. + */ +# define RAND_R_ADDITIONAL_INPUT_TOO_LONG 102 +# define RAND_R_ALREADY_INSTANTIATED 103 +# define RAND_R_ARGUMENT_OUT_OF_RANGE 105 +# define RAND_R_CANNOT_OPEN_FILE 121 +# define RAND_R_DRBG_ALREADY_INITIALIZED 129 +# define RAND_R_DRBG_NOT_INITIALISED 104 +# define RAND_R_ENTROPY_INPUT_TOO_LONG 106 +# define RAND_R_ENTROPY_OUT_OF_RANGE 124 +# define RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED 127 +# define RAND_R_ERROR_INITIALISING_DRBG 107 +# define RAND_R_ERROR_INSTANTIATING_DRBG 108 +# define RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 109 +# define RAND_R_ERROR_RETRIEVING_ENTROPY 110 +# define RAND_R_ERROR_RETRIEVING_NONCE 111 +# define RAND_R_FAILED_TO_CREATE_LOCK 126 +# define RAND_R_FUNC_NOT_IMPLEMENTED 101 +# define RAND_R_FWRITE_ERROR 123 +# define RAND_R_GENERATE_ERROR 112 +# define RAND_R_INTERNAL_ERROR 113 +# define RAND_R_IN_ERROR_STATE 114 +# define RAND_R_NOT_A_REGULAR_FILE 122 +# define RAND_R_NOT_INSTANTIATED 115 +# define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128 +# define RAND_R_PARENT_LOCKING_NOT_ENABLED 130 +# define RAND_R_PARENT_STRENGTH_TOO_WEAK 131 +# define RAND_R_PERSONALISATION_STRING_TOO_LONG 116 +# define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED 133 +# define RAND_R_PRNG_NOT_SEEDED 100 +# define RAND_R_RANDOM_POOL_OVERFLOW 125 +# define RAND_R_RANDOM_POOL_UNDERFLOW 134 +# define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117 +# define RAND_R_RESEED_ERROR 118 +# define RAND_R_SELFTEST_FAILURE 119 +# define RAND_R_TOO_LITTLE_NONCE_REQUESTED 135 +# define RAND_R_TOO_MUCH_NONCE_REQUESTED 136 +# define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 +# define RAND_R_UNSUPPORTED_DRBG_TYPE 120 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rc2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rc2.h new file mode 100644 index 00000000..585f9e4c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rc2.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include + +# ifndef OPENSSL_NO_RC2 +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int RC2_INT; + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rc4.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rc4.h new file mode 100644 index 00000000..86803b37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rc4.h @@ -0,0 +1,36 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include + +# ifndef OPENSSL_NO_RC4 +# include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rc5.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rc5.h new file mode 100644 index 00000000..793f88e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rc5.h @@ -0,0 +1,63 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC5_H +# define HEADER_RC5_H + +# include + +# ifndef OPENSSL_NO_RC5 +# ifdef __cplusplus +extern "C" { +# endif + +# define RC5_ENCRYPT 1 +# define RC5_DECRYPT 0 + +# define RC5_32_INT unsigned int + +# define RC5_32_BLOCK 8 +# define RC5_32_KEY_LENGTH 16/* This is a default, max is 255 */ + +/* + * This are the only values supported. Tweak the code if you want more The + * most supported modes will be RC5-32/12/16 RC5-32/16/8 + */ +# define RC5_8_ROUNDS 8 +# define RC5_12_ROUNDS 12 +# define RC5_16_ROUNDS 16 + +typedef struct rc5_key_st { + /* Number of rounds */ + int rounds; + RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)]; +} RC5_32_KEY; + +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds); +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC5_32_KEY *key, int enc); +void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *ks, unsigned char *iv, + int enc); +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ripemd.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ripemd.h new file mode 100644 index 00000000..c42026aa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ripemd.h @@ -0,0 +1,47 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include + +#ifndef OPENSSL_NO_RMD160 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define RIPEMD160_LONG unsigned int + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rsa.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rsa.h new file mode 100644 index 00000000..5e76365c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rsa.h @@ -0,0 +1,513 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include + +# ifndef OPENSSL_NO_RSA +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* The types RSA and RSA_METHOD are defined in ossl_typ.h */ + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +/* based on RFC 8017 appendix A.1.2 */ +# define RSA_ASN1_VERSION_DEFAULT 0 +# define RSA_ASN1_VERSION_MULTI 1 + +# define RSA_DEFAULT_PRIME_NUM 2 + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0000 +# endif +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) +/* Salt length matches digest */ +# define RSA_PSS_SALTLEN_DIGEST -1 +/* Verify only: auto detect salt length */ +# define RSA_PSS_SALTLEN_AUTO -2 +/* Set salt length to maximum possible */ +# define RSA_PSS_SALTLEN_MAX -3 +/* Old compatible max salt length for sign only */ +# define RSA_PSS_SALTLEN_MAX_SIGN -2 + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes, NULL) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)(l)) + +# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)(l)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \ + EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, \ + 0, (void *)(md)) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES (EVP_PKEY_ALG_CTRL + 13) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_bits(const RSA *rsa); +int RSA_size(const RSA *rsa); +int RSA_security_bits(const RSA *rsa); + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r,BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], + BIGNUM *coeffs[], int pnum); +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +int RSA_get_multi_prime_extra_count(const RSA *r); +int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]); +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); +int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], + const BIGNUM *coeffs[]); +const BIGNUM *RSA_get0_n(const RSA *d); +const BIGNUM *RSA_get0_e(const RSA *d); +const BIGNUM *RSA_get0_d(const RSA *d); +const BIGNUM *RSA_get0_p(const RSA *d); +const BIGNUM *RSA_get0_q(const RSA *d); +const BIGNUM *RSA_get0_dmp1(const RSA *r); +const BIGNUM *RSA_get0_dmq1(const RSA *r); +const BIGNUM *RSA_get0_iqmp(const RSA *r); +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r); +void RSA_clear_flags(RSA *r, int flags); +int RSA_test_flags(const RSA *r, int flags); +void RSA_set_flags(RSA *r, int flags); +int RSA_get_version(RSA *r); +ENGINE *RSA_get0_engine(const RSA *r); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), + void *cb_arg)) + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +/* Multi-prime version */ +int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb); + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, + const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb); + +int RSA_check_key(const RSA *); +int RSA_check_key_ex(const RSA *, BN_GENCB *cb); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_null_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* these are the actual RSA functions */ +const RSA_METHOD *RSA_PKCS1_OpenSSL(void); + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + /* Decoded hash algorithm from maskGenAlgorithm */ + X509_ALGOR *maskHash; +}; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; + /* Decoded hash algorithm from maskGenFunc */ + X509_ALGOR *maskHash; +} RSA_OAEP_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_STDIO +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +int RSA_print(BIO *bp, const RSA *r, int offset); + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +#define RSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef) +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +RSA_METHOD *RSA_meth_new(const char *name, int flags); +void RSA_meth_free(RSA_METHOD *meth); +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +const char *RSA_meth_get0_name(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +int RSA_meth_get_flags(const RSA_METHOD *meth); +int RSA_meth_set_flags(RSA_METHOD *meth, int flags); +void *RSA_meth_get0_app_data(const RSA_METHOD *meth); +int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data); +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_enc(RSA_METHOD *rsa, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_dec(RSA_METHOD *rsa, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_enc(RSA_METHOD *rsa, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_dec(RSA_METHOD *rsa, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); +int RSA_meth_set_mod_exp(RSA_METHOD *rsa, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx)); +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx)); +int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa)); +int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa)); +int (*RSA_meth_get_sign(const RSA_METHOD *meth)) + (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); +int RSA_meth_set_sign(RSA_METHOD *rsa, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)); +int (*RSA_meth_get_verify(const RSA_METHOD *meth)) + (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +int RSA_meth_set_verify(RSA_METHOD *rsa, + int (*verify) (int dtype, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)); +int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_keygen(RSA_METHOD *rsa, + int (*keygen) (RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb)); +int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb)); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/rsaerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/rsaerr.h new file mode 100644 index 00000000..59b15e13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/rsaerr.h @@ -0,0 +1,167 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSAERR_H +# define HEADER_RSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RSA_strings(void); + +/* + * RSA function codes. + */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_ENCODE_PKCS1 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_PSS_INIT 165 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 149 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_ALGOR_TO_MD 156 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_CHECK_KEY_EX 160 +# define RSA_F_RSA_CMS_DECRYPT 159 +# define RSA_F_RSA_CMS_VERIFY 158 +# define RSA_F_RSA_ITEM_VERIFY 148 +# define RSA_F_RSA_METH_DUP 161 +# define RSA_F_RSA_METH_NEW 162 +# define RSA_F_RSA_METH_SET1_NAME 163 +# define RSA_F_RSA_MGF1_TO_MD 157 +# define RSA_F_RSA_MULTIP_INFO_NEW 166 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_OSSL_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_OSSL_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_OSSL_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 154 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 152 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 153 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PARAM_DECODE 164 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIV_DECODE 150 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PSS_GET_PARAM 151 +# define RSA_F_RSA_PSS_TO_CTX 155 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 126 +# define RSA_F_SETUP_TBUF 167 + +/* + * RSA reason codes. + */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_DOES_NOT_MATCH 158 +# define RSA_R_DIGEST_NOT_ALLOWED 145 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST 157 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_LABEL 160 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_MULTI_PRIME_KEY 167 +# define RSA_R_INVALID_OAEP_PARAMETERS 161 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_PRIME_NUM_INVALID 165 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MISSING_PRIVATE_KEY 179 +# define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 +# define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 +# define RSA_R_MP_R_NOT_PRIME 170 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_PSS_SALTLEN_TOO_SMALL 164 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_DIGEST 166 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 162 +# define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/safestack.h b/Hin2n/src/main/jniLibs/x86/include/openssl/safestack.h new file mode 100644 index 00000000..38b55789 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/safestack.h @@ -0,0 +1,207 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define STACK_OF(type) struct stack_st_##type + +# define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ + { \ + return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ + { \ + return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ + { \ + return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ + { \ + OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ + { \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ + sk_##t1##_copyfunc copyfunc, \ + sk_##t1##_freefunc freefunc) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \ + (OPENSSL_sk_copyfunc)copyfunc, \ + (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ + { \ + return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \ + } + +# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2) +# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) +# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \ + SKM_DEFINE_STACK_OF(t1, const t2, t2) +# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; +typedef const char *OPENSSL_CSTRING; + +/*- + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char) +DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_sk_num +# pragma weak OPENSSL_sk_value +# pragma weak OPENSSL_sk_new +# pragma weak OPENSSL_sk_new_null +# pragma weak OPENSSL_sk_new_reserve +# pragma weak OPENSSL_sk_reserve +# pragma weak OPENSSL_sk_free +# pragma weak OPENSSL_sk_zero +# pragma weak OPENSSL_sk_delete +# pragma weak OPENSSL_sk_delete_ptr +# pragma weak OPENSSL_sk_push +# pragma weak OPENSSL_sk_unshift +# pragma weak OPENSSL_sk_pop +# pragma weak OPENSSL_sk_shift +# pragma weak OPENSSL_sk_pop_free +# pragma weak OPENSSL_sk_insert +# pragma weak OPENSSL_sk_set +# pragma weak OPENSSL_sk_find +# pragma weak OPENSSL_sk_find_ex +# pragma weak OPENSSL_sk_sort +# pragma weak OPENSSL_sk_is_sorted +# pragma weak OPENSSL_sk_dup +# pragma weak OPENSSL_sk_deep_copy +# pragma weak OPENSSL_sk_set_cmp_func +# endif /* __SUNPRO_C */ + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/seed.h b/Hin2n/src/main/jniLibs/x86/include/openssl/seed.h new file mode 100644 index 00000000..de10b085 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/seed.h @@ -0,0 +1,96 @@ +/* + * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include + +# ifndef OPENSSL_NO_SEED +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# include + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/sha.h b/Hin2n/src/main/jniLibs/x86/include/openssl/sha.h new file mode 100644 index 00000000..6a1eb0de --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/sha.h @@ -0,0 +1,119 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define SHA_LONG unsigned int + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); + +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; + +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/srp.h b/Hin2n/src/main/jniLibs/x86/include/openssl/srp.h new file mode 100644 index 00000000..aaf13558 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/srp.h @@ -0,0 +1,135 @@ +/* + * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2004, EdelKey Project. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Christophe Renou and Peter Sylvester, + * for the EdelKey project. + */ + +#ifndef HEADER_SRP_H +# define HEADER_SRP_H + +#include + +#ifndef OPENSSL_NO_SRP +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DEFINE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +DEFINE_STACK_OF(SRP_user_pwd) + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + const BIGNUM *default_g; + const BIGNUM *default_N; +} SRP_VBASE; + +/* + * Internal structure storing N and g pair + */ +typedef struct SRP_gN_st { + char *id; + const BIGNUM *g; + const BIGNUM *N; +} SRP_gN; + +DEFINE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +void SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +DEPRECATEDIN_1_1_0(SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)) +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, + const BIGNUM *b, const BIGNUM *N); +BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v); +int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N); +BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g); +BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u); +int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/srtp.h b/Hin2n/src/main/jniLibs/x86/include/openssl/srtp.h new file mode 100644 index 00000000..0b57c235 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/srtp.h @@ -0,0 +1,50 @@ +/* + * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +/* AEAD SRTP protection profiles from RFC 7714 */ +# define SRTP_AEAD_AES_128_GCM 0x0007 +# define SRTP_AEAD_AES_256_GCM 0x0008 + +# ifndef OPENSSL_NO_SRTP + +__owur int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +__owur int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +__owur STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +__owur SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ssl.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl.h new file mode 100644 index 00000000..6724ccf2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl.h @@ -0,0 +1,2438 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif +# include +# include +# include +# include + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* OpenSSL version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* The maximum number of encrypt/decrypt pipelines we can support */ +# define SSL_MAX_PIPELINES 32 + +/* text strings for the ciphers */ + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr"/* this cipher class has been removed */ +# define SSL_TXT_kDHd "kDHd"/* this cipher class has been removed */ +# define SSL_TXT_kDH "kDH"/* this cipher class has been removed */ +# define SSL_TXT_kEDH "kEDH"/* alias for kDHE */ +# define SSL_TXT_kDHE "kDHE" +# define SSL_TXT_kECDHr "kECDHr"/* this cipher class has been removed */ +# define SSL_TXT_kECDHe "kECDHe"/* this cipher class has been removed */ +# define SSL_TXT_kECDH "kECDH"/* this cipher class has been removed */ +# define SSL_TXT_kEECDH "kEECDH"/* alias for kECDHE */ +# define SSL_TXT_kECDHE "kECDHE" +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kRSAPSK "kRSAPSK" +# define SSL_TXT_kECDHEPSK "kECDHEPSK" +# define SSL_TXT_kDHEPSK "kDHEPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDH "aECDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST12 "aGOST12" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_DHE "DHE"/* same as "kDHE:-ADH" */ +# define SSL_TXT_EDH "EDH"/* alias for DHE */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* alias for ECDHE" */ +# define SSL_TXT_ECDHE "ECDHE"/* same as "kECDHE:-AECDH" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_AES_CCM "AESCCM" +# define SSL_TXT_AES_CCM_8 "AESCCM8" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" +# define SSL_TXT_CHACHA20 "CHACHA20" +# define SSL_TXT_GOST "GOST89" +# define SSL_TXT_ARIA "ARIA" +# define SSL_TXT_ARIA_GCM "ARIAGCM" +# define SSL_TXT_ARIA128 "ARIA128" +# define SSL_TXT_ARIA256 "ARIA256" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_GOST12 "GOST12" +# define SSL_TXT_GOST89MAC12 "GOST89MAC12" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + * This applies to ciphersuites for TLSv1.2 and below. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL" +/* This is the default set of TLSv1.3 ciphersuites */ +# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_CHACHA20_POLY1305_SHA256:" \ + "TLS_AES_128_GCM_SHA256" +# else +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_AES_128_GCM_SHA256" +#endif +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; +typedef struct ssl_comp_st SSL_COMP; + +STACK_OF(SSL_CIPHER); +STACK_OF(SSL_COMP); + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg); + +/* Extension context codes */ +/* This extension is only allowed in TLS */ +#define SSL_EXT_TLS_ONLY 0x0001 +/* This extension is only allowed in DTLS */ +#define SSL_EXT_DTLS_ONLY 0x0002 +/* Some extensions may be allowed in DTLS but we don't implement them for it */ +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +/* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ +#define SSL_EXT_SSL3_ALLOWED 0x0008 +/* Extension is only defined for TLS1.2 and below */ +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +/* Extension is only defined for TLS1.3 and above */ +#define SSL_EXT_TLS1_3_ONLY 0x0020 +/* Ignore this extension during parsing if we are resuming */ +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 +#define SSL_EXT_CLIENT_HELLO 0x0080 +/* Really means TLS1.2 or below */ +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb)(SSL *s, unsigned int ext_type, + const unsigned char **out, size_t *outlen, + int *al, void *add_arg); + +typedef void (*custom_ext_free_cb)(SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb)(SSL *s, unsigned int ext_type, + const unsigned char *in, size_t inlen, + int *al, void *parse_arg); + + +typedef int (*SSL_custom_ext_add_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, + size_t *outlen, X509 *x, + size_t chainidx, + int *al, void *add_arg); + +typedef void (*SSL_custom_ext_free_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *out, + void *add_arg); + +typedef int (*SSL_custom_ext_parse_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *in, + size_t inlen, X509 *x, + size_t chainidx, + int *al, void *parse_arg); + +/* Typedef for verification callback */ +typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/* + * Some values are reserved until OpenSSL 1.2.0 because they were previously + * included in SSL_OP_ALL in a 1.1.x release. + * + * Reserved value (until OpenSSL 1.2.0) 0x00000001U + * Reserved value (until OpenSSL 1.2.0) 0x00000002U + */ +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U + +/* Reserved value (until OpenSSL 1.2.0) 0x00000008U */ +# define SSL_OP_TLSEXT_PADDING 0x00000010U +/* Reserved value (until OpenSSL 1.2.0) 0x00000020U */ +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U +/* + * Reserved value (until OpenSSL 1.2.0) 0x00000080U + * Reserved value (until OpenSSL 1.2.0) 0x00000100U + * Reserved value (until OpenSSL 1.2.0) 0x00000200U + */ + +/* In TLSv1.3 allow a non-(ec)dhe based kex_mode */ +# define SSL_OP_ALLOW_NO_DHE_KEX 0x00000400U + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. Added in 0.9.6e + */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800U + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000U +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000U +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000U +# ifndef OPENSSL_NO_DTLS1_METHOD +/* Use Cisco's "speshul" version of DTLS_BAD_VER + * (only with deprecated DTLSv1_client_method()) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# endif + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000U +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000U +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000U +/* Disable encrypt-then-mac */ +# define SSL_OP_NO_ENCRYPT_THEN_MAC 0x00080000U + +/* + * Enable TLSv1.3 Compatibility mode. This is on by default. A future version + * of OpenSSL may have this disabled by default. + */ +# define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0x00100000U + +/* Prioritize Chacha20Poly1305 when client does. + * Modifies SSL_OP_CIPHER_SERVER_PREFERENCE */ +# define SSL_OP_PRIORITIZE_CHACHA 0x00200000U + +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000U +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000U + +/* + * Switches off automatic TLSv1.3 anti-replay protection for early data. This + * is a server-side option only (no effect on the client). + */ +# define SSL_OP_NO_ANTI_REPLAY 0x01000000U + +# define SSL_OP_NO_SSLv3 0x02000000U +# define SSL_OP_NO_TLSv1 0x04000000U +# define SSL_OP_NO_TLSv1_2 0x08000000U +# define SSL_OP_NO_TLSv1_1 0x10000000U +# define SSL_OP_NO_TLSv1_3 0x20000000U + +# define SSL_OP_NO_DTLSv1 0x04000000U +# define SSL_OP_NO_DTLSv1_2 0x08000000U + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +# define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) + +/* Disallow all renegotiation */ +# define SSL_OP_NO_RENEGOTIATION 0x40000000U + +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000U + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. + * This used to be 0x80000BFFU before 1.1.1. + */ +# define SSL_OP_ALL (SSL_OP_CRYPTOPRO_TLSEXT_BUG|\ + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS|\ + SSL_OP_LEGACY_SERVER_CONNECT|\ + SSL_OP_TLSEXT_PADDING|\ + SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + +/* OBSOLETE OPTIONS: retained for compatibility */ + +/* Removed from OpenSSL 1.1.0. Was 0x00000001L */ +/* Related to removed SSLv2. */ +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000002L */ +/* Related to removed SSLv2. */ +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +/* Removed from OpenSSL 0.9.8q and 1.0.0c. Was 0x00000008L */ +/* Dead forever, see CVE-2010-4180 */ +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +/* Removed from OpenSSL 1.0.1h and 1.0.2. Was 0x00000010L */ +/* Refers to ancient SSLREF and SSLv2. */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000020 */ +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +/* Removed from OpenSSL 0.9.7h and 0.9.8b. Was 0x00000040L */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000080 */ +/* Ancient SSLeay version. */ +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000100L */ +# define SSL_OP_TLS_D5_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000200L */ +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00080000L */ +# define SSL_OP_SINGLE_ECDH_USE 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00100000L */ +# define SSL_OP_SINGLE_DH_USE 0x0 +/* Removed from OpenSSL 1.0.1k and 1.0.2. Was 0x00200000L */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x01000000L */ +# define SSL_OP_NO_SSLv2 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x08000000L */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x10000000L */ +# define SSL_OP_PKCS1_CHECK_2 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x20000000L */ +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x40000000L */ +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001U +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004U +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008U +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) Released buffers are freed. + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010U +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020U +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040U +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U +/* + * Support Asynchronous operation + */ +# define SSL_MODE_ASYNC 0x00000100U + +/* + * When using DTLS/SCTP, include the terminating zero in the label + * used for computing the endpoint-pair shared secret. Required for + * interoperability with implementations having this bug like these + * older version of OpenSSL: + * - OpenSSL 1.0.0 series + * - OpenSSL 1.0.1 series + * - OpenSSL 1.0.2 series + * - OpenSSL 1.1.0 series + * - OpenSSL 1.1.1 and 1.1.1a + */ +# define SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certificate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001U + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +# define SSL_CONF_FLAG_REQUIRE_PRIVATE 0x40 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 +# define SSL_CONF_TYPE_NONE 0x4 + +/* Maximum length of the application-controlled segment of a a TLSv1.3 cookie */ +# define SSL_COOKIE_LENGTH 4096 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +unsigned long SSL_CTX_get_options(const SSL_CTX *ctx); +unsigned long SSL_get_options(const SSL *s); +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_clear_options(SSL *s, unsigned long op); +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_set_options(SSL *s, unsigned long op); + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# define SSL_get_extms_support(s) \ + SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL) + +# ifndef OPENSSL_NO_SRP + +/* see tls_srp.c */ +__owur int SSL_SRP_CTX_init(SSL *s); +__owur int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +__owur int SSL_srp_server_param_with_username(SSL *s, int *ad); +__owur int SRP_Calc_A_param(SSL *s); + +# endif + +/* 100k max cert list */ +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv3/TLSv1 it is 32 + * bytes. The callback can alter this length to be less if desired. It is + * also an error for the callback to set the size to zero. + */ +typedef int (*GEN_SESSION_CB) (SSL *ssl, unsigned char *id, + unsigned int *id_len); + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + const unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + const unsigned char *data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +__owur int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + const unsigned + char *cookie, + unsigned int + cookie_len)); + +void SSL_CTX_set_stateless_cookie_generate_cb( + SSL_CTX *ctx, + int (*gen_stateless_cookie_cb) (SSL *ssl, + unsigned char *cookie, + size_t *cookie_len)); +void SSL_CTX_set_stateless_cookie_verify_cb( + SSL_CTX *ctx, + int (*verify_stateless_cookie_cb) (SSL *ssl, + const unsigned char *cookie, + size_t cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG + +typedef int (*SSL_CTX_npn_advertised_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned int *outlen, + void *arg); +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + SSL_CTX_npn_advertised_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_advertised_cb SSL_CTX_set_next_protos_advertised_cb + +typedef int (*SSL_CTX_npn_select_cb_func)(SSL *s, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + SSL_CTX_npn_select_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_select_cb SSL_CTX_set_next_proto_select_cb + +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# define SSL_get0_npn_negotiated SSL_get0_next_proto_negotiated +# endif + +__owur int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +__owur int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +typedef int (*SSL_CTX_alpn_select_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + SSL_CTX_alpn_select_cb_func cb, + void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); +void SSL_set_psk_client_callback(SSL *ssl, SSL_psk_client_cb_func cb); + +typedef unsigned int (*SSL_psk_server_cb_func)(SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb); +void SSL_set_psk_server_callback(SSL *ssl, SSL_psk_server_cb_func cb); + +__owur int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +__owur int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +typedef int (*SSL_psk_find_session_cb_func)(SSL *ssl, + const unsigned char *identity, + size_t identity_len, + SSL_SESSION **sess); +typedef int (*SSL_psk_use_session_cb_func)(SSL *ssl, const EVP_MD *md, + const unsigned char **id, + size_t *idlen, + SSL_SESSION **sess); + +void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb); +void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, + SSL_psk_find_session_cb_func cb); +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb); +void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, + SSL_psk_use_session_cb_func cb); + +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +__owur int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, + unsigned int ext_type); + +__owur int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg); + +__owur int SSL_extension_supported(unsigned int ext_type); + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 +# define SSL_ASYNC_PAUSED 5 +# define SSL_ASYNC_NO_JOBS 6 +# define SSL_CLIENT_HELLO_CB 7 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) +# define SSL_want_async(s) (SSL_want(s) == SSL_ASYNC_PAUSED) +# define SSL_want_async_job(s) (SSL_want(s) == SSL_ASYNC_NO_JOBS) +# define SSL_want_client_hello_cb(s) (SSL_want(s) == SSL_CLIENT_HELLO_CB) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +/* + * A callback for logging out TLS key material. This callback should log out + * |line| followed by a newline. + */ +typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line); + +/* + * SSL_CTX_set_keylog_callback configures a callback to log key material. This + * is intended for debugging use with tools like Wireshark. The cb function + * should log line followed by a newline. + */ +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); + +/* + * SSL_CTX_get_keylog_callback returns the callback configured by + * SSL_CTX_set_keylog_callback. + */ +SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); +uint32_t SSL_get_max_early_data(const SSL *s); +int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data); +uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx); +int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data); +uint32_t SSL_get_recv_max_early_data(const SSL *s); + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These need to be after the above set of includes due to a compiler bug + * in VisualStudio 2015 + */ +DEFINE_STACK_OF_CONST(SSL_CIPHER) +DEFINE_STACK_OF(SSL_COMP) + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)(arg))) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0, \ + (char *)(a))) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0, \ + (char *)(arg))) +DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug)) + +/* TLSv1.3 KeyUpdate message types */ +/* -1 used so that this is an invalid value for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NONE -1 +/* Values as defined for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +/* + * The valid handshake states (one for each type message sent and one for each + * type of message received). There are also two "special" states: + * TLS = TLS or DTLS state + * DTLS = DTLS specific state + * CR/SR = Client Read/Server Read + * CW/SW = Client Write/Server Write + * + * The "special" states are: + * TLS_ST_BEFORE = No handshake has been initiated yet + * TLS_ST_OK = A handshake has been successfully completed + */ +typedef enum { + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED, + TLS_ST_SW_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_CERT_VRFY, + TLS_ST_SW_CERT_VRFY, + TLS_ST_CR_HELLO_REQ, + TLS_ST_SW_KEY_UPDATE, + TLS_ST_CW_KEY_UPDATE, + TLS_ST_SR_KEY_UPDATE, + TLS_ST_CR_KEY_UPDATE, + TLS_ST_EARLY_DATA, + TLS_ST_PENDING_EARLY_DATA_END, + TLS_ST_CW_END_OF_EARLY_DATA, + TLS_ST_SR_END_OF_EARLY_DATA +} OSSL_HANDSHAKE_STATE; + +/* + * Most of the following state values are no longer used and are defined to be + * the closest equivalent value in the current state machine code. Not all + * defines have an equivalent and are set to a dummy value (-1). SSL_ST_CONNECT + * and SSL_ST_ACCEPT are still in use in the definition of SSL_CB_ACCEPT_LOOP, + * SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP and SSL_CB_CONNECT_EXIT. + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 + +# define SSL_ST_MASK 0x0FFF + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_in_connect_init(a) (SSL_in_init(a) && !SSL_is_server(a)) +# define SSL_in_accept_init(a) (SSL_in_init(a) && SSL_is_server(a)) +int SSL_in_init(const SSL *s); +int SSL_in_before(const SSL *s); +int SSL_is_init_finished(const SSL *s); + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 +# define SSL_VERIFY_POST_HANDSHAKE 0x08 + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() +# endif + +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION +# define SSL_AD_CERTIFICATE_REQUIRED TLS13_AD_CERTIFICATE_REQUIRED +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_ERROR_WANT_ASYNC 9 +# define SSL_ERROR_WANT_ASYNC_JOB 10 +# define SSL_ERROR_WANT_CLIENT_HELLO_CB 11 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 */ +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB 79 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_GROUPS 90 +# define SSL_CTRL_SET_GROUPS 91 +# define SSL_CTRL_SET_GROUPS_LIST 92 +# define SSL_CTRL_GET_SHARED_GROUP 93 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_PEER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_SET_DH_AUTO 118 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CTRL_GET_EXTMS_SUPPORT 122 +# define SSL_CTRL_SET_MIN_PROTO_VERSION 123 +# define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +# define SSL_CTRL_SET_SPLIT_SEND_FRAGMENT 125 +# define SSL_CTRL_SET_MAX_PIPELINES 126 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE 127 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB 128 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129 +# define SSL_CTRL_GET_MIN_PROTO_VERSION 130 +# define SSL_CTRL_GET_MAX_PROTO_VERSION 131 +# define SSL_CTRL_GET_SIGNATURE_NID 132 +# define SSL_CTRL_GET_TMP_KEY 133 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)(arg)) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_set1_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_add0_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_add1_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_get0_chain_certs(s,px509) \ + SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(s) \ + SSL_set0_chain(s,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_set_current_cert(s,op) \ + SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_get1_groups(s, glist) \ + SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_CTX_set1_groups(ctx, glist, glistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_CTX_set1_groups_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s)) +# define SSL_set1_groups(s, glist, glistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_set1_groups_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str)) +# define SSL_get_shared_group(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str)) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_client_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_client_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str)) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist)) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen, \ + (char *)(clist)) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)(clist)) +# define SSL_get_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_SIGNATURE_NID,0,pn) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_peer_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_TMP_KEY,0,pk) +# define SSL_get_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,plst) +# define SSL_CTX_set_min_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_CTX_set_max_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_CTX_get_min_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_CTX_get_max_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +# define SSL_set_min_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_set_max_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_get_min_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_get_max_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) + +/* Backwards compatibility, original 1.1.0 names */ +# define SSL_CTRL_GET_SERVER_TMP_KEY \ + SSL_CTRL_GET_PEER_TMP_KEY +# define SSL_get_server_tmp_key(s, pk) \ + SSL_get_peer_tmp_key(s, pk) + +/* + * The following symbol names are old and obsolete. They are kept + * for compatibility reasons only and should not be used anymore. + */ +# define SSL_CTRL_GET_CURVES SSL_CTRL_GET_GROUPS +# define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS +# define SSL_CTRL_SET_CURVES_LIST SSL_CTRL_SET_GROUPS_LIST +# define SSL_CTRL_GET_SHARED_CURVE SSL_CTRL_GET_SHARED_GROUP + +# define SSL_get1_curves SSL_get1_groups +# define SSL_CTX_set1_curves SSL_CTX_set1_groups +# define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +# define SSL_set1_curves SSL_set1_groups +# define SSL_set1_curves_list SSL_set1_groups_list +# define SSL_get_shared_curve SSL_get_shared_group + + +# if OPENSSL_API_COMPAT < 0x10100000L +/* Provide some compatibility macros for removed functionality. */ +# define SSL_CTX_need_tmp_RSA(ctx) 0 +# define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +# define SSL_need_tmp_RSA(ssl) 0 +# define SSL_set_tmp_rsa(ssl,rsa) 1 +# define SSL_CTX_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +# define SSL_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +/* + * We "pretend" to call the callback to avoid warnings about unused static + * functions. + */ +# define SSL_CTX_set_tmp_rsa_callback(ctx, cb) while(0) (cb)(NULL, 0, 0) +# define SSL_set_tmp_rsa_callback(ssl, cb) while(0) (cb)(NULL, 0, 0) +# endif +__owur const BIO_METHOD *BIO_f_ssl(void); +__owur BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +__owur BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +__owur BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +__owur int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +__owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +__owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +int SSL_CTX_up_ref(SSL_CTX *ctx); +void SSL_CTX_free(SSL_CTX *); +__owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +__owur long SSL_CTX_get_timeout(const SSL_CTX *ctx); +__owur X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +void SSL_CTX_set1_cert_store(SSL_CTX *, X509_STORE *); +__owur int SSL_want(const SSL *s); +__owur int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +__owur const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +__owur const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s); +__owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +__owur const char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +__owur const char *OPENSSL_cipher_name(const char *rfc_name); +__owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); +__owur uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +__owur const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c); +__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c); + +__owur int SSL_get_fd(const SSL *s); +__owur int SSL_get_rfd(const SSL *s); +__owur int SSL_get_wfd(const SSL *s); +__owur const char *SSL_get_cipher_list(const SSL *s, int n); +__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); +__owur int SSL_get_read_ahead(const SSL *s); +__owur int SSL_pending(const SSL *s); +__owur int SSL_has_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +__owur int SSL_set_fd(SSL *s, int fd); +__owur int SSL_set_rfd(SSL *s, int fd); +__owur int SSL_set_wfd(SSL *s, int fd); +# endif +void SSL_set0_rbio(SSL *s, BIO *rbio); +void SSL_set0_wbio(SSL *s, BIO *wbio); +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +__owur BIO *SSL_get_rbio(const SSL *s); +__owur BIO *SSL_get_wbio(const SSL *s); +__owur int SSL_set_cipher_list(SSL *s, const char *str); +__owur int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +__owur int SSL_set_ciphersuites(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +__owur int SSL_get_verify_mode(const SSL *s); +__owur int SSL_get_verify_depth(const SSL *s); +__owur SSL_verify_cb SSL_get_verify_callback(const SSL *s); +void SSL_set_verify(SSL *s, int mode, SSL_verify_cb callback); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +__owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, + long len); +# endif +__owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +__owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +__owur int SSL_use_certificate(SSL *ssl, X509 *x); +__owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +__owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + + +/* serverinfo file format versions */ +# define SSL_SERVERINFOV1 1 +# define SSL_SERVERINFOV2 2 + +/* Set serverinfo data for the current active cert. */ +__owur int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, + const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +#endif + +__owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +__owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +#endif +__owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +__owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +/* PEM type */ +__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file); +__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_load_error_strings() \ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \ + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# endif + +__owur const char *SSL_state_string(const SSL *s); +__owur const char *SSL_rstate_string(const SSL *s); +__owur const char *SSL_state_string_long(const SSL *s); +__owur const char *SSL_rstate_string_long(const SSL *s); +__owur long SSL_SESSION_get_time(const SSL_SESSION *s); +__owur long SSL_SESSION_set_time(SSL_SESSION *s, long t); +__owur long SSL_SESSION_get_timeout(const SSL_SESSION *s); +__owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +__owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); +__owur int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version); + +__owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s); +__owur int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname); +void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, + const unsigned char **alpn, + size_t *len); +__owur int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, + const unsigned char *alpn, + size_t len); +__owur const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s); +__owur int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher); +__owur int SSL_SESSION_has_ticket(const SSL_SESSION *s); +__owur unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s); +void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick, + size_t *len); +__owur uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s); +__owur int SSL_SESSION_set_max_early_data(SSL_SESSION *s, + uint32_t max_early_data); +__owur int SSL_copy_session_id(SSL *to, const SSL *from); +__owur X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +__owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); +__owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len); +__owur int SSL_SESSION_is_resumable(const SSL_SESSION *s); + +__owur SSL_SESSION *SSL_SESSION_new(void); +__owur SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s, + unsigned int *len); +__owur unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_STDIO +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); +int SSL_SESSION_up_ref(SSL_SESSION *ses); +void SSL_SESSION_free(SSL_SESSION *ses); +__owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +__owur int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); +__owur int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); +__owur int SSL_set_generate_session_id(SSL *s, GEN_SESSION_CB cb); +__owur int SSL_has_matching_session_id(const SSL *s, + const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +__owur X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +__owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +__owur int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +__owur int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +__owur SSL_verify_cb SSL_CTX_get_verify_callback(const SSL_CTX *ctx); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +__owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +# endif +__owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +__owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +__owur int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +__owur int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); +__owur int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); +pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx); +void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx); +void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb); +void SSL_set_default_passwd_cb_userdata(SSL *s, void *u); +pem_password_cb *SSL_get_default_passwd_cb(SSL *s); +void *SSL_get_default_passwd_cb_userdata(SSL *s); + +__owur int SSL_CTX_check_private_key(const SSL_CTX *ctx); +__owur int SSL_check_private_key(const SSL *ctx); + +__owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_up_ref(SSL *s); +int SSL_is_dtls(const SSL *s); +__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +__owur int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); +__owur int SSL_set_purpose(SSL *ssl, int purpose); +__owur int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); +__owur int SSL_set_trust(SSL *ssl, int trust); + +__owur int SSL_set1_host(SSL *s, const char *hostname); +__owur int SSL_add1_host(SSL *s, const char *hostname); +__owur const char *SSL_get0_peername(SSL *s); +void SSL_set_hostflags(SSL *s, unsigned int flags); + +__owur int SSL_CTX_dane_enable(SSL_CTX *ctx); +__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, + uint8_t mtype, uint8_t ord); +__owur int SSL_dane_enable(SSL *s, const char *basedomain); +__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, + uint8_t mtype, unsigned const char *data, size_t dlen); +__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki); +__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, + uint8_t *mtype, unsigned const char **data, + size_t *dlen); +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +SSL_DANE *SSL_get0_dane(SSL *ssl); +/* + * DANE flags + */ +unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags); +unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags); + +__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +__owur X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +__owur X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +__owur BIGNUM *SSL_get_srp_g(SSL *s); +__owur BIGNUM *SSL_get_srp_N(SSL *s); + +__owur char *SSL_get_srp_username(SSL *s); +__owur char *SSL_get_srp_userinfo(SSL *s); +# endif + +/* + * ClientHello callback and helpers. + */ + +# define SSL_CLIENT_HELLO_SUCCESS 1 +# define SSL_CLIENT_HELLO_ERROR 0 +# define SSL_CLIENT_HELLO_RETRY (-1) + +typedef int (*SSL_client_hello_cb_fn) (SSL *s, int *al, void *arg); +void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb, + void *arg); +int SSL_client_hello_isv2(SSL *s); +unsigned int SSL_client_hello_get0_legacy_version(SSL *s); +size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_compression_methods(SSL *s, + const unsigned char **out); +int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get0_ext(SSL *s, unsigned int type, + const unsigned char **out, size_t *outlen); + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +# ifdef OSSL_ASYNC_FD +/* + * Windows application developer has to include windows.h to use these. + */ +__owur int SSL_waiting_for_async(SSL *s); +__owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); +__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +# endif +__owur int SSL_accept(SSL *ssl); +__owur int SSL_stateless(SSL *s); +__owur int SSL_connect(SSL *ssl); +__owur int SSL_read(SSL *ssl, void *buf, int num); +__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); + +# define SSL_READ_EARLY_DATA_ERROR 0 +# define SSL_READ_EARLY_DATA_SUCCESS 1 +# define SSL_READ_EARLY_DATA_FINISH 2 + +__owur int SSL_read_early_data(SSL *s, void *buf, size_t num, + size_t *readbytes); +__owur int SSL_peek(SSL *ssl, void *buf, int num); +__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); +__owur int SSL_write(SSL *ssl, const void *buf, int num); +__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); +__owur int SSL_write_early_data(SSL *s, const void *buf, size_t num, + size_t *written); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +# define SSL_EARLY_DATA_NOT_SENT 0 +# define SSL_EARLY_DATA_REJECTED 1 +# define SSL_EARLY_DATA_ACCEPTED 2 + +__owur int SSL_get_early_data_status(const SSL *s); + +__owur int SSL_get_error(const SSL *s, int ret_code); +__owur const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL3_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_client_method(void)) +# endif + +#define SSLv23_method TLS_method +#define SSLv23_server_method TLS_server_method +#define SSLv23_client_method TLS_client_method + +/* Negotiate highest available SSL/TLS version */ +__owur const SSL_METHOD *TLS_method(void); +__owur const SSL_METHOD *TLS_server_method(void); +__owur const SSL_METHOD *TLS_client_method(void); + +# ifndef OPENSSL_NO_TLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_2_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_2_METHOD +/* DTLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) +# endif + +__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +__owur size_t DTLS_get_data_mtu(const SSL *s); + +__owur STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); +__owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s); + +__owur int SSL_do_handshake(SSL *s); +int SSL_key_update(SSL *s, int updatetype); +int SSL_get_key_update_type(const SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +__owur int SSL_renegotiate_pending(const SSL *s); +int SSL_shutdown(SSL *s); +__owur int SSL_verify_client_post_handshake(SSL *s); +void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val); +void SSL_set_post_handshake_auth(SSL *s, int val); + +__owur const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx); +__owur const SSL_METHOD *SSL_get_ssl_method(const SSL *s); +__owur int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +__owur const char *SSL_alert_type_string_long(int value); +__owur const char *SSL_alert_type_string(int value); +__owur const char *SSL_alert_desc_string_long(int value); +__owur const char *SSL_alert_desc_string(int value); + +void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s); +__owur const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx); +__owur int SSL_add1_to_CA_list(SSL *ssl, const X509 *x); +__owur int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x); +__owur const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +__owur STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +__owur int SSL_add_client_CA(SSL *ssl, X509 *x); +__owur int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +__owur long SSL_get_default_timeout(const SSL *s); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_library_init() OPENSSL_init_ssl(0, NULL) +# endif + +__owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk); + +__owur SSL *SSL_dup(SSL *ssl); + +__owur X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ +struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +__owur X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +__owur EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +__owur int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +__owur int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +__owur int SSL_get_shutdown(const SSL *ssl); +__owur int SSL_version(const SSL *ssl); +__owur int SSL_client_version(const SSL *s); +__owur int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); +__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +__owur SSL_SESSION *SSL_get_session(const SSL *ssl); +__owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +__owur SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +__owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +void SSL_set_verify_result(SSL *ssl, long v); +__owur long SSL_get_verify_result(const SSL *ssl); +__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s); + +__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_SESSION_get_master_key(const SSL_SESSION *sess, + unsigned char *out, size_t outlen); +__owur int SSL_SESSION_set1_master_key(SSL_SESSION *sess, + const unsigned char *in, size_t len); +uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *sess); + +#define SSL_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef) +__owur int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +#define SSL_SESSION_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, l, p, newf, dupf, freef) +__owur int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +#define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) +__owur int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); + +__owur int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_split_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_set_split_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_max_pipelines(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) +# define SSL_set_max_pipelines(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) + +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); +void SSL_set_default_read_buffer_len(SSL *s, size_t len); + +# ifndef OPENSSL_NO_DH +/* NB: the |keylength| is only applicable when is_export is true */ +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif + +__owur const COMP_METHOD *SSL_get_current_compression(const SSL *s); +__owur const COMP_METHOD *SSL_get_current_expansion(const SSL *s); +__owur const char *SSL_COMP_get_name(const COMP_METHOD *comp); +__owur const char *SSL_COMP_get0_name(const SSL_COMP *comp); +__owur int SSL_COMP_get_id(const SSL_COMP *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +__owur STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_COMP_free_compression_methods() while(0) continue +# endif +__owur int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); +int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, + int isv2format, STACK_OF(SSL_CIPHER) **sk, + STACK_OF(SSL_CIPHER) **scsvs); + +/* TLS extensions functions */ +__owur int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +__owur int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +__owur int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn session_secret_cb, + void *arg); + +void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + int + is_forward_secure)); + +void SSL_set_not_resumable_session_callback(SSL *ssl, + int (*cb) (SSL *ssl, + int is_forward_secure)); + +void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); +void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); +int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); + +void SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); +void *SSL_get_record_padding_callback_arg(const SSL *ssl); +int SSL_set_block_padding(SSL *ssl, size_t block_size); + +int SSL_set_num_tickets(SSL *s, size_t num_tickets); +size_t SSL_get_num_tickets(const SSL *s); +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_cache_hit(s) SSL_session_reused(s) +# endif + +__owur int SSL_session_reused(const SSL *s); +__owur int SSL_is_server(const SSL *s); + +__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +__owur unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, + unsigned int flags); +__owur int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +__owur int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +__owur int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +__owur int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +void SSL_add_ssl_module(void); +int SSL_config(SSL *s, const char *name); +int SSL_CTX_config(SSL_CTX *ctx, const char *name); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +# endif + +# ifndef OPENSSL_NO_SOCK +int DTLSv1_listen(SSL *s, BIO_ADDR *client); +# endif + +# ifndef OPENSSL_NO_CT + +/* + * A callback for verifying that the received SCTs are sufficient. + * Expected to return 1 if they are sufficient, otherwise 0. + * May return a negative integer if an error occurs. + * A connection should be aborted if the SCTs are deemed insufficient. + */ +typedef int (*ssl_ct_validation_cb)(const CT_POLICY_EVAL_CTX *ctx, + const STACK_OF(SCT) *scts, void *arg); + +/* + * Sets a |callback| that is invoked upon receipt of ServerHelloDone to validate + * the received SCTs. + * If the callback returns a non-positive result, the connection is terminated. + * Call this function before beginning a handshake. + * If a NULL |callback| is provided, SCT validation is disabled. + * |arg| is arbitrary userdata that will be passed to the callback whenever it + * is invoked. Ownership of |arg| remains with the caller. + * + * NOTE: A side-effect of setting a CT callback is that an OCSP stapled response + * will be requested. + */ +int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, + void *arg); +int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, + ssl_ct_validation_cb callback, + void *arg); +#define SSL_disable_ct(s) \ + ((void) SSL_set_validation_callback((s), NULL, NULL)) +#define SSL_CTX_disable_ct(ctx) \ + ((void) SSL_CTX_set_validation_callback((ctx), NULL, NULL)) + +/* + * The validation type enumerates the available behaviours of the built-in SSL + * CT validation callback selected via SSL_enable_ct() and SSL_CTX_enable_ct(). + * The underlying callback is a static function in libssl. + */ +enum { + SSL_CT_VALIDATION_PERMISSIVE = 0, + SSL_CT_VALIDATION_STRICT +}; + +/* + * Enable CT by setting up a callback that implements one of the built-in + * validation variants. The SSL_CT_VALIDATION_PERMISSIVE variant always + * continues the handshake, the application can make appropriate decisions at + * handshake completion. The SSL_CT_VALIDATION_STRICT variant requires at + * least one valid SCT, or else handshake termination will be requested. The + * handshake may continue anyway if SSL_VERIFY_NONE is in effect. + */ +int SSL_enable_ct(SSL *s, int validation_mode); +int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode); + +/* + * Report whether a non-NULL callback is enabled. + */ +int SSL_ct_is_enabled(const SSL *s); +int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx); + +/* Gets the SCTs received from a connection */ +const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s); + +/* + * Loads the CT log list from the default location. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx); + +/* + * Loads the CT log list from the specified file path. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path); + +/* + * Sets the CT log list used by all SSL connections created from this SSL_CTX. + * Ownership of the CTLOG_STORE is transferred to the SSL_CTX. + */ +void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs); + +/* + * Gets the CT log list used by all SSL connections created from this SSL_CTX. + * This will be NULL unless one of the following functions has been called: + * - SSL_CTX_set_default_ctlog_list_file + * - SSL_CTX_set_ctlog_list_file + * - SSL_CTX_set_ctlog_store + */ +const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx); + +# endif /* OPENSSL_NO_CT */ + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +# define SSL_SECOP_OTHER_TYPE 0xffff0000 +# define SSL_SECOP_OTHER_NONE 0 +# define SSL_SECOP_OTHER_CIPHER (1 << 16) +# define SSL_SECOP_OTHER_CURVE (2 << 16) +# define SSL_SECOP_OTHER_DH (3 << 16) +# define SSL_SECOP_OTHER_PKEY (4 << 16) +# define SSL_SECOP_OTHER_SIGALG (5 << 16) +# define SSL_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +# define SSL_SECOP_PEER 0x1000 + +/* Values for "op" parameter in security callback */ + +/* Called to filter ciphers */ +/* Ciphers client supports */ +# define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +# define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +# define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +# define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +# define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +# define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE) +/* Temporary DH key */ +# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_PKEY) +/* SSL/TLS version */ +# define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE) +/* Session tickets */ +# define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +# define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +# define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +# define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +# define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +# define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE) +/* EE key in certificate */ +# define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT) +/* CA key in certificate */ +# define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +# define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +# define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER) +/* Peer CA key in certificate */ +# define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +# define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER) + +void SSL_set_security_level(SSL *s, int level); +__owur int SSL_get_security_level(const SSL *s); +void SSL_set_security_callback(SSL *s, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, + const SSL_CTX *ctx, int op, + int bits, int nid, void *other, + void *ex); +void SSL_set0_security_ex_data(SSL *s, void *ex); +__owur void *SSL_get0_security_ex_data(const SSL *s); + +void SSL_CTX_set_security_level(SSL_CTX *ctx, int level); +__owur int SSL_CTX_get_security_level(const SSL_CTX *ctx); +void SSL_CTX_set_security_callback(SSL_CTX *ctx, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s, + const SSL_CTX *ctx, + int op, int bits, + int nid, + void *other, + void *ex); +void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex); +__owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx); + +/* OPENSSL_INIT flag 0x010000 reserved for internal use */ +# define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L +# define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L + +# define OPENSSL_INIT_SSL_DEFAULT \ + (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS) + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + +# ifndef OPENSSL_NO_UNIT_TEST +__owur const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +__owur int SSL_free_buffers(SSL *ssl); +__owur int SSL_alloc_buffers(SSL *ssl); + +/* Status codes passed to the decrypt session ticket callback. Some of these + * are for internal use only and are never passed to the callback. */ +typedef int SSL_TICKET_STATUS; + +/* Support for ticket appdata */ +/* fatal error, malloc failure */ +# define SSL_TICKET_FATAL_ERR_MALLOC 0 +/* fatal error, either from parsing or decrypting the ticket */ +# define SSL_TICKET_FATAL_ERR_OTHER 1 +/* No ticket present */ +# define SSL_TICKET_NONE 2 +/* Empty ticket present */ +# define SSL_TICKET_EMPTY 3 +/* the ticket couldn't be decrypted */ +# define SSL_TICKET_NO_DECRYPT 4 +/* a ticket was successfully decrypted */ +# define SSL_TICKET_SUCCESS 5 +/* same as above but the ticket needs to be renewed */ +# define SSL_TICKET_SUCCESS_RENEW 6 + +/* Return codes for the decrypt session ticket callback */ +typedef int SSL_TICKET_RETURN; + +/* An error occurred */ +#define SSL_TICKET_RETURN_ABORT 0 +/* Do not use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE 1 +/* Do not use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE_RENEW 2 +/* Use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE 3 +/* Use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE_RENEW 4 + +typedef int (*SSL_CTX_generate_session_ticket_fn)(SSL *s, void *arg); +typedef SSL_TICKET_RETURN (*SSL_CTX_decrypt_session_ticket_fn)(SSL *s, SSL_SESSION *ss, + const unsigned char *keyname, + size_t keyname_length, + SSL_TICKET_STATUS status, + void *arg); +int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx, + SSL_CTX_generate_session_ticket_fn gen_cb, + SSL_CTX_decrypt_session_ticket_fn dec_cb, + void *arg); +int SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len); +int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len); + +extern const char SSL_version_str[]; + +typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us); + +void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb); + + +typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg); +void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx, + SSL_allow_early_data_cb_fn cb, + void *arg); +void SSL_set_allow_early_data_cb(SSL *s, + SSL_allow_early_data_cb_fn cb, + void *arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ssl2.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl2.h new file mode 100644 index 00000000..5321bd27 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl2.h @@ -0,0 +1,24 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL2_VERSION 0x0002 + +# define SSL2_MT_CLIENT_HELLO 1 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ssl3.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl3.h new file mode 100644 index 00000000..8d01fcc4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ssl3.h @@ -0,0 +1,339 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA SSL3_CK_DHE_DSS_DES_40_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA SSL3_CK_DHE_DSS_DES_64_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA SSL3_CK_DHE_DSS_DES_192_CBC3_SHA +# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA SSL3_CK_DHE_RSA_DES_40_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA SSL3_CK_DHE_RSA_DES_64_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA 0x03000016 +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA SSL3_CK_DHE_RSA_DES_192_CBC3_SHA + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define SSL3_RFC_RSA_NULL_MD5 "TLS_RSA_WITH_NULL_MD5" +# define SSL3_RFC_RSA_NULL_SHA "TLS_RSA_WITH_NULL_SHA" +# define SSL3_RFC_RSA_DES_192_CBC3_SHA "TLS_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_DSS_DES_192_CBC3_SHA "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_RSA_DES_192_CBC3_SHA "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_ADH_DES_192_CBC_SHA "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_RSA_IDEA_128_SHA "TLS_RSA_WITH_IDEA_CBC_SHA" +# define SSL3_RFC_RSA_RC4_128_MD5 "TLS_RSA_WITH_RC4_128_MD5" +# define SSL3_RFC_RSA_RC4_128_SHA "TLS_RSA_WITH_RC4_128_SHA" +# define SSL3_RFC_ADH_RC4_128_MD5 "TLS_DH_anon_WITH_RC4_128_MD5" + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" + +/* + * This next block of six "EDH" labels is for backward compatibility with + * older versions of OpenSSL. New code should use the six "DHE" labels above + * instead: + */ +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD 256 + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define DTLS1_RT_HEARTBEAT 24 + +/* Pseudo content types to indicate additional parameters */ +# define TLS1_RT_CRYPTO 0x1000 +# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) +# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) +# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) +# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) + +# define TLS1_RT_CRYPTO_READ 0x0000 +# define TLS1_RT_CRYPTO_WRITE 0x0100 +# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) +# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) +# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) +# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) + +/* Pseudo content types for SSL/TLS header info */ +# define SSL3_RT_HEADER 0x100 +# define SSL3_RT_INNER_CONTENT_TYPE 0x101 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined for *either* SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 10 + +# if defined(TLS_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +/* No longer used as of OpenSSL 1.1.1 */ +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 + +/* Removed from OpenSSL 1.1.0 */ +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0 + +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 + +/* Set if we encrypt then mac instead of usual mac then encrypt */ +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_READ 0x0100 +# define TLS1_FLAGS_ENCRYPT_THEN_MAC TLS1_FLAGS_ENCRYPT_THEN_MAC_READ + +/* Set if extended master secret extension received from peer */ +# define TLS1_FLAGS_RECEIVED_EXTMS 0x0200 + +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE 0x0400 + +# define TLS1_FLAGS_STATELESS 0x0800 + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_END_OF_EARLY_DATA 5 +# define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_URL 21 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# define SSL3_MT_SUPPLEMENTAL_DATA 23 +# define SSL3_MT_KEY_UPDATE 24 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define SSL3_MT_MESSAGE_HASH 254 +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +/* Dummy message type for handling CCS like a normal handshake message */ +# define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x001 +# define SSL3_CC_WRITE 0x002 +# define SSL3_CC_CLIENT 0x010 +# define SSL3_CC_SERVER 0x020 +# define SSL3_CC_EARLY 0x040 +# define SSL3_CC_HANDSHAKE 0x080 +# define SSL3_CC_APPLICATION 0x100 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/sslerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/sslerr.h new file mode 100644 index 00000000..82983d3c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/sslerr.h @@ -0,0 +1,773 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSLERR_H +# define HEADER_SSLERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_SSL_strings(void); + +/* + * SSL function codes. + */ +# define SSL_F_ADD_CLIENT_KEY_SHARE_EXT 438 +# define SSL_F_ADD_KEY_SHARE 512 +# define SSL_F_BYTES_TO_CIPHER_LIST 519 +# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 +# define SSL_F_CIPHERSUITE_CB 622 +# define SSL_F_CONSTRUCT_CA_NAMES 552 +# define SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS 553 +# define SSL_F_CONSTRUCT_STATEFUL_TICKET 636 +# define SSL_F_CONSTRUCT_STATELESS_TICKET 637 +# define SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH 539 +# define SSL_F_CREATE_TICKET_PREQUEL 638 +# define SSL_F_CT_MOVE_SCTS 345 +# define SSL_F_CT_STRICT 349 +# define SSL_F_CUSTOM_EXT_ADD 554 +# define SSL_F_CUSTOM_EXT_PARSE 555 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DANE_CTX_ENABLE 347 +# define SSL_F_DANE_MTYPE_SET 393 +# define SSL_F_DANE_TLSA_ADD 394 +# define SSL_F_DERIVE_SECRET_KEY_AND_IV 514 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 318 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_HM_FRAGMENT_NEW 623 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 339 +# define SSL_F_DTLS1_RETRANSMIT_MESSAGE 390 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_DTLS1_WRITE_BYTES 545 +# define SSL_F_DTLSV1_LISTEN 350 +# define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC 371 +# define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385 +# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370 +# define SSL_F_DTLS_PROCESS_HELLO_VERIFY 386 +# define SSL_F_DTLS_RECORD_LAYER_NEW 635 +# define SSL_F_DTLS_WAIT_FOR_DRY 592 +# define SSL_F_EARLY_DATA_COUNT_OK 532 +# define SSL_F_FINAL_EARLY_DATA 556 +# define SSL_F_FINAL_EC_PT_FORMATS 485 +# define SSL_F_FINAL_EMS 486 +# define SSL_F_FINAL_KEY_SHARE 503 +# define SSL_F_FINAL_MAXFRAGMENTLEN 557 +# define SSL_F_FINAL_RENEGOTIATE 483 +# define SSL_F_FINAL_SERVER_NAME 558 +# define SSL_F_FINAL_SIG_ALGS 497 +# define SSL_F_GET_CERT_VERIFY_TBS_DATA 588 +# define SSL_F_NSS_KEYLOG_INT 500 +# define SSL_F_OPENSSL_INIT_SSL 342 +# define SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION 436 +# define SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION 598 +# define SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE 430 +# define SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE 593 +# define SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE 594 +# define SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION 417 +# define SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION 599 +# define SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION 437 +# define SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION 600 +# define SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE 431 +# define SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE 601 +# define SSL_F_OSSL_STATEM_SERVER_POST_WORK 602 +# define SSL_F_OSSL_STATEM_SERVER_PRE_WORK 640 +# define SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE 603 +# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION 418 +# define SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION 604 +# define SSL_F_PARSE_CA_NAMES 541 +# define SSL_F_PITEM_NEW 624 +# define SSL_F_PQUEUE_NEW 625 +# define SSL_F_PROCESS_KEY_SHARE_EXT 439 +# define SSL_F_READ_STATE_MACHINE 352 +# define SSL_F_SET_CLIENT_CIPHERSUITE 540 +# define SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET 595 +# define SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET 589 +# define SSL_F_SRP_VERIFY_SERVER_PARAM 596 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 608 +# define SSL_F_SSL3_FINAL_FINISH_MAC 285 +# define SSL_F_SSL3_FINISH_MAC 587 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_INIT_FINISHED_MAC 397 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CERT_CHAIN 316 +# define SSL_F_SSL_ADD_CERT_TO_BUF 319 +# define SSL_F_SSL_ADD_CERT_TO_WPACKET 493 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BUILD_CERT_CHAIN 332 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CACHE_CIPHERLIST 520 +# define SSL_F_SSL_CERT_ADD0_CHAIN_CERT 346 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CERT_SET0_CHAIN 340 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO 606 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CHOOSE_CLIENT_VERSION 607 +# define SSL_F_SSL_CIPHER_DESCRIPTION 626 +# define SSL_F_SSL_CIPHER_LIST_TO_BYTES 425 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT 627 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CONF_CMD 334 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_ENABLE_CT 398 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_ALPN_PROTOS 343 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK 396 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH 551 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_CTX_USE_SERVERINFO 336 +# define SSL_F_SSL_CTX_USE_SERVERINFO_EX 543 +# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 +# define SSL_F_SSL_DANE_DUP 403 +# define SSL_F_SSL_DANE_ENABLE 395 +# define SSL_F_SSL_DERIVE 590 +# define SSL_F_SSL_DO_CONFIG 391 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_DUP_CA_LIST 408 +# define SSL_F_SSL_ENABLE_CT 402 +# define SSL_F_SSL_GENERATE_PKEY_GROUP 559 +# define SSL_F_SSL_GENERATE_SESSION_ID 547 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_HANDSHAKE_HASH 560 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_KEY_UPDATE 515 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_LOG_MASTER_SECRET 498 +# define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499 +# define SSL_F_SSL_MODULE_INIT 392 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_NEXT_PROTO_VALIDATE 565 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PEEK_EX 432 +# define SSL_F_SSL_PEEK_INTERNAL 522 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_READ_EARLY_DATA 529 +# define SSL_F_SSL_READ_EX 434 +# define SSL_F_SSL_READ_INTERNAL 523 +# define SSL_F_SSL_RENEGOTIATE 516 +# define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 +# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 +# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID 423 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SET_ALPN_PROTOS 344 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CERT_AND_KEY 621 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK 399 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH 550 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_START_ASYNC_JOB 389 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VALIDATE_CT 400 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE 616 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_SSL_WRITE_EARLY_DATA 526 +# define SSL_F_SSL_WRITE_EARLY_FINISH 527 +# define SSL_F_SSL_WRITE_EX 433 +# define SSL_F_SSL_WRITE_INTERNAL 524 +# define SSL_F_STATE_MACHINE 353 +# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 +# define SSL_F_TLS12_COPY_SIGALGS 533 +# define SSL_F_TLS13_CHANGE_CIPHER_STATE 440 +# define SSL_F_TLS13_ENC 609 +# define SSL_F_TLS13_FINAL_FINISH_MAC 605 +# define SSL_F_TLS13_GENERATE_SECRET 591 +# define SSL_F_TLS13_HKDF_EXPAND 561 +# define SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA 617 +# define SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA 618 +# define SSL_F_TLS13_SETUP_KEY_BLOCK 441 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS 341 +# define SSL_F_TLS1_ENC 401 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_GET_CURVELIST 338 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SAVE_U16 628 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_TLS1_SET_GROUPS 629 +# define SSL_F_TLS1_SET_RAW_SIGALGS 630 +# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 +# define SSL_F_TLS1_SET_SHARED_SIGALGS 631 +# define SSL_F_TLS1_SET_SIGALGS 632 +# define SSL_F_TLS_CHOOSE_SIGALG 513 +# define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK 354 +# define SSL_F_TLS_COLLECT_EXTENSIONS 435 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES 542 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST 372 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS 429 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY 494 +# define SSL_F_TLS_CONSTRUCT_CERT_VERIFY 496 +# define SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC 427 +# define SSL_F_TLS_CONSTRUCT_CKE_DHE 404 +# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405 +# define SSL_F_TLS_CONSTRUCT_CKE_GOST 406 +# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407 +# define SSL_F_TLS_CONSTRUCT_CKE_RSA 409 +# define SSL_F_TLS_CONSTRUCT_CKE_SRP 410 +# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE 484 +# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO 487 +# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE 488 +# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489 +# define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466 +# define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355 +# define SSL_F_TLS_CONSTRUCT_CTOS_COOKIE 535 +# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530 +# define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467 +# define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468 +# define SSL_F_TLS_CONSTRUCT_CTOS_ETM 469 +# define SSL_F_TLS_CONSTRUCT_CTOS_HELLO 356 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE 357 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE 470 +# define SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN 549 +# define SSL_F_TLS_CONSTRUCT_CTOS_NPN 471 +# define SSL_F_TLS_CONSTRUCT_CTOS_PADDING 472 +# define SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH 619 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK 501 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 509 +# define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 473 +# define SSL_F_TLS_CONSTRUCT_CTOS_SCT 474 +# define SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME 475 +# define SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET 476 +# define SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS 477 +# define SSL_F_TLS_CONSTRUCT_CTOS_SRP 478 +# define SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST 479 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS 480 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS 481 +# define SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP 482 +# define SSL_F_TLS_CONSTRUCT_CTOS_VERIFY 358 +# define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS 443 +# define SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA 536 +# define SSL_F_TLS_CONSTRUCT_EXTENSIONS 447 +# define SSL_F_TLS_CONSTRUCT_FINISHED 359 +# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST 373 +# define SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST 510 +# define SSL_F_TLS_CONSTRUCT_KEY_UPDATE 517 +# define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET 428 +# define SSL_F_TLS_CONSTRUCT_NEXT_PROTO 426 +# define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE 490 +# define SSL_F_TLS_CONSTRUCT_SERVER_HELLO 491 +# define SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE 492 +# define SSL_F_TLS_CONSTRUCT_STOC_ALPN 451 +# define SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE 374 +# define SSL_F_TLS_CONSTRUCT_STOC_COOKIE 613 +# define SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG 452 +# define SSL_F_TLS_CONSTRUCT_STOC_DONE 375 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA 531 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO 525 +# define SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS 453 +# define SSL_F_TLS_CONSTRUCT_STOC_EMS 454 +# define SSL_F_TLS_CONSTRUCT_STOC_ETM 455 +# define SSL_F_TLS_CONSTRUCT_STOC_HELLO 376 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE 377 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE 456 +# define SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN 548 +# define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG 457 +# define SSL_F_TLS_CONSTRUCT_STOC_PSK 504 +# define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE 458 +# define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME 459 +# define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET 460 +# define SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST 461 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS 544 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS 611 +# define SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP 462 +# define SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO 521 +# define SSL_F_TLS_FINISH_HANDSHAKE 597 +# define SSL_F_TLS_GET_MESSAGE_BODY 351 +# define SSL_F_TLS_GET_MESSAGE_HEADER 387 +# define SSL_F_TLS_HANDLE_ALPN 562 +# define SSL_F_TLS_HANDLE_STATUS_REQUEST 563 +# define SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES 566 +# define SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT 449 +# define SSL_F_TLS_PARSE_CTOS_ALPN 567 +# define SSL_F_TLS_PARSE_CTOS_COOKIE 614 +# define SSL_F_TLS_PARSE_CTOS_EARLY_DATA 568 +# define SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS 569 +# define SSL_F_TLS_PARSE_CTOS_EMS 570 +# define SSL_F_TLS_PARSE_CTOS_KEY_SHARE 463 +# define SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN 571 +# define SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH 620 +# define SSL_F_TLS_PARSE_CTOS_PSK 505 +# define SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES 572 +# define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464 +# define SSL_F_TLS_PARSE_CTOS_SERVER_NAME 573 +# define SSL_F_TLS_PARSE_CTOS_SESSION_TICKET 574 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS 575 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT 615 +# define SSL_F_TLS_PARSE_CTOS_SRP 576 +# define SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST 577 +# define SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS 578 +# define SSL_F_TLS_PARSE_CTOS_USE_SRTP 465 +# define SSL_F_TLS_PARSE_STOC_ALPN 579 +# define SSL_F_TLS_PARSE_STOC_COOKIE 534 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA 538 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 528 +# define SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS 580 +# define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445 +# define SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN 581 +# define SSL_F_TLS_PARSE_STOC_NPN 582 +# define SSL_F_TLS_PARSE_STOC_PSK 502 +# define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 448 +# define SSL_F_TLS_PARSE_STOC_SCT 564 +# define SSL_F_TLS_PARSE_STOC_SERVER_NAME 583 +# define SSL_F_TLS_PARSE_STOC_SESSION_TICKET 584 +# define SSL_F_TLS_PARSE_STOC_STATUS_REQUEST 585 +# define SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS 612 +# define SSL_F_TLS_PARSE_STOC_USE_SRTP 446 +# define SSL_F_TLS_POST_PROCESS_CLIENT_HELLO 378 +# define SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE 384 +# define SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE 360 +# define SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST 610 +# define SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST 361 +# define SSL_F_TLS_PROCESS_CERT_STATUS 362 +# define SSL_F_TLS_PROCESS_CERT_STATUS_BODY 495 +# define SSL_F_TLS_PROCESS_CERT_VERIFY 379 +# define SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC 363 +# define SSL_F_TLS_PROCESS_CKE_DHE 411 +# define SSL_F_TLS_PROCESS_CKE_ECDHE 412 +# define SSL_F_TLS_PROCESS_CKE_GOST 413 +# define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 414 +# define SSL_F_TLS_PROCESS_CKE_RSA 415 +# define SSL_F_TLS_PROCESS_CKE_SRP 416 +# define SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE 380 +# define SSL_F_TLS_PROCESS_CLIENT_HELLO 381 +# define SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE 382 +# define SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS 444 +# define SSL_F_TLS_PROCESS_END_OF_EARLY_DATA 537 +# define SSL_F_TLS_PROCESS_FINISHED 364 +# define SSL_F_TLS_PROCESS_HELLO_REQ 507 +# define SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST 511 +# define SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT 442 +# define SSL_F_TLS_PROCESS_KEY_EXCHANGE 365 +# define SSL_F_TLS_PROCESS_KEY_UPDATE 518 +# define SSL_F_TLS_PROCESS_NEW_SESSION_TICKET 366 +# define SSL_F_TLS_PROCESS_NEXT_PROTO 383 +# define SSL_F_TLS_PROCESS_SERVER_CERTIFICATE 367 +# define SSL_F_TLS_PROCESS_SERVER_DONE 368 +# define SSL_F_TLS_PROCESS_SERVER_HELLO 369 +# define SSL_F_TLS_PROCESS_SKE_DHE 419 +# define SSL_F_TLS_PROCESS_SKE_ECDHE 420 +# define SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE 421 +# define SSL_F_TLS_PROCESS_SKE_SRP 422 +# define SSL_F_TLS_PSK_DO_BINDER 506 +# define SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT 450 +# define SSL_F_TLS_SETUP_HANDSHAKE 508 +# define SSL_F_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_WPACKET_INTERN_INIT_LEN 633 +# define SSL_F_WPACKET_START_SUB_PACKET_LEN__ 634 +# define SSL_F_WRITE_STATE_MACHINE 586 + +/* + * SSL reason codes. + */ +# define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE 143 +# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CIPHER 186 +# define SSL_R_BAD_DATA 390 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_VALUE 102 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_EARLY_DATA 233 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_EXTENSION 110 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HANDSHAKE_STATE 236 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_HRR_VERSION 263 +# define SSL_R_BAD_KEY_SHARE 108 +# define SSL_R_BAD_KEY_UPDATE 122 +# define SSL_R_BAD_LEGACY_VERSION 292 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_PACKET 240 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK 219 +# define SSL_R_BAD_PSK_IDENTITY 114 +# define SSL_R_BAD_RECORD_TYPE 443 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_VALUE 384 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BINDER_DOES_NOT_VERIFY 253 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CALLBACK_FAILED 234 +# define SSL_R_CANNOT_CHANGE_CIPHER 109 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_KEY_TOO_SMALL 397 +# define SSL_R_CA_MD_TOO_WEAK 398 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_CB_ERROR 377 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED 218 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_CONTEXT_NOT_DANE_ENABLED 167 +# define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED 206 +# define SSL_R_DANE_ALREADY_ENABLED 172 +# define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL 173 +# define SSL_R_DANE_NOT_ENABLED 175 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE 180 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE 184 +# define SSL_R_DANE_TLSA_BAD_DATA_LENGTH 189 +# define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH 192 +# define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE 200 +# define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY 201 +# define SSL_R_DANE_TLSA_BAD_SELECTOR 202 +# define SSL_R_DANE_TLSA_NULL_DATA 203 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 394 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 +# define SSL_R_EE_KEY_TOO_SMALL 399 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204 +# define SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE 194 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTENSION_NOT_RECEIVED 279 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_EXT_LENGTH_MISMATCH 163 +# define SSL_R_FAILED_TO_INIT_ASYNC 405 +# define SSL_R_FRAGMENTED_CLIENT_HELLO 401 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_POINT_COMPRESSION 162 +# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INCONSISTENT_EARLY_DATA_ALPN 222 +# define SSL_R_INCONSISTENT_EARLY_DATA_SNI 231 +# define SSL_R_INCONSISTENT_EXTMS 104 +# define SSL_R_INSUFFICIENT_SECURITY 241 +# define SSL_R_INVALID_ALERT 205 +# define SSL_R_INVALID_CCS_MESSAGE 260 +# define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_CONFIG 283 +# define SSL_R_INVALID_CONFIGURATION_NAME 113 +# define SSL_R_INVALID_CONTEXT 282 +# define SSL_R_INVALID_CT_VALIDATION_TYPE 212 +# define SSL_R_INVALID_KEY_UPDATE_TYPE 120 +# define SSL_R_INVALID_MAX_EARLY_DATA 174 +# define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_SEQUENCE_NUMBER 402 +# define SSL_R_INVALID_SERVERINFO_DATA 388 +# define SSL_R_INVALID_SESSION_ID 999 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_LONG 404 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 +# define SSL_R_MISSING_FATAL 256 +# define SSL_R_MISSING_PARAMETERS 290 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SIGALGS_EXTENSION 112 +# define SSL_R_MISSING_SIGNING_CERT 221 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION 209 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 +# define SSL_R_NOT_ON_RECORD_BOUNDARY 182 +# define SSL_R_NOT_REPLACING_CERTIFICATE 289 +# define SSL_R_NOT_SERVER 284 +# define SSL_R_NO_APPLICATION_PROTOCOL 235 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CHANGE_FOLLOWING_HRR 214 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_COOKIE_CALLBACK_SET 287 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PEM_EXTENSIONS 389 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SHARED_GROUPS 410 +# define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_SUITABLE_KEY_SHARE 101 +# define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 +# define SSL_R_NO_VALID_SCTS 216 +# define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_OVERFLOW_ERROR 237 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEM_NAME_BAD_PREFIX 391 +# define SSL_R_PEM_NAME_TOO_SHORT 392 +# define SSL_R_PIPELINE_FAILURE 406 +# define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278 +# define SSL_R_PRIVATE_KEY_MISMATCH 288 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUEST_PENDING 285 +# define SSL_R_REQUEST_SENT 286 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SCT_VERIFICATION_FAILED 208 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH 232 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_COMMAND_SECTION_EMPTY 117 +# define SSL_R_SSL_COMMAND_SECTION_NOT_FOUND 125 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_NEGATIVE_LENGTH 372 +# define SSL_R_SSL_SECTION_EMPTY 126 +# define SSL_R_SSL_SECTION_NOT_FOUND 136 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_TOO_LONG 408 +# define SSL_R_SSL_SESSION_VERSION_MISMATCH 210 +# define SSL_R_STILL_IN_INIT 121 +# define SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 +# define SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TOO_MANY_KEY_UPDATES 132 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 +# define SSL_R_TOO_MUCH_EARLY_DATA 164 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_CCS_MESSAGE 262 +# define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_CMD_NAME 386 +# define SSL_R_UNKNOWN_COMMAND 139 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSOLICITED_EXTENSION 217 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_VERSION_TOO_HIGH 166 +# define SSL_R_VERSION_TOO_LOW 396 +# define SSL_R_WRONG_CERTIFICATE_TYPE 383 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/stack.h b/Hin2n/src/main/jniLibs/x86/include/openssl/stack.h new file mode 100644 index 00000000..cfc07505 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/stack.h @@ -0,0 +1,83 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */ + +typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); +typedef void (*OPENSSL_sk_freefunc)(void *); +typedef void *(*OPENSSL_sk_copyfunc)(const void *); + +int OPENSSL_sk_num(const OPENSSL_STACK *); +void *OPENSSL_sk_value(const OPENSSL_STACK *, int); + +void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data); + +OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n); +int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n); +void OPENSSL_sk_free(OPENSSL_STACK *); +void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *)); +OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *, + OPENSSL_sk_copyfunc c, + OPENSSL_sk_freefunc f); +int OPENSSL_sk_insert(OPENSSL_STACK *sk, const void *data, int where); +void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc); +void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p); +int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data); +void *OPENSSL_sk_shift(OPENSSL_STACK *st); +void *OPENSSL_sk_pop(OPENSSL_STACK *st); +void OPENSSL_sk_zero(OPENSSL_STACK *st); +OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *st); +void OPENSSL_sk_sort(OPENSSL_STACK *st); +int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _STACK OPENSSL_STACK +# define sk_num OPENSSL_sk_num +# define sk_value OPENSSL_sk_value +# define sk_set OPENSSL_sk_set +# define sk_new OPENSSL_sk_new +# define sk_new_null OPENSSL_sk_new_null +# define sk_free OPENSSL_sk_free +# define sk_pop_free OPENSSL_sk_pop_free +# define sk_deep_copy OPENSSL_sk_deep_copy +# define sk_insert OPENSSL_sk_insert +# define sk_delete OPENSSL_sk_delete +# define sk_delete_ptr OPENSSL_sk_delete_ptr +# define sk_find OPENSSL_sk_find +# define sk_find_ex OPENSSL_sk_find_ex +# define sk_push OPENSSL_sk_push +# define sk_unshift OPENSSL_sk_unshift +# define sk_shift OPENSSL_sk_shift +# define sk_pop OPENSSL_sk_pop +# define sk_zero OPENSSL_sk_zero +# define sk_set_cmp_func OPENSSL_sk_set_cmp_func +# define sk_dup OPENSSL_sk_dup +# define sk_sort OPENSSL_sk_sort +# define sk_is_sorted OPENSSL_sk_is_sorted +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/store.h b/Hin2n/src/main/jniLibs/x86/include/openssl/store.h new file mode 100644 index 00000000..a40a7339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/store.h @@ -0,0 +1,266 @@ +/* + * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STORE_H +# define HEADER_OSSL_STORE_H + +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * The main OSSL_STORE functions. + * ------------------------------ + * + * These allow applications to open a channel to a resource with supported + * data (keys, certs, crls, ...), read the data a piece at a time and decide + * what to do with it, and finally close. + */ + +typedef struct ossl_store_ctx_st OSSL_STORE_CTX; + +/* + * Typedef for the OSSL_STORE_INFO post processing callback. This can be used + * to massage the given OSSL_STORE_INFO, or to drop it entirely (by returning + * NULL). + */ +typedef OSSL_STORE_INFO *(*OSSL_STORE_post_process_info_fn)(OSSL_STORE_INFO *, + void *); + +/* + * Open a channel given a URI. The given UI method will be used any time the + * loader needs extra input, for example when a password or pin is needed, and + * will be passed the same user data every time it's needed in this context. + * + * Returns a context reference which represents the channel to communicate + * through. + */ +OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, + void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data); + +/* + * Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be + * done, and depends on the underlying loader (use OSSL_STORE_get0_scheme to + * determine which loader is used), except for common commands (see below). + * Each command takes different arguments. + */ +int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */); +int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); + +/* + * Common ctrl commands that different loaders may choose to support. + */ +/* int on = 0 or 1; STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on); */ +# define OSSL_STORE_C_USE_SECMEM 1 +/* Where custom commands start */ +# define OSSL_STORE_C_CUSTOM_START 100 + +/* + * Read one data item (a key, a cert, a CRL) that is supported by the OSSL_STORE + * functionality, given a context. + * Returns a OSSL_STORE_INFO pointer, from which OpenSSL typed data can be + * extracted with OSSL_STORE_INFO_get0_PKEY(), OSSL_STORE_INFO_get0_CERT(), ... + * NULL is returned on error, which may include that the data found at the URI + * can't be figured out for certain or is ambiguous. + */ +OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); + +/* + * Check if end of data (end of file) is reached + * Returns 1 on end, 0 otherwise. + */ +int OSSL_STORE_eof(OSSL_STORE_CTX *ctx); + +/* + * Check if an error occurred + * Returns 1 if it did, 0 otherwise. + */ +int OSSL_STORE_error(OSSL_STORE_CTX *ctx); + +/* + * Close the channel + * Returns 1 on success, 0 on error. + */ +int OSSL_STORE_close(OSSL_STORE_CTX *ctx); + + +/*- + * Extracting OpenSSL types from and creating new OSSL_STORE_INFOs + * --------------------------------------------------------------- + */ + +/* + * Types of data that can be ossl_stored in a OSSL_STORE_INFO. + * OSSL_STORE_INFO_NAME is typically found when getting a listing of + * available "files" / "tokens" / what have you. + */ +# define OSSL_STORE_INFO_NAME 1 /* char * */ +# define OSSL_STORE_INFO_PARAMS 2 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_PKEY 3 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_CERT 4 /* X509 * */ +# define OSSL_STORE_INFO_CRL 5 /* X509_CRL * */ + +/* + * Functions to generate OSSL_STORE_INFOs, one function for each type we + * support having in them, as well as a generic constructor. + * + * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO + * and will therefore be freed when the OSSL_STORE_INFO is freed. + */ +OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name); +int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); + +/* + * Functions to try to extract data from a OSSL_STORE_INFO. + */ +int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info); + +const char *OSSL_STORE_INFO_type_string(int type); + +/* + * Free the OSSL_STORE_INFO + */ +void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info); + + +/*- + * Functions to construct a search URI from a base URI and search criteria + * ----------------------------------------------------------------------- + */ + +/* OSSL_STORE search types */ +# define OSSL_STORE_SEARCH_BY_NAME 1 /* subject in certs, issuer in CRLs */ +# define OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 2 +# define OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 3 +# define OSSL_STORE_SEARCH_BY_ALIAS 4 + +/* To check what search types the scheme handler supports */ +int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type); + +/* Search term constructors */ +/* + * The input is considered to be owned by the caller, and must therefore + * remain present throughout the lifetime of the returned OSSL_STORE_SEARCH + */ +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, + const ASN1_INTEGER + *serial); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, + const unsigned char + *bytes, size_t len); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias); + +/* Search term destructor */ +void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search); + +/* Search term accessors */ +int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion); +X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion); +const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH + *criterion); +const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH + *criterion, size_t *length); +const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion); +const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion); + +/* + * Add search criterion and expected return type (which can be unspecified) + * to the loading channel. This MUST happen before the first OSSL_STORE_load(). + */ +int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type); +int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search); + + +/*- + * Function to register a loader for the given URI scheme. + * ------------------------------------------------------- + * + * The loader receives all the main components of an URI except for the + * scheme. + */ + +typedef struct ossl_store_loader_st OSSL_STORE_LOADER; +OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme); +const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); +const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); +/* struct ossl_store_loader_ctx_st is defined differently by each loader */ +typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; +typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER + *loader, + const char *uri, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, + OSSL_STORE_open_fn open_function); +typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd, + va_list args); +int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, + OSSL_STORE_ctrl_fn ctrl_function); +typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected); +int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader, + OSSL_STORE_expect_fn expect_function); +typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx, + OSSL_STORE_SEARCH *criteria); +int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader, + OSSL_STORE_find_fn find_function); +typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader, + OSSL_STORE_load_fn load_function); +typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader, + OSSL_STORE_eof_fn eof_function); +typedef int (*OSSL_STORE_error_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, + OSSL_STORE_error_fn error_function); +typedef int (*OSSL_STORE_close_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, + OSSL_STORE_close_fn close_function); +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); + +int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); +OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme); + +/*- + * Functions to list STORE loaders + * ------------------------------- + */ +int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER + *loader, void *do_arg), + void *do_arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/storeerr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/storeerr.h new file mode 100644 index 00000000..190eab07 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/storeerr.h @@ -0,0 +1,91 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STOREERR_H +# define HEADER_OSSL_STOREERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OSSL_STORE_strings(void); + +/* + * OSSL_STORE function codes. + */ +# define OSSL_STORE_F_FILE_CTRL 129 +# define OSSL_STORE_F_FILE_FIND 138 +# define OSSL_STORE_F_FILE_GET_PASS 118 +# define OSSL_STORE_F_FILE_LOAD 119 +# define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 124 +# define OSSL_STORE_F_FILE_NAME_TO_URI 126 +# define OSSL_STORE_F_FILE_OPEN 120 +# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 127 +# define OSSL_STORE_F_OSSL_STORE_EXPECT 130 +# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 128 +# define OSSL_STORE_F_OSSL_STORE_FIND 131 +# define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 100 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 101 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL 102 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME 103 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION 135 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS 104 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY 105 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT 106 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL 107 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED 123 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME 109 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS 110 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY 111 +# define OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION 134 +# define OSSL_STORE_F_OSSL_STORE_INIT_ONCE 112 +# define OSSL_STORE_F_OSSL_STORE_LOADER_NEW 113 +# define OSSL_STORE_F_OSSL_STORE_OPEN 114 +# define OSSL_STORE_F_OSSL_STORE_OPEN_INT 115 +# define OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT 117 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS 132 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 133 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 136 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME 137 +# define OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT 116 +# define OSSL_STORE_F_TRY_DECODE_PARAMS 121 +# define OSSL_STORE_F_TRY_DECODE_PKCS12 122 +# define OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED 125 + +/* + * OSSL_STORE reason codes. + */ +# define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107 +# define OSSL_STORE_R_BAD_PASSWORD_READ 115 +# define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113 +# define OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST 121 +# define OSSL_STORE_R_INVALID_SCHEME 106 +# define OSSL_STORE_R_IS_NOT_A 112 +# define OSSL_STORE_R_LOADER_INCOMPLETE 116 +# define OSSL_STORE_R_LOADING_STARTED 117 +# define OSSL_STORE_R_NOT_A_CERTIFICATE 100 +# define OSSL_STORE_R_NOT_A_CRL 101 +# define OSSL_STORE_R_NOT_A_KEY 102 +# define OSSL_STORE_R_NOT_A_NAME 103 +# define OSSL_STORE_R_NOT_PARAMETERS 104 +# define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114 +# define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108 +# define OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 119 +# define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109 +# define OSSL_STORE_R_UNREGISTERED_SCHEME 105 +# define OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE 110 +# define OSSL_STORE_R_UNSUPPORTED_OPERATION 118 +# define OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE 120 +# define OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED 111 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/symhacks.h b/Hin2n/src/main/jniLibs/x86/include/openssl/symhacks.h new file mode 100644 index 00000000..156ea6e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/symhacks.h @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/tls1.h b/Hin2n/src/main/jniLibs/x86/include/openssl/tls1.h new file mode 100644 index 00000000..76d9fda4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/tls1.h @@ -0,0 +1,1237 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Default security level if not overridden at config time */ +# ifndef OPENSSL_TLS_SECURITY_LEVEL +# define OPENSSL_TLS_SECURITY_LEVEL 1 +# endif + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS1_3_VERSION 0x0304 +# define TLS_MAX_VERSION TLS1_3_VERSION + +/* Special value for method supporting multiple versions */ +# define TLS_ANY_VERSION 0x10000 + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((SSL_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_version(s) : 0) + +# define TLS1_get_client_version(s) \ + ((SSL_client_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_client_version(s) : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* TLSv1.3 alerts */ +# define TLS13_AD_MISSING_EXTENSION 109 /* fatal */ +# define TLS13_AD_CERTIFICATE_REQUIRED 116 /* fatal */ +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ +# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +/* + * Prior to TLSv1.3 the supported_groups extension was known as + * elliptic_curves + */ +# define TLSEXT_TYPE_supported_groups 10 +# define TLSEXT_TYPE_elliptic_curves TLSEXT_TYPE_supported_groups +# define TLSEXT_TYPE_ec_point_formats 11 + + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC7301 */ +# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* + * Extension type for Certificate Transparency + * https://tools.ietf.org/html/rfc6962#section-3.3.1 + */ +# define TLSEXT_TYPE_signed_certificate_timestamp 18 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC7366 */ +# define TLSEXT_TYPE_encrypt_then_mac 22 + +/* ExtensionType value from RFC7627 */ +# define TLSEXT_TYPE_extended_master_secret 23 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* As defined for TLS1.3 */ +# define TLSEXT_TYPE_psk 41 +# define TLSEXT_TYPE_early_data 42 +# define TLSEXT_TYPE_supported_versions 43 +# define TLSEXT_TYPE_cookie 44 +# define TLSEXT_TYPE_psk_kex_modes 45 +# define TLSEXT_TYPE_certificate_authorities 47 +# define TLSEXT_TYPE_post_handshake_auth 49 +# define TLSEXT_TYPE_signature_algorithms_cert 50 +# define TLSEXT_TYPE_key_share 51 + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 +# define TLSEXT_signature_gostr34102001 237 +# define TLSEXT_signature_gostr34102012_256 238 +# define TLSEXT_signature_gostr34102012_512 239 + +/* Total number of different signature algorithms */ +# define TLSEXT_signature_num 7 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 +# define TLSEXT_hash_gostr3411 237 +# define TLSEXT_hash_gostr34112012_256 238 +# define TLSEXT_hash_gostr34112012_512 239 + +/* Total number of different digest algorithms */ + +# define TLSEXT_hash_num 10 + +/* Flag set for unrecognised algorithms */ +# define TLSEXT_nid_unknown 0x1000000 + +/* ECC curves */ + +# define TLSEXT_curve_P_256 23 +# define TLSEXT_curve_P_384 24 + +/* OpenSSL value to disable maximum fragment length extension */ +# define TLSEXT_max_fragment_length_DISABLED 0 +/* Allowed values for max fragment length extension */ +# define TLSEXT_max_fragment_length_512 1 +# define TLSEXT_max_fragment_length_1024 2 +# define TLSEXT_max_fragment_length_2048 3 +# define TLSEXT_max_fragment_length_4096 4 + +int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode); +int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode); + +# define TLSEXT_MAXLEN_host_name 255 + +__owur const char *SSL_get_servername(const SSL *s, const int type); +__owur int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * 0 or -1 otherwise. + */ +__owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context); + +/* + * SSL_export_keying_material_early exports a value derived from the + * early exporter master secret, as specified in + * https://tools.ietf.org/html/draft-ietf-tls-tls13-23. It writes + * |olen| bytes to |out| given a label and optional context. It + * returns 1 on success and 0 otherwise. + */ +__owur int SSL_export_keying_material_early(SSL *s, unsigned char *out, + size_t olen, const char *label, + size_t llen, + const unsigned char *context, + size_t contextlen); + +int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid); +int SSL_get_signature_type_nid(const SSL *s, int *pnid); + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +__owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); + +# define SSL_set_tlsext_host_name(s,name) \ + SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,\ + (void *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ + SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,\ + (void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0,arg) + +# define SSL_get_tlsext_status_type(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_set_tlsext_status_type(ssl, type) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0,arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen,arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ + SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,\ + (void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0,arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_TLSEXT_TICKET_KEYS,keylen,keys) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_TICKET_KEYS,keylen,keys) + +# define SSL_CTX_get_tlsext_status_cb(ssl, cb) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB,0,(void *)cb) +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,\ + (void (*)(void))cb) + +# define SSL_CTX_get_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) + +# define SSL_CTX_set_tlsext_status_type(ssl, type) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_CTX_get_tlsext_status_type(ssl) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,\ + (void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_DTLSEXT_HB_ENABLED 0x01 +# define SSL_DTLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_DTLSEXT_HB_DONT_RECV_REQUESTS 0x04 +# define SSL_get_dtlsext_heartbeat_pending(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_dtlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT \ + SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING \ + SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS \ + SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS +# define SSL_TLSEXT_HB_ENABLED \ + SSL_DTLSEXT_HB_ENABLED +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS \ + SSL_DTLSEXT_HB_DONT_SEND_REQUESTS +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS \ + SSL_DTLSEXT_HB_DONT_RECV_REQUESTS +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_get_dtlsext_heartbeat_pending(ssl) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_set_dtlsext_heartbeat_no_requests(ssl,arg) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D +# define TLS1_CK_DHE_PSK_WITH_RC4_128_SHA 0x0300008E +# define TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008F +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA 0x03000090 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA 0x03000091 +# define TLS1_CK_RSA_PSK_WITH_RC4_128_SHA 0x03000092 +# define TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x03000093 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA 0x03000094 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA 0x03000095 + +/* PSK ciphersuites from 5487 */ +# define TLS1_CK_PSK_WITH_AES_128_GCM_SHA256 0x030000A8 +# define TLS1_CK_PSK_WITH_AES_256_GCM_SHA384 0x030000A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256 0x030000AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384 0x030000AB +# define TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256 0x030000AC +# define TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384 0x030000AD +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA256 0x030000AE +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA384 0x030000AF +# define TLS1_CK_PSK_WITH_NULL_SHA256 0x030000B0 +# define TLS1_CK_PSK_WITH_NULL_SHA384 0x030000B1 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256 0x030000B2 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384 0x030000B3 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA256 0x030000B4 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA384 0x030000B5 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256 0x030000B6 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384 0x030000B7 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA256 0x030000B8 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA384 0x030000B9 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_PSK_WITH_NULL_SHA 0x0300002C +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA 0x0300002D +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA 0x0300002E + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_CK_RSA_WITH_AES_128_CCM 0x0300C09C +# define TLS1_CK_RSA_WITH_AES_256_CCM 0x0300C09D +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM 0x0300C09E +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM 0x0300C09F +# define TLS1_CK_RSA_WITH_AES_128_CCM_8 0x0300C0A0 +# define TLS1_CK_RSA_WITH_AES_256_CCM_8 0x0300C0A1 +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8 0x0300C0A2 +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8 0x0300C0A3 +# define TLS1_CK_PSK_WITH_AES_128_CCM 0x0300C0A4 +# define TLS1_CK_PSK_WITH_AES_256_CCM 0x0300C0A5 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM 0x0300C0A6 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM 0x0300C0A7 +# define TLS1_CK_PSK_WITH_AES_128_CCM_8 0x0300C0A8 +# define TLS1_CK_PSK_WITH_AES_256_CCM_8 0x0300C0A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8 0x0300C0AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8 0x0300C0AB + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM 0x0300C0AC +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM 0x0300C0AD +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8 0x0300C0AE +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8 0x0300C0AF + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BA +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BB +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BC +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BD +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BE +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 0x030000BF + +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C0 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C1 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C2 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C3 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C4 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 0x030000C5 + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* ECDHE PSK ciphersuites from RFC5489 */ +# define TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA 0x0300C033 +# define TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300C034 +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0x0300C037 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0x0300C038 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA 0x0300C039 +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256 0x0300C03A +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384 0x0300C03B + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C072 +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C073 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C074 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C075 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C076 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C077 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C078 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C079 + +# define TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C094 +# define TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C095 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C096 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C097 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C098 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C099 +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C09A +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C09B + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCA8 +# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0x0300CCA9 +# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCAA +# define TLS1_CK_PSK_WITH_CHACHA20_POLY1305 0x0300CCAB +# define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAC +# define TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAD +# define TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305 0x0300CCAE + +/* TLS v1.3 ciphersuites */ +# define TLS1_3_CK_AES_128_GCM_SHA256 0x03001301 +# define TLS1_3_CK_AES_256_GCM_SHA384 0x03001302 +# define TLS1_3_CK_CHACHA20_POLY1305_SHA256 0x03001303 +# define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 +# define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 +# define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 +# define TLS1_CK_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C052 +# define TLS1_CK_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C053 +# define TLS1_CK_DH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C054 +# define TLS1_CK_DH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C055 +# define TLS1_CK_DHE_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C056 +# define TLS1_CK_DHE_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C057 +# define TLS1_CK_DH_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C058 +# define TLS1_CK_DH_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C059 +# define TLS1_CK_DH_anon_WITH_ARIA_128_GCM_SHA256 0x0300C05A +# define TLS1_CK_DH_anon_WITH_ARIA_256_GCM_SHA384 0x0300C05B +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05C +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05D +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05E +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05F +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C060 +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C061 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C062 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C063 +# define TLS1_CK_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06A +# define TLS1_CK_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06B +# define TLS1_CK_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06C +# define TLS1_CK_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06D +# define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E +# define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_128_SHA "TLS_DH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_WITH_AES_256_SHA "TLS_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_256_SHA "TLS_DH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_NULL_SHA256 "TLS_RSA_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_SHA256 "TLS_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_SHA256 "TLS_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA256 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA256 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA256 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA256 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_128_SHA256 "TLS_DH_anon_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_SHA256 "TLS_DH_anon_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_GCM_SHA256 "TLS_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_GCM_SHA384 "TLS_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_GCM_SHA256 "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_GCM_SHA384 "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ADH_WITH_AES_128_GCM_SHA256 "TLS_DH_anon_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_GCM_SHA384 "TLS_DH_anon_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_WITH_AES_128_CCM "TLS_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_RSA_WITH_AES_256_CCM "TLS_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM "TLS_DHE_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM "TLS_DHE_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_RSA_WITH_AES_128_CCM_8 "TLS_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_RSA_WITH_AES_256_CCM_8 "TLS_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM_8 "TLS_DHE_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM_8 "TLS_DHE_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_128_CCM "TLS_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_PSK_WITH_AES_256_CCM "TLS_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM "TLS_DHE_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM "TLS_DHE_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_PSK_WITH_AES_128_CCM_8 "TLS_PSK_WITH_AES_128_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_256_CCM_8 "TLS_PSK_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM_8 "TLS_PSK_DHE_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM_8 "TLS_PSK_DHE_WITH_AES_256_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM "TLS_ECDHE_ECDSA_WITH_AES_128_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM "TLS_ECDHE_ECDSA_WITH_AES_256_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8" +# define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +# define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +# define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +# define TLS1_3_RFC_AES_128_CCM_SHA256 "TLS_AES_128_CCM_SHA256" +# define TLS1_3_RFC_AES_128_CCM_8_SHA256 "TLS_AES_128_CCM_8_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_NULL_SHA "TLS_ECDHE_ECDSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_NULL_SHA "TLS_ECDHE_RSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_NULL_SHA "TLS_ECDH_anon_WITH_NULL_SHA" +# define TLS1_RFC_ECDH_anon_WITH_DES_192_CBC3_SHA "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_128_CBC_SHA "TLS_ECDH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_256_CBC_SHA "TLS_ECDH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA "TLS_PSK_WITH_NULL_SHA" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA "TLS_DHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA "TLS_RSA_PSK_WITH_NULL_SHA" +# define TLS1_RFC_PSK_WITH_3DES_EDE_CBC_SHA "TLS_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA "TLS_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA "TLS_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_3DES_EDE_CBC_SHA "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA "TLS_RSA_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA "TLS_RSA_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_GCM_SHA256 "TLS_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_GCM_SHA384 "TLS_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_GCM_SHA256 "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_GCM_SHA384 "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_GCM_SHA256 "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_GCM_SHA384 "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA256 "TLS_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA384 "TLS_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA256 "TLS_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_PSK_WITH_NULL_SHA384 "TLS_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA256 "TLS_DHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA384 "TLS_DHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA256 "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA384 "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA256 "TLS_RSA_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA384 "TLS_RSA_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA "TLS_ECDHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA256 "TLS_ECDHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA384 "TLS_ECDHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_SRP_SHA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CHACHA20_POLY1305 "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_WITH_SEED_SHA "TLS_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_SEED_SHA "TLS_DHE_DSS_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_SEED_SHA "TLS_DHE_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ADH_WITH_SEED_SHA "TLS_DH_anon_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_RC4_128_SHA "TLS_ECDHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDH_anon_WITH_RC4_128_SHA "TLS_ECDH_anon_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_RC4_128_SHA "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_RC4_128_SHA "TLS_ECDHE_RSA_WITH_RC4_128_SHA" +# define TLS1_RFC_PSK_WITH_RC4_128_SHA "TLS_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_PSK_WITH_RC4_128_SHA "TLS_RSA_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_DHE_PSK_WITH_RC4_128_SHA "TLS_DHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_anon_WITH_ARIA_128_GCM_SHA256 "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_anon_WITH_ARIA_256_GCM_SHA384 "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" + + +/* + * XXX Backward compatibility alert: Older versions of OpenSSL gave some DHE + * ciphers names with "EDH" instead of "DHE". Going forward, we should be + * using DHE everywhere, though we may indefinitely maintain aliases for + * users or configurations that used "EDH" + */ +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +# define TLS1_TXT_PSK_WITH_NULL_SHA "PSK-NULL-SHA" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA "DHE-PSK-NULL-SHA" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA "RSA-PSK-NULL-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +# define TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA "DHE-PSK-RC4-SHA" +# define TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA "DHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA "DHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA "DHE-PSK-AES256-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA "RSA-PSK-RC4-SHA" +# define TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA "RSA-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA "RSA-PSK-AES128-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA "RSA-PSK-AES256-CBC-SHA" + +/* PSK ciphersuites from RFC 5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256 "DHE-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384 "DHE-PSK-AES256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256 "RSA-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384 "RSA-PSK-AES256-GCM-SHA384" + +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256 "PSK-AES128-CBC-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384 "PSK-AES256-CBC-SHA384" +# define TLS1_TXT_PSK_WITH_NULL_SHA256 "PSK-NULL-SHA256" +# define TLS1_TXT_PSK_WITH_NULL_SHA384 "PSK-NULL-SHA384" + +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256 "DHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384 "DHE-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA256 "DHE-PSK-NULL-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA384 "DHE-PSK-NULL-SHA384" + +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256 "RSA-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384 "RSA-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA256 "RSA-PSK-NULL-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA384 "RSA-PSK-NULL-SHA384" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 "CAMELLIA128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DH-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DHE-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 "ADH-CAMELLIA128-SHA256" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 "CAMELLIA256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DH-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DH-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DHE-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DHE-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 "ADH-CAMELLIA256-SHA256" + +# define TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256 "PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384 "PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "DHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "DHE-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "RSA-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "RSA-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-PSK-CAMELLIA256-SHA384" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_TXT_RSA_WITH_AES_128_CCM "AES128-CCM" +# define TLS1_TXT_RSA_WITH_AES_256_CCM "AES256-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM "DHE-RSA-AES128-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM "DHE-RSA-AES256-CCM" + +# define TLS1_TXT_RSA_WITH_AES_128_CCM_8 "AES128-CCM8" +# define TLS1_TXT_RSA_WITH_AES_256_CCM_8 "AES256-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8 "DHE-RSA-AES128-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8 "DHE-RSA-AES256-CCM8" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM "PSK-AES128-CCM" +# define TLS1_TXT_PSK_WITH_AES_256_CCM "PSK-AES256-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM "DHE-PSK-AES128-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM "DHE-PSK-AES256-CCM" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM_8 "PSK-AES128-CCM8" +# define TLS1_TXT_PSK_WITH_AES_256_CCM_8 "PSK-AES256-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8 "DHE-PSK-AES128-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8 "DHE-PSK-AES256-CCM8" + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM "ECDHE-ECDSA-AES128-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM "ECDHE-ECDSA-AES256-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8 "ECDHE-ECDSA-AES128-CCM8" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8 "ECDHE-ECDSA-AES256-CCM8" + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +/* TLS v1.2 PSK GCM ciphersuites from RFC5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" + +/* ECDHE PSK ciphersuites from RFC 5489 */ +# define TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA "ECDHE-PSK-RC4-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "ECDHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-PSK-AES256-CBC-SHA" + +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "ECDHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "ECDHE-PSK-AES256-CBC-SHA384" + +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA "ECDHE-PSK-NULL-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256 "ECDHE-PSK-NULL-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384 "ECDHE-PSK-NULL-SHA384" + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-RSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-RSA-CAMELLIA256-SHA384" + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_PSK_WITH_CHACHA20_POLY1305 "PSK-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305 "ECDHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305 "DHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305 "RSA-PSK-CHACHA20-POLY1305" + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_TXT_RSA_WITH_ARIA_128_GCM_SHA256 "ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_ARIA_256_GCM_SHA384 "ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "DHE-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "DHE-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_ARIA_128_GCM_SHA256 "DH-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_ARIA_256_GCM_SHA384 "DH-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "DHE-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "DHE-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_ARIA_128_GCM_SHA256 "DH-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_ARIA_256_GCM_SHA384 "DH-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_anon_WITH_ARIA_128_GCM_SHA256 "ADH-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_anon_WITH_ARIA_256_GCM_SHA384 "ADH-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ARIA256-GCM-SHA384" +# define TLS1_TXT_PSK_WITH_ARIA_128_GCM_SHA256 "PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_ARIA_256_GCM_SHA384 "PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "DHE-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "DHE-PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "RSA-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "RSA-PSK-ARIA256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST01_SIGN 22 +# define TLS_CT_GOST12_SIGN 238 +# define TLS_CT_GOST12_512_SIGN 239 + +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 10 + +# if defined(SSL3_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 22 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "extended master secret" +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE 22 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# undef TLS_MD_EXTENDED_MASTER_SECRET_CONST +/* + * extended master secret + */ +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x6e\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ts.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ts.h new file mode 100644 index 00000000..3b58aa52 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ts.h @@ -0,0 +1,559 @@ +/* + * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include + +# ifndef OPENSSL_NO_TS +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# include +# include + +typedef struct TS_msg_imprint_st TS_MSG_IMPRINT; +typedef struct TS_req_st TS_REQ; +typedef struct TS_accuracy_st TS_ACCURACY; +typedef struct TS_tst_info_st TS_TST_INFO; + +/* Possible values for status. */ +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. */ +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + + +typedef struct TS_status_info_st TS_STATUS_INFO; +typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; +typedef struct ESS_cert_id ESS_CERT_ID; +typedef struct ESS_signing_cert ESS_SIGNING_CERT; + +DEFINE_STACK_OF(ESS_CERT_ID) + +typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2; +typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2; + +DEFINE_STACK_OF(ESS_CERT_ID_V2) + +typedef struct TS_resp_st TS_RESP; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +#ifndef OPENSSL_NO_STDIO +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +#endif +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +#ifndef OPENSSL_NO_STDIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +#endif +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +#ifndef OPENSSL_NO_STDIO +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +#endif +TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +#ifndef OPENSSL_NO_STDIO +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +#endif +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void); +void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a); +int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp); +ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a, + const unsigned char **pp, long length); +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a); + +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void); +void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a); +int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **pp); +ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a, + const unsigned char **pp, + long length); +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i); +const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a); + +const STACK_OF(ASN1_UTF8STRING) * +TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a); + +const ASN1_BIT_STRING * +TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, + int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx TS_RESP_CTX; + +DEFINE_STACK_OF_CONST(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, + const EVP_MD *signer_digest); +int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* Maximum status message length */ +# define TS_MAX_STATUS_LENGTH (1024 * 1024) + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); +int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f); +int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f); +BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b); +unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, + unsigned char *hexstr, long len); +X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s); +STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +#ifndef OPENSSL_NO_ENGINE +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +#endif +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_digest(CONF *conf, const char *section, + const char *md, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/tserr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/tserr.h new file mode 100644 index 00000000..07f23339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/tserr.h @@ -0,0 +1,132 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TSERR_H +# define HEADER_TSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_TS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_TS_strings(void); + +/* + * TS function codes. + */ +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_ADD_SIGNING_CERT_V2 147 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_CERT_ID_V2_NEW_INIT 156 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_ESS_SIGNING_CERT_V2_NEW_INIT 157 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_INVALID 151 +# define TS_F_TS_CONF_LOAD_CERT 153 +# define TS_F_TS_CONF_LOAD_CERTS 154 +# define TS_F_TS_CONF_LOAD_KEY 155 +# define TS_F_TS_CONF_LOOKUP_FAIL 152 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* + * TS reason codes. + */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CANNOT_LOAD_CERT 137 +# define TS_R_CANNOT_LOAD_KEY 138 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR 139 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_VAR_BAD_VALUE 135 +# define TS_R_VAR_LOOKUP_FAILURE 136 +# define TS_R_WRONG_CONTENT_TYPE 114 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/txt_db.h b/Hin2n/src/main/jniLibs/x86/include/openssl/txt_db.h new file mode 100644 index 00000000..ec981a43 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/txt_db.h @@ -0,0 +1,57 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include +# include +# include +# include + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 +# define DB_ERROR_WRONG_NUM_FIELDS 6 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DEFINE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/ui.h b/Hin2n/src/main/jniLibs/x86/include/openssl/ui.h new file mode 100644 index 00000000..7c721ec8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/ui.h @@ -0,0 +1,368 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# include +# include +# include + +/* For compatibility reasons, the macro OPENSSL_NO_UI is currently retained */ +# if OPENSSL_API_COMPAT < 0x10200000L +# ifdef OPENSSL_NO_UI_CONSOLE +# define OPENSSL_NO_UI +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is useful when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* + * Alternatively, this function is used to duplicate the user data. + * This uses the duplicator method function. The destroy function will + * be used to free the user data in this case. + */ +int UI_dup_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); +int UI_get_result_length(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parameterised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) + +# define UI_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, l, p, newf, dupf, freef) +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +# ifndef OPENSSL_NO_UI_CONSOLE + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +# endif + +/* + * NULL method. Literally does nothing, but may serve as a placeholder + * to avoid internal default. + */ +const UI_METHOD *UI_null(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called with all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DEFINE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(const char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_data_duplicator(UI_METHOD *method, + void *(*duplicator) (UI *ui, void *ui_data), + void (*destructor)(UI *ui, void *ui_data)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data); +int (*UI_method_get_opener(const UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(const UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(const UI_METHOD *method)) + (UI *, const char *, const char *); +void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *); +void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *); +const void *UI_method_get_ex_data(const UI_METHOD *method, int idx); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean prompt + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +int UI_get_result_string_length(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); +int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); +UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/uierr.h b/Hin2n/src/main/jniLibs/x86/include/openssl/uierr.h new file mode 100644 index 00000000..bd68864d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/uierr.h @@ -0,0 +1,65 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UIERR_H +# define HEADER_UIERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_UI_strings(void); + +/* + * UI function codes. + */ +# define UI_F_CLOSE_CONSOLE 115 +# define UI_F_ECHO_CONSOLE 116 +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_NOECHO_CONSOLE 117 +# define UI_F_OPEN_CONSOLE 114 +# define UI_F_UI_CONSTRUCT_PROMPT 121 +# define UI_F_UI_CREATE_METHOD 112 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_USER_DATA 118 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_GET_RESULT_LENGTH 119 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_PROCESS 113 +# define UI_F_UI_SET_RESULT 105 +# define UI_F_UI_SET_RESULT_EX 120 + +/* + * UI reason codes. + */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_PROCESSING_ERROR 107 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_SYSASSIGN_ERROR 109 +# define UI_R_SYSDASSGN_ERROR 110 +# define UI_R_SYSQIOW_ERROR 111 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 +# define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE 108 +# define UI_R_USER_DATA_DUPLICATION_UNSUPPORTED 112 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/whrlpool.h b/Hin2n/src/main/jniLibs/x86/include/openssl/whrlpool.h new file mode 100644 index 00000000..20ea3503 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/whrlpool.h @@ -0,0 +1,48 @@ +/* + * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +#include + +# ifndef OPENSSL_NO_WHIRLPOOL +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/x509.h b/Hin2n/src/main/jniLibs/x86/include/openssl/x509.h new file mode 100644 index 00000000..39ca0ba5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/x509.h @@ -0,0 +1,1047 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Flags for X509_get_signature_info() */ +/* Signature info is valid */ +# define X509_SIG_INFO_VALID 0x1 +/* Signature is suitable for TLS use */ +# define X509_SIG_INFO_TLS 0x2 + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +typedef struct X509_sig_st X509_SIG; + +typedef struct X509_name_entry_st X509_NAME_ENTRY; + +DEFINE_STACK_OF(X509_NAME_ENTRY) + +DEFINE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) + +typedef struct x509_attributes_st X509_ATTRIBUTE; + +DEFINE_STACK_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st X509_REQ_INFO; + +typedef struct X509_req_st X509_REQ; + +typedef struct x509_cert_aux_st X509_CERT_AUX; + +typedef struct x509_cinf_st X509_CINF; + +DEFINE_STACK_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DEFINE_STACK_OF(X509_TRUST) + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT 0 /* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC (1U << 0) +# define X509_TRUST_DYNAMIC_NAME (1U << 1) +/* No compat trust if self-signed, preempts "DO_SS" */ +# define X509_TRUST_NO_SS_COMPAT (1U << 2) +/* Compat trust if no explicit accepted trust EKUs */ +# define X509_TRUST_DO_SS_COMPAT (1U << 3) +/* Accept "anyEKU" as a wildcard trust OID */ +# define X509_TRUST_OK_ANY_EKU (1U << 4) + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional; use old X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +DEFINE_STACK_OF(X509_REVOKED) + +typedef struct X509_crl_info_st X509_CRL_INFO; + +DEFINE_STACK_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; +} X509_PKEY; + +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; +} X509_INFO; + +DEFINE_STACK_OF(X509_INFO) + +/* + * The next 2 structures and their 8 routines are used to manipulate Netscape's + * spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +#ifndef OPENSSL_NO_SCRYPT +typedef struct SCRYPT_PARAMS_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; + ASN1_INTEGER *blockSize; + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; +} SCRYPT_PARAMS; +#endif + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +const char *X509_verify_cert_error_string(long n); + +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +# endif +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +# endif +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + +# ifndef OPENSSL_NO_STDIO +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, const X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +long X509_get_pathlen(X509 *x); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, + const ASN1_OCTET_STRING **pdigest); +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, + ASN1_OCTET_STRING **pdigest); + +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +#define X509_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef) +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid, + int *secbits, uint32_t *flags); +void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, + int secbits, uint32_t flags); + +int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, + uint32_t *flags); + +void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_trusted(const X509 *x); +int X509_alias_set1(X509 *x, const unsigned char *name, int len); +int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x); +STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); + +long X509_get_version(const X509 *x); +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(const X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(const X509 *a); +const ASN1_TIME * X509_get0_notBefore(const X509 *x); +ASN1_TIME *X509_getm_notBefore(const X509 *x); +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); +const ASN1_TIME *X509_get0_notAfter(const X509 *x); +ASN1_TIME *X509_getm_notAfter(const X509 *x); +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +int X509_up_ref(X509 *x); +int X509_get_signature_type(const X509 *x); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_get_notBefore X509_getm_notBefore +# define X509_get_notAfter X509_getm_notAfter +# define X509_set_notBefore X509_set1_notBefore +# define X509_set_notAfter X509_set1_notAfter +#endif + + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf) + */ +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); +void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid); +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); + +EVP_PKEY *X509_get0_pubkey(const X509 *x); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); + +long X509_REQ_get_version(const X509_REQ *req); +int X509_REQ_set_version(X509_REQ *x, long version); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_REQ_get_signature_nid(const X509_REQ *req); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); +int X509_CRL_up_ref(X509_CRL *crl); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +# define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate +#endif + +long X509_CRL_get_version(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)) +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)) +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_CRL_get_signature_nid(const X509_CRL *crl); +int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); + +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); +const STACK_OF(X509_EXTENSION) * +X509_REVOKED_get0_extensions(const X509_REVOKED *r); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_aux_print(BIO *out, X509 *x, int indent); +# ifndef OPENSSL_NO_STDIO +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags); +# endif + +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); + +int X509_NAME_entry_count(const X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, + const unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(const X509 *x); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(const X509_CRL *x); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, + int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, + int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + const ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) +#ifndef OPENSSL_NO_SCRYPT +DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS) +#endif + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +#ifndef OPENSSL_NO_SCRYPT +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p); +#endif + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); + +const STACK_OF(X509_ATTRIBUTE) * +PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(const X509_TRUST *xp); +char *X509_TRUST_get0_name(const X509_TRUST *xp); +int X509_TRUST_get_trust(const X509_TRUST *xp); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/x509_vfy.h b/Hin2n/src/main/jniLibs/x86/include/openssl/x509_vfy.h new file mode 100644 index 00000000..adb8bce7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/x509_vfy.h @@ -0,0 +1,628 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +/* + * Protect against recursion, x509.h and x509_vfy.h each include the other. + */ +# ifndef HEADER_X509_H +# include +# endif + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +typedef enum { + X509_LU_NONE = 0, + X509_LU_X509, X509_LU_CRL +} X509_LOOKUP_TYPE; + +#if OPENSSL_API_COMPAT < 0x10100000L +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#endif + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_STACK_OF(X509_OBJECT) +DEFINE_STACK_OF(X509_VERIFY_PARAM) + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, + X509_STORE_CTX *ctx, X509 *x); +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, + X509 *x, X509 *issuer); +typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL **crl, X509 *x); +typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); +typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL *crl, X509 *x); +typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); +typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); + + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +# define X509_V_ERR_UNNESTED_RESOURCE 46 +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +# define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +# define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +# define X509_V_ERR_EE_KEY_TOO_SMALL 66 +# define X509_V_ERR_CA_KEY_TOO_SMALL 67 +# define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +# define X509_V_ERR_NO_VALID_SCTS 71 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +/* OCSP status errors */ +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ + +/* Certificate verify flags */ + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */ +# endif +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check self-signed CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.1.0. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +/* Do not check certificate/CRL validity against current time */ +# define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +int X509_OBJECT_up_ref_count(X509_OBJECT *a); +X509_OBJECT *X509_OBJECT_new(void); +void X509_OBJECT_free(X509_OBJECT *a); +X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); +X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a); +int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); +int X509_STORE_lock(X509_STORE *ctx); +int X509_STORE_unlock(X509_STORE *ctx); +int X509_STORE_up_ref(X509_STORE *v); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx),(func)) +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_fn verify); +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); +void X509_STORE_set_verify_cb(X509_STORE *ctx, + X509_STORE_CTX_verify_cb verify_cb); +# define X509_STORE_set_verify_cb_func(ctx,func) \ + X509_STORE_set_verify_cb((ctx),(func)) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx); +void X509_STORE_set_get_issuer(X509_STORE *ctx, + X509_STORE_CTX_get_issuer_fn get_issuer); +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx); +void X509_STORE_set_check_issued(X509_STORE *ctx, + X509_STORE_CTX_check_issued_fn check_issued); +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx); +void X509_STORE_set_check_revocation(X509_STORE *ctx, + X509_STORE_CTX_check_revocation_fn check_revocation); +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx); +void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl); +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx); +void X509_STORE_set_check_crl(X509_STORE *ctx, + X509_STORE_CTX_check_crl_fn check_crl); +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx); +void X509_STORE_set_cert_crl(X509_STORE *ctx, + X509_STORE_CTX_cert_crl_fn cert_crl); +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx); +void X509_STORE_set_check_policy(X509_STORE *ctx, + X509_STORE_CTX_check_policy_fn check_policy); +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx); +void X509_STORE_set_lookup_certs(X509_STORE *ctx, + X509_STORE_CTX_lookup_certs_fn lookup_certs); +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx); +void X509_STORE_set_lookup_crls(X509_STORE *ctx, + X509_STORE_CTX_lookup_crls_fn lookup_crls); +#define X509_STORE_set_lookup_crls_cb(ctx, func) \ + X509_STORE_set_lookup_crls((ctx), (func)) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx); +void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn cleanup); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx); + +#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) +int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); +void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_cb verify); +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx); +X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define X509_STORE_CTX_get_chain X509_STORE_CTX_get0_chain +# define X509_STORE_CTX_set_chain X509_STORE_CTX_set0_untrusted +# define X509_STORE_CTX_trusted_stack X509_STORE_CTX_set0_trusted_stack +# define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject +# define X509_STORE_get1_certs X509_STORE_CTX_get1_certs +# define X509_STORE_get1_crls X509_STORE_CTX_get1_crls +/* the following macro is misspelled; use X509_STORE_get1_certs instead */ +# define X509_STORE_get1_cert X509_STORE_CTX_get1_certs +/* the following macro is misspelled; use X509_STORE_get1_crls instead */ +# define X509_STORE_get1_crl X509_STORE_CTX_get1_crls +#endif + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + ASN1_INTEGER *serial, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_fingerprint_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const unsigned char* bytes, + int len, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_alias_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const char *str, + int len, + X509_OBJECT *ret); + +X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name); +void X509_LOOKUP_meth_free(X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_new_item(X509_LOOKUP_METHOD *method, + int (*new_item) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_new_item(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_free(X509_LOOKUP_METHOD *method, + void (*free_fn) (X509_LOOKUP *ctx)); +void (*X509_LOOKUP_meth_get_free(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_init(X509_LOOKUP_METHOD *method, + int (*init) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_init(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_shutdown(X509_LOOKUP_METHOD *method, + int (*shutdown) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_shutdown(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_ctrl(X509_LOOKUP_METHOD *method, + X509_LOOKUP_ctrl_fn ctrl_fn); +X509_LOOKUP_ctrl_fn X509_LOOKUP_meth_get_ctrl(const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_subject(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_subject_fn fn); +X509_LOOKUP_get_by_subject_fn X509_LOOKUP_meth_get_get_by_subject( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_issuer_serial(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_issuer_serial_fn fn); +X509_LOOKUP_get_by_issuer_serial_fn X509_LOOKUP_meth_get_get_by_issuer_serial( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_fingerprint(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_fingerprint_fn fn); +X509_LOOKUP_get_by_fingerprint_fn X509_LOOKUP_meth_get_get_by_fingerprint( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_alias(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_alias_fn fn); +X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( + const X509_LOOKUP_METHOD *method); + + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + X509_NAME *name); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, ASN1_INTEGER *serial, + X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const char *str, int len, X509_OBJECT *ret); +int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data); +void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); +X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane); +#define DANE_FLAG_NO_DANE_EE_NAMECHECKS (1L << 0) + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); +time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, + uint32_t flags); +uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +/* Non positive return values are errors */ +#define X509_PCY_TREE_FAILURE -2 /* Failure to satisfy explicit policy */ +#define X509_PCY_TREE_INVALID -1 /* Inconsistent or invalid extensions */ +#define X509_PCY_TREE_INTERNAL 0 /* Internal error, most likely malloc */ + +/* + * Positive return values form a bit mask, all but the first are internal to + * the library and don't appear in results from X509_policy_check(). + */ +#define X509_PCY_TREE_VALID 1 /* The policy tree is valid */ +#define X509_PCY_TREE_EMPTY 2 /* The policy tree is empty */ +#define X509_PCY_TREE_EXPLICIT 4 /* Explicit policy required */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/x509err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/x509err.h new file mode 100644 index 00000000..02738531 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/x509err.h @@ -0,0 +1,130 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509ERR_H +# define HEADER_X509ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509_strings(void); + +/* + * X509 function codes. + */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BUILD_CHAIN 106 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_NAME_CONSTRAINTS 149 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DANE_I2D 107 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_I2D_X509_AUX 151 +# define X509_F_LOOKUP_CERTS_SK 152 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_NEW_DIR 153 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_DIFF 105 +# define X509_F_X509_CRL_METHOD_NEW 154 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_LOOKUP_METH_NEW 160 +# define X509_F_X509_LOOKUP_NEW 155 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_CANON 156 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_OBJECT_NEW 150 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_DECODE 148 +# define X509_F_X509_PUBKEY_GET0 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_ADD_LOOKUP 157 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_STORE_NEW 158 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 +# define X509_F_X509_VERIFY_PARAM_NEW 159 + +/* + * X509 reason codes. + */ +# define X509_R_AKID_MISMATCH 110 +# define X509_R_BAD_SELECTOR 133 +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_CRL_ALREADY_DELTA 127 +# define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_IDP_MISMATCH 128 +# define X509_R_INVALID_ATTRIBUTES 138 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_ISSUER_MISMATCH 129 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NEWER_CRL_NOT_NEWER 132 +# define X509_R_NO_CERTIFICATE_FOUND 135 +# define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_NO_CRL_FOUND 137 +# define X509_R_NO_CRL_NUMBER 130 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3.h b/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3.h new file mode 100644 index 00000000..6c6eca38 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3.h @@ -0,0 +1,937 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, const char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 +# define X509V3_CTX_REPLACE 0x2 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; + +DEFINE_STACK_OF(GENERAL_NAME) +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; +DEFINE_STACK_OF(GENERAL_NAMES) + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DEFINE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DEFINE_STACK_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DEFINE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DEFINE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DEFINE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, \ + "section:", (val)->section, \ + ",name:", (val)->name, ",value:", (val)->value) + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +/* EXFLAG_SET is set to indicate that some values have been precomputed */ +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +/* Self signed */ +# define EXFLAG_SS 0x2000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DEFINE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, const char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); +char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); +int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *name, const char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* The new declarations are in crypto.h, but the old ones were here. */ +# define hex_to_string OPENSSL_buf2hexstr +# define string_to_hex OPENSSL_hexstr2buf +#endif + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +#ifndef OPENSSL_NO_STDIO +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); +#endif +int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +void X509_set_proxy_flag(X509 *x); +void X509_set_proxy_pathlen(X509 *x, long l); +long X509_get_proxy_pathlen(X509 *x); + +uint32_t X509_get_extension_flags(X509 *x); +uint32_t X509_get_key_usage(X509 *x); +uint32_t X509_get_extended_key_usage(X509 *x); +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x); +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x); +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x); +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x); + +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(const char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg); +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(const X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* Never check the subject CN */ +# define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +#ifndef OPENSSL_NO_RFC3779 +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DEFINE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DEFINE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DEFINE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); +int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int X509v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int X509v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int X509v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned X509v3_addr_get_afi(const IPAddressFamily *f); +int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int X509v3_asid_is_canonical(ASIdentifiers *asid); +int X509v3_addr_is_canonical(IPAddrBlocks *addr); +int X509v3_asid_canonize(ASIdentifiers *asid); +int X509v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int X509v3_asid_inherits(ASIdentifiers *asid); +int X509v3_addr_inherits(IPAddrBlocks *addr); +int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int X509v3_asid_validate_path(X509_STORE_CTX *); +int X509v3_addr_validate_path(X509_STORE_CTX *); +int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, + int allow_inheritance); +int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +#endif /* OPENSSL_NO_RFC3779 */ + +DEFINE_STACK_OF(ASN1_STRING) + +/* + * Admission Syntax + */ +typedef struct NamingAuthority_st NAMING_AUTHORITY; +typedef struct ProfessionInfo_st PROFESSION_INFO; +typedef struct Admissions_st ADMISSIONS; +typedef struct AdmissionSyntax_st ADMISSION_SYNTAX; +DECLARE_ASN1_FUNCTIONS(NAMING_AUTHORITY) +DECLARE_ASN1_FUNCTIONS(PROFESSION_INFO) +DECLARE_ASN1_FUNCTIONS(ADMISSIONS) +DECLARE_ASN1_FUNCTIONS(ADMISSION_SYNTAX) +DEFINE_STACK_OF(ADMISSIONS) +DEFINE_STACK_OF(PROFESSION_INFO) +typedef STACK_OF(PROFESSION_INFO) PROFESSION_INFOS; + +const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId( + const NAMING_AUTHORITY *n); +const ASN1_IA5STRING *NAMING_AUTHORITY_get0_authorityURL( + const NAMING_AUTHORITY *n); +const ASN1_STRING *NAMING_AUTHORITY_get0_authorityText( + const NAMING_AUTHORITY *n); +void NAMING_AUTHORITY_set0_authorityId(NAMING_AUTHORITY *n, + ASN1_OBJECT* namingAuthorityId); +void NAMING_AUTHORITY_set0_authorityURL(NAMING_AUTHORITY *n, + ASN1_IA5STRING* namingAuthorityUrl); +void NAMING_AUTHORITY_set0_authorityText(NAMING_AUTHORITY *n, + ASN1_STRING* namingAuthorityText); + +const GENERAL_NAME *ADMISSION_SYNTAX_get0_admissionAuthority( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_admissionAuthority( + ADMISSION_SYNTAX *as, GENERAL_NAME *aa); +const STACK_OF(ADMISSIONS) *ADMISSION_SYNTAX_get0_contentsOfAdmissions( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_contentsOfAdmissions( + ADMISSION_SYNTAX *as, STACK_OF(ADMISSIONS) *a); +const GENERAL_NAME *ADMISSIONS_get0_admissionAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_admissionAuthority(ADMISSIONS *a, GENERAL_NAME *aa); +const NAMING_AUTHORITY *ADMISSIONS_get0_namingAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_namingAuthority(ADMISSIONS *a, NAMING_AUTHORITY *na); +const PROFESSION_INFOS *ADMISSIONS_get0_professionInfos(const ADMISSIONS *a); +void ADMISSIONS_set0_professionInfos(ADMISSIONS *a, PROFESSION_INFOS *pi); +const ASN1_OCTET_STRING *PROFESSION_INFO_get0_addProfessionInfo( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_addProfessionInfo( + PROFESSION_INFO *pi, ASN1_OCTET_STRING *aos); +const NAMING_AUTHORITY *PROFESSION_INFO_get0_namingAuthority( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_namingAuthority( + PROFESSION_INFO *pi, NAMING_AUTHORITY *na); +const STACK_OF(ASN1_STRING) *PROFESSION_INFO_get0_professionItems( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionItems( + PROFESSION_INFO *pi, STACK_OF(ASN1_STRING) *as); +const STACK_OF(ASN1_OBJECT) *PROFESSION_INFO_get0_professionOIDs( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionOIDs( + PROFESSION_INFO *pi, STACK_OF(ASN1_OBJECT) *po); +const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_registrationNumber( + PROFESSION_INFO *pi, ASN1_PRINTABLESTRING *rn); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3err.h b/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3err.h new file mode 100644 index 00000000..5f25442f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86/include/openssl/x509v3err.h @@ -0,0 +1,162 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3ERR_H +# define HEADER_X509V3ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509V3_strings(void); + +/* + * X509V3 function codes. + */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ADDR_VALIDATE_PATH_INTERNAL 166 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_BIGNUM_TO_STRING 167 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_LEVEL_ADD_NODE 168 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_CACHE_CREATE 169 +# define X509V3_F_POLICY_CACHE_NEW 170 +# define X509V3_F_POLICY_DATA_NEW 171 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_TREE_INIT 172 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V2I_TLS_FEATURE 165 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* + * X509V3 reason codes. + */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86/libcrypto.so b/Hin2n/src/main/jniLibs/x86/libcrypto.so new file mode 100644 index 0000000000000000000000000000000000000000..587d41267e487e01447ba7465b6996f581e7eaf9 GIT binary patch literal 3240184 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

l0&s7pR^`kWo;%L?#Iek~8U zkq{atN`;&{j0fv+$#}Q{pUfv3x+FWPt6Z>*XP3`xHVI>OlcdmPJSdOG#Tr~8y+F0q zoye^8l85D~I0|a~dMz9*?tizeNVyrYNy;st(c_C7tL1SzEWyJYz`@Vr38y*TNm@^R z)n+{PGVK{g5pD1Zh_Gj(e&0CrZGmJrJT4T$3gZMbCxw9vMhz}ITw=daG}Cl3SjN!Z zO>jDl9Wa3sMYQM#D7445@&%*>Q|bAo?=bZ0FFHNi^{U+%)Y}K)EhFmrWz^gJrgQ3Pa1do=es08B@GT>;!1qTunjqg!|)yg-K@)YsvXfhI1 z)M34S7(P*F>j66}?Jz3CY7~2+Hc^udUHLMpvmwnQn6%wSakjA&*E5azIj}S`5a6Q7 zJw|cBn4c@fhNh!A4;fubBew6cdmJ~mtvrI9Sh_~+1_tjF@aKr;{2s`V!4b-NN^kFt z+P;S?R_Il#Plgn`Z-+D_qqq=B%@6vXGM0y6bzpmNGt*d71l7s#Y4weWsuD(isovgW zEMEjKnbBp98U|R@8FFLh#H^*`Dl;-TIwhy5uj5F?5%oMSnOK&rFjT+4(&dztn598P zhQSM-p{X*-Qn_!ZBrkPpEU7?lY`#Is$y3JsN@NF@Req``^0TGu)eIv)Y)DjM0#R4Y zl(7xkQ8|+mIZbQ%_Ss5i2~|;CBRP`1NnVjHs0{g9`2@q`%E zXpYM?qmo6LcB~d_ig|{rL1|pc{MjOqtiGo(?@$)mi4eHrh?+MfE2u)4_mjAa;2lz_ ztinuI;lpBK(OhiE-(l0vBI^%}Ej9L_+U-)6Ni&Ptsx+)8nsFE9vLf47)cc4LH-0U4 zQpPNFU<_NvDN*QQ(WbKhdOIwFT(qMh%Vo?*pO#)6ph?L{nhPVLw|8^wu$dil6S9xl zwef3Zfd{2JVYnU?JFMnsna1i?xTU8?9WI|t-mJ!h@-`EC>FN$447$9%q_<-NDD9g% zG@xtLuMCI3_vg4)ZiAm%UPKe=p4=-$dD=L987EMmQ0D_w=RQ%BUxwi)I^hKh`E|Dt zV^fcCxA9;vIG7ky<3R_ex#NScilCOu9T3L{pA)%FEk?P1R_mFPBeF!Rx>GHopcYpV z)-#JxQd!i6u-LR3SlFe!F+RSkQ;&QW@0vs(l+}yzdZVWi)Kwr`xl*EH)xOMtTr60jeG6Un;g+)t6`t!Y>@{kBI`BQs!3@gLWU zTrRnI0!C>p_4u9~En#5t~(G?cs1f$t85e?FL-%;IYiLS7o9~biLNs)}d{|K$o z6}Iyud_Qr)uV873X|frj{C;Pe zuL~EZ`i{Vp-u|5#s*@J^3$Z*dm<}&8O(;nBy^ebbVMQ7~>Geha5WE-66d$9wr>i7q zAxA~<a=$|+Q)ozb|LjSVEQ{aqpUPCi{OO@cngTk666E?OWX@tTs;J?Y5oZn?4X}$ebzvI_p zXfa@+Bq(6C66*%oK;*>g_e7!=7qXw}udt~>waf2$0C!P?y-~}9P?TFua-4`lc8<(w zV7+A?lH>AwzK6gLf0cAQmpO~_dmh3y7|or2&x4YxET=OO-eCrlFgBO}4u|-f90VGY zAaWTY>}ocGP%>Uwq?;ncPJdyBu}Ab1hw_mho8N{q4*PAtMrAoUsgqiimANJASt%v; zdzuhKodv-w)I<$KA_gO~q!?=YqLzn!@w!U%Mt#*M(fDCKWZj=>ybc9qA?r?Pw(I4z zsN;Skk&4EH(0aRNr8z1|d)bT3dC|DB)prD8EPgA(qdp`Z35D!-M=h%*0EXBd=Bg*A zrd)G|LsW{2mhov^7|84F8fk`qxvKgdx5Y z{(LMoUl%n*ZI5xTB@F?!@Frl1W<83qp_MPo49+(iDbS5g=uMFlo6sI9nJKhJN@ig{ zDx1d79Cl6nhb>^(zuT4liy_8bLc z#=JCiK{Rx9a@j95?O0Ixn%ecU>3xPjgl;x(I((vW-ef(`XS(uk*WNIDUn3c)^;JBfnjBn zB#xjq35pb9Jp8uR=p-u9LYs8WPPu|fFgmH<_JFb-PTY25?Fy?kn1Ns@A;L*!{WsVR zEC}ps7J1rb-Kk>&DVf~@K7_3AqO7IyWcEhmjm@`en| zG2{aU-K)2+`G`a!yUwvleyZ8?E-^b^af*S)Di#yHuNd9POwdT6%TG$kUu>C3OEO}b znX^)pS~)kZX=Yl*7ABS^v>Ne9G4|+T$j!tMq1{Z*Uu;drIgwn_rX_DAi-wjqIXSdV zDcuaFXl07iRf>_~bgXpHf3i>m^-3E^{IjAJST5CXMOkXAs_@XcIx$y;3)z`*$ou&$0BZU z$wGG3t9pHdh#Or^B980z_d%@N=#o9Y6#ao4AsySQL%>iCch_r{y?|3hGnrn(zRG$f!OM{+6}DR3~Xyf^GBoe$D+k2{nL#6QOSlMi;4V%F@MZofSve+ zzr@yfpB=W^iG_CYN%UklCNcM5(a7?s%r>}cCC_V=B35q2UA^mNOUkj7BheINN_3vZ zxYiP#XEm<1M(5d#Yi-eK#x)FcXl9t9nzcanA;Yd{$QHFm0~RP_hN$uZwElLwYWL- zp>w;YlB1uOR#k~WOU8UbJQ1$Mz}1r4_?4p=R_|xn@gt8Cz77LCMjB&?fM?4S#4A)E2taQ@C&%lpCke zt6SBxvXfx zNii*$A}LiN0QZ27WPv^k}hhp2>x;q zgZOnDRimiXQsc(4#rpE9gi*qJ!-NE0a`aV&s5_&F*_QGRA{wZFNgRKuim&fGQ+Hc% zDd@_Qyu*dXH*W7TYi`L_xKXFc8v8EBCMe9bC&sqHD%2R%im*%Gl$Hkdx*>bTbQq_H zqS!jJ`p`45k(7@)F4}8jo%I(-)vG0YzBf&i``&Zz_x!tg|F^vV*XP_{%lkjT{WJR` z+n!V7-`}b6ub!<6J-r2?kzd)Ml$Q;@YE?}_Ml=~5=Zm<;B~PkkNcs{)83wNe@sf@H zz$`e9*1KfWRo7SbPctvqKO&~p92Xn&yeL*?<5FkpM&%DfqVf(kxb@Xx@yQ6<7ki{!rEF0aItdSMLo_QDi!9ykTO7EA@d3|hckFb&KDr-J$5 zG_U})f`#C8@H#LZydInZ{w-(&u^cO$skaAa!F_`_*EL@)li|1#Di9r`jIuRtK{-7J z4A&=K$7t9-)jLgZ&rk8nE>`{&Zvp0@`KjK5RKVgbz$3cr-U8$)f0nmk7LpC=?ZrAeymXT? z$VGEY^txB=b*FS(D943GkrHuMz$x~%61(0H+$~dcvl5dn3SFuW^LfxE zDx?huS{2F&$F)WRpJ-GlA{=N%^4b&T2oTVeP*6C~mQYeS(3ntEIMAAqWjN5BP*^z7 zo={piZV-nX4%MP^;F#Q^P)gOB`bMNRl0Qptzf(sDw;|7KLv!mMvBo{LzcM)eG_>^i|UeeS~Pkz#b;Q2N}3>1vG@nlX3bj7Tv$aL6`yp)FDj zC52|rU1%yPG;8j{S&?EWDWK2I(wv|n-9}cFwL8f92Qu;`N&?ubZ$^hiNI8 z;mt>`3T)ndWT{}LHy@Q&Fv}}7R-ns(=S5v%E@hAAX?0t~Hk3v4WZqjI%}W3k(Y%wY zw&1QbM)e0;#H>t=P*N)xwq#^#ywBSh8g0yT;;vk-dttOOJlj6!%^}By<|vqN*J1xo zCVTTOKyGxtJgY5?&X*T5g0TNysu?>A>G9p~In z&R9};|99uyPtI6gTscj{dnfUkxWBT?e-q{^D`ytGIleh+b8Vjde(i}qnao@y9?D&3 z-YLu7Q$Ud<9 zI^CY$c(Z-!>yVz?jd^<~{&_KRCAqPUXjN##f#NmCiwFX`bgex{82WdZH1xSV_yAUGXBAt-cyd3GP4~U!=bW+~oRpu*%0L1KC*|k7P`E!?Eh0|N z&)MzQ)Q>9E2-ce;qws#<8M8%;6N(v0=ynTQvwg_kB$qBw{sTwk#_@O1pWIh*BQnus z`#Z;kyOW!eh{#>`a}vdKiOt4Q_U{X}FZdCqOqA!~nerSwzdRSx-$5zQ!Aa#gPycdX zGIMZJdEOx=_&l#pk?)9{Xd1N#Ae1N_`B7PkHt=WEb-#wo&Y|UhZ^rGtBaQnT{krIEbFY# zz7)4F(P!T#p>DP7v%e`J7d!RYRT6rMSD*bIiQ%4rK6^!|aYY&2Dz^Ben7ZO^r)LoD z-5rQW;*j7HQUcL`U1ynIe-(1B+b^k0IPdzRZokzY{-$nU?5s-!?pm(fkw(2trF1(I zDH)G1Lc|w{Z%|GaVSjqtp#b3qd*Ltnos{_B;t&}|HuxLdIH&yap)>a-^Men;k4&W5 zzT&^aF3LHX8T_{RY5TN{V-pqdFYmDe3eSEY2T?x0v!n~_e~GF8dgZ~? z|9Wf`ol|6~&!O*__WZ1&_}rlr;f8LUtiR79YkL}3*q8oev|MfEx%JtXK_&05u4MoCpVZfcmZZ~ANAEnb z>w3}hxM&z!T&#;CQ2IGA<{xt!PYzk6nVr!E)S%Q+7f%V_kyO5@eN-x-&!rRM)yMxp50!fjWS8a(^PYciqw>8QuDlL&YGn@^Zu&{<$JsOk+!_ZY|A0p{jC26 zEUYx@cWKIx<5{3IWqAM|#A{o4AwZh)V*Tn%-b%&iCr+iBT|!3kLXIXZ2&CfnMJ^0I&Eq5pcqnHqr((w&8iCI4LxVyIKPi*>v4c4{0|+Ar{Ss7`DL}|dr?f39HoehkuEusENyZSAKZZ`CfRe{elgp} zyR6BS;d>o6YA}KrCgyALKgc$+{qq>>q2fK#FU^_5P`P?O5WfWvB`4jtFGsB?KP9gu z^EPzVne}&k244A8yaZZ>vPQP!Z_-eLr#wzv!GHo6 zs#k^;xB_sEqt}Ma0YVcfRd>=iAWRd66d&x!L>swu?zd+HYYRf~1cd&!C}WzF86j z7bEVG{ctQ1?f1iRPXLZM9P>kPjH>Q6B4!9CLatzHuDU&jWJu*we`eRm*p3TfWpNIm zi0L9dtZq))2JDp;_yy@6&<@7Z6fH==&9857Gn z``@eKH7&I{X}y36mJWXZFVS+(F~4elI;q$GKW~54p37wWdvLP-m7SODgR)u1&6W7S zpaY=^2bDqZ{J{POW$5|~+24WT|IPOIyoLXJx4#*9J^U|VfB*GNH2+QeTXOjQ+uvt7 zGaJe?ALO5T-T-r}?5|!g&z2_H;N(QioGF|=fYU@zjO;^*WYDz4mt4RQUs(Hk`+U1R zOodU`BPI6pjXDNjOpniAbDtm8UJPbZ2K@a+Oga^$o@Xh0F0a0oV!z^?eNId%Qt(t< zW*IYZ-(x(#a#;4IV7ccU>*}{O=1y(K8!0sy(v}%~=}_&49@_%zt1bP8zHv+4mK69z z3^}QW%q(U0fO23lD6`#>eXuu}5S*=na~~(^CE^WlQdRBJXBS;L8jYwmzI>Hx8EpKY zWJhAoQ+Q9OTGpw^QTVE@`U9(xhas);hLpy<)W-YL>b6YPH*VKAcIq3)5eS*;dPVYe zG5#{;%@>)^zW~95C3V&7aO8Xe8I0lYzc3`qTy*3`ILry|FkEVqJMt!6rj5lbe3;1v z@QEq0Y#gcbBBHn507jIe1W7|y_wsC{7k~Zu+lfCcpGS7#Zxnxc3s97X$$Ob@52lM3 zl_fJfW>zMddaPAd77%pOw#j*GZtQB;h!*32#$#p_8}InMTg1o&MhNUWuPC~*8K0$B zw&Jt=%1(S%UWp>F2w#Z>!-{2Bj-nRsUxtY`rq^?@TOP$3)M|1qt0}#H6F${6d5-Kw z*Z&5eW@VYxWY!V1_cj%Te2U)QU){W8tspk&;Jwz!d#eexfB5co5MO{(oRt32eBQ2N zQJ2)b<4P#F^h!HE%dd3ev+_zWKEqcA20txoobpQGHT>PmXU0epnIAz1QQF-LN_#(q0u4&?@he^s zgTEKM1h^y}eWyO#aiu;RWgIM$v?k8aLK8VFz0V?tZ2Z#-CV-kx7~VN0s@B z#ofy)*CiuLiBcAoc{o&o&|so#T(u|(V&Tq04vaAm9vE6*a2NSu7tx>z8x-8`A)b@<$K{WmH$4*AJrQ#H1@npkHqLB zGl%5!vUA6Sw;6w`u+E(rgJk?UqzwMY4@@3+^peA-(Hv4nQ+MwiEIBjKndd*Ao8G&P zKdjElqmYb1GWxutvhZzWfmS)WlO>tJeb|1n+86^NJW2CC()&L-{xJ8GW|}hcjHrx1 zHYww0k2;cfePZO1(RO0=8R^w$W9)&Co&P_MKUn7&FQO0`bwlc6H3^wljGxAi$WuDW<=DC3;{**SQ0KKo19cg1XC(snVV$#0*;i=^cz zAGS&LVT(~7xb>S)YX;4SP@|ASdI@&d)ov*Io9~n0`GR{$)&Q&9qzLMj6R*B{pAwdMWjV0=gc7hJivmgn zcmd@X&%Rq`mt+5Sl(~dTpOtKa1CmkjRqWU5Zt3?&p|e3b^M-0WcjkLR>vI}aHux9< z$@>!f#ANK_LohcU-Hbd7ZR_q+b#dolqr_}ZzfF4)kM5uFU-FXV(2ckBBxAQpw?`Cku;b5tHVUj;lhruU3vg~%7hRvZ{DYY z=Gz<-?Qh`%=^+=Tncw+I2jeKRc1z=rpMksaS53FNQLma_G7!Dff;U2O;FndiuRN{} zBCY>8de+M0od}@U{~Mag%Hy@-UbVxLRNKl^xPYf2(!?L1E;naiJBp{;hk8=t_drz6 zDe>ErPD}hNNvAb_W727l=O&%b_*F?~ApZHJvo`+8r1PWkjHL4l^>(p7dx~*=XmA$t z1bxk(f>P*PaW+gzH_)K49ZjH1y(S9V_SwhrMJHse>KkZsRWXd0lH+V`3qGFfUaa3W zmVzj73v1Q8PgtPS^BvNR@N`~h}&lBnw%*ud4KaCO^9SuvCVqf)xU#zJ-@dq3G)E3!z3)B_5_$ z@5it@^5@OxJipN0`}M8yTz&TC`quxNuh0I9yv01UVWNE_;%`gr-*Bp0WtHr`2$wJ( zI}W&5js%;E0R~I#Kqn!zn1tN$*Y$5 z^5j)(d_nT6HC~atYL9<0dDR}jIeFC?|4j0#GoF*Y8i>z^Q&pDT*E!e^LFIq;Meo>O zlKtrg^rt?3>kH^l!1hP*#>Yf|GSxo~F^Zb{MfGq<+0W?zUG$FX5mh7DlMM5`#;5f@rX@?Rh>(3Xv|GFXBJj{HZ(0S*vnVY zWUgUFNuKSLkL|oVJAjAe*ND{<~1ojRo^=Sm6Bnz0RDk zRaf6t6{xDdeaYQ-SAM?gu5Vs5F~6@(vCh<|rp=mS!;65a(=4^qX6RGXEh*EjX;W;o zW~S=r{L`v0|H|6_MU1z`DpDdUxd*wyMKD*L)y3gaNEzr15cg!o6pYM-SqJXQ>LV9 zqMzyMGpwSw$!@uqyq@$Yev)pvm#U>q5e?6`+iiLZX;@zWpE?l@d`;I~)Y_MMOaWb9X)=DD?kfuDW#Bafdx{=~<= z((+i(>Mdi8qE@A%BuZ@MRM*Qx&+-0;(msCHY?49hJc{UdqvXMcR&^&ir1Pb+)5 z?#0z>j(mUYu1mjjk+ygBj~1k6uG${_=Nm(p?b)GSw{O_E^b4K0|NO1T{>5|aUE04r z`tqUPlKZa8y*zU9kC(iuJ-O9&?8FN>e;zsbp_v)JIoh>t5C3ENCt{Yq*ISR~f4WTj z=HKo7_qA)fzWvC;x!2gn-_T-xpMLlsU(atn+E#8UyY>@W*CXRQ|9zot?lph6_S?Ekx!f4igj_HTsIokF+Yb?4IX z*TQ#HEs;*8x>!y26@R^8!Gb)$$9cmY-@e^h__aH~zVxndI^7GxUt5AcSngc77lS2SI*N1u)x0r!zdV4!CD|xj2*;rwyh*ebYmCcbcr@{x zC)N^!X7qd07;}~-#5k#&Mk+C&fJD|QyBIB`Kf8L81Dc}vUs_fp`Z)O)6lRS$j zEY7PA!3$;$*&2q1D(nf5JSPJDR$(zG*)bCoZ!r-Ln1vmAMqhOm-WG(v+sp8gS1mVD z3^Rx%8k`Y;h;kq|_-Tfplwo3XmI4=aN{$Sqjyy@UF#pM{A+4$}$LfxFRd5srQK7(9 z|ItcSqTG!QGn(;~WiX0MO}O_B$@SlkG9%fVjA)|9Pl8CK>Tm56w`7VsabKpdrU#_L zx;Wc|6hy@kx_}2&16S*>+QgI6x!F9B8?$++@=3rLGI5^1F(+2~9)a>i=NHiT6vPaD zf7sObH_Dg^*|n_tay33?%N1!pO52-cOh)^KN~hxH4+0pc!2OM11+af@iGK-Ifh&ns z<4dQ?RAJ~tkQ!#nU?wr)jkpybf$qO3?e;rM!=LO(ha-L!ZWrqHvL1|o4lxY9Dia@$ z=SVEy8h_bLY7|)+&@US6z*0hsr>Kip>szhyqj1J|%SHM1*0`)k3&Z8{Ln8bh!qC&n z{Vj>l9)B1&I%Gl=mtU(zCP(AHQDMCCU#Sb#ooIr1?&!e1)A3EX2M5HVUFXby8-G%Z z04Ok4gp-Pj&RK@*b(@@Zn2+ z#m6>z*n`*NR3OAywN=092hY;RDY_q@9`lTH5=dSU?5 z$GJqpVtJw-Fezgu<;~Vmtg2#F8rgji(|M~`u2UiO5MXH2L+E@DWoLP)p75X=&7|gp z?_Q3=SV{jmXTFu3XPw0 z;(h73{9d`dwD0RwPnMKE-bZ|R$E>mFBlbT*b=Ym&Jy`d=v+jtq@pIicAuQg9uN6&- zdt!W&_!~d>uj1them+@Vkx*He%|o?o$gGQzi64RwlzEy&q_ViU$qfHB3IFK3hsSqu zE)f3Q_cE{>rQa_bXeuYzvXPwNnc4#{A{RGkbB-xp;z(yXC`S&o-q!fJLwGGa{@2Js z-El2^^^kRveSvWt>56|+a+m4C@&o;?st4Jy__4Ez^Hc7AcIcW3eMmXcJ=M#}@|t#B zzE3m}ZbZFdi029NPW z00+yg>B3<%Yc^STFTD&u%Jfm(EsXx79hHdUx$92Y!;ZQaPSu^Th2@AZPx9Oby}cq; zyz1>W>WlmS%k_49*DLrUs#OlGJB<6&d~(Khq3^i=TXOD#9QLcOHaI*?HI#?0 zmvG`c#2I+A1h4bd%=CW?U+oWBB{l|`o(z(%PE;+FAg>{aj^iO5#;&f{GW_3?vl!H2 zd3#iBvy2msf5?90D8Ajl#mI3X1YV=b#PQlV1-9{@vX9{$AN;hzZv5g4ej@8P+2cpY zarLdE<2Zg1ky`yY(ptWj-QMNTxgVO6(}OJPoP2+9m3&ECzD|;9Y|-0eINMK-q|ExE zIu%2$MEzm-!4qdWmobjB1fw2_!vS?zd~f3XON4@d2?b*Nu=*{Jq8>BkeAFX)`w=uz8!j2I!C~>8_FLo_;7s2(->C11 zaSCV1Z}Yu|H>^f+bT!UOeog(v#yB#+^5t=ydy3-NeOrw|9B9~|VVvSG4|G9qU7PH_ zol;`+$b3w>Ln-*xz}wfm0wM*QEBFW5M6<7S)|?|WVJZ5+nH z2Zu|Y2kWjoJOzSNuOGwcuGH8iRX=p`1=h?+7nN{Clws^tnm!fHYULT3S&u|5vI9>1!~u?+#LZ5B)&mj}p%8Bd^!XH0RL8+@$GMu4Q@`!^ z@R2d`0|^csQ!G~`HJlduJKrYX9$$}dH;z!=g%0D})P*BCo-&RYdvUlgw2b<|S+u~) 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 jibkyT`wzc<73K12ei2 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 T1MJBlMor04TH$3QY;>@5a#VM< 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

ZuP7yiuK-@t z;Ix70zKnStYxyqx8H~V_mtj{W>Cp@?!~r3MlVh|EqS=i_>44`{h2@0{1Wg{>w|1q+ zz#XxmxNM@htXx%7t~|Jz5U>_LN1SFn&~Txk?waEAwYjp?ZF?e5HVW1dV?YO=m63oT zWKKP7qm99sO7c9V-h_cq@Yc4!64QCmL;C*F{>IQ)>buMl;Xo_AcY0nPY2VR^ug~ti zroCTBT{d~8vDA+R!Ca5`-ukyVxAc{fdq30OKh)~JC=%=Vin5s!TAziBIuJoebU)Ga z`pCWC^Dc@$#HmOn5A4U!Q9Iyu#RHtR#4Rr)xA&B0>N7mavo~eRAF^8%y!5%uqj=iqImJ?{0zt&7oYPHWox(X>HG}LmSc_|^m&E&ru~Cbudc0j{l-kIHY)(RJbemhdiA_9 zQaj0pcq7^l6o&PFru=?6(w9f>y~g%6G{KT6=d<;^Hd4y#^{6(jx zD7||?T!VWR;?qO=5i7ZrWM7h32Tln?l)JA|?^LSoZdW=2D0xVDvft08pXv6yAF)kA z%Sp2>Xn7PlPxH^%9MMrnsaGiAv03Am4LfWD*3PHx3bnl77~HS&U(Kaf`OoW~K8ybM zaGKNN)g;=x)i3FNTlF^D-X8H!Icz6g^qi02Wk7$R3eiWMv!1J7Giv{FIxS?NHr#w`UjFC+xBje5%p+5G{}3z zMrv?^=70bdpfmV(8Y-%Q(W~{)epY7Q|(vVCFn$2yAIX)RC&z! zOAz836A=Afogfvf)Vfkou!D0dZ$Pi?cr5mV?uM1Ily--D%9i;ebljIog$b+ z0q6?0srh$8lW0E!w5}~`!MFC%f^Tl31!<6k0p!F)aGR{rU`$!yu5F9F7q zEBP=WxN9?$N=h|s+%+UNW+k$iNn$;xex>?Az?iW$cGd44>b5#lHl>5GO$6Nw)#3ec zY!YJHC|`p-{XT33e0py1$`k$@JagYDk$wPel+)*Z+9;y|uuOhB!Z&;1Sr%(V&$mX$ zQje*OzM-_Gv()&k7+F(e{x>I>UK!>)9d(xeHPSOl*W4b8)~d-*9JT8BZ0w3lfa`cG zminAnsJ&vS9y@#yS%i8tpb+MNKKC!RZ)T|+1V<3iDv9k$!&i!;nrs_2;`2?0kq()rP(-7HS&YVYFgkL8a!MB zUa!AP{*Vll@tGy@DgQHd- z|IY05!B@i(H*!8vZ%rtC;-;Bl>6f2D1AyZDRl>K%@|<>RH0ZzMu-B9lgs3lgsI(-z z77B2E`ZSgrOHWdgeT}r-`~Bumo_kyVWb;LVKVgl&gJb*_s+A0lWB2iPBonW%m$tvQ z>-Oz!Wx`Yf%Qt=Eg09n(2!(vW_=I6ZEysbj0|fATnb*sBtH%IFD+ zhtJ=0&u9t?RUb z6DDv(x75Mn9_fR&T4e7+i}4S7))pyugcSR);h5jI+N97b-*BfGhb+a)>~R>U^G8;n zqN9BCi`o-;r?A=CFJn-uO6<#4yWpu69P$?0E~bt{!>aB>xeCrmq&Md zyBw1{9rb5++bkB`z^x!Oa4r{`A;{N=(b+IWv!Ee1Hcmw2Sh4TlvEZ z%KJY&N%TkkYwcR*U&%FnR@56C&(mMFNBVt)l^$Cr68>hlaoujaURbP@_4Qe@Z{(}&B~u&RNmU(Dv#j!_%*vVKAz2O@7QXTtfY5rjk}oV>K$9} zo-~(BUL*Qv6c6C{UwqN~&h*{rEwM_h-S6Q*(qpaN8@cTrTP~b|po1Phcpn)FTxA%4 z;V{0MCW=FgYSGmOv=?8<;1cCw0u$HeZzO~vX>3P7$+Rxm=l^Gy{Hcz&OfGE)rN=f) zo9XcU`z_D;BxtbXTEb&acq}~cMbp*W-%tbNj+~c5a)c>RtP5RTCt-=vVQSaq)mU?w zdpzU5_Ln|r-yWHB6oqBznu8*{i8lC0A1M0geAYUyDm<0Frz4}jNT}K$X1F56?L2Xf zJfdqPKS;UyACZzxE7N1EGcBKO?;dI4@LmP@ul}6zXK_&7cR!6JrLpYD+CWF5x56@D)Da!c)JV*WH{foU{Fwy^-75bhlr1ASCVxRAN+WhBdSK_@H zVV|FlGL3 zqJQ;k;@>Uj=lGZCZ8B?-@F`dluxBgQh4NMy^Wjm*&+%6NE3W+Wv{g%Uajvzl`DNVd zJ#n!?qm>9(i%MSpkRjC3N_l=y^mo20dJf3bqgf3hsmilcV_@MiIUkHdi!kt9f_xve z@*AdEdy43hUN}^P(lerZ5PD>fGYsPbhj9yTK`R|q>2ZNonXh~r?%)-Y>2aDq!Pd+T z{n4c!lV)|-Qcclrcd3=>apm6F^7OcfH#R~8;^Dwk?a;INg^SFHW#TKnZ68<0mma(ew*t7hgzHU5~jU2kY5R zs?L=q^GzZdc%Zdi7b6$AttR*YY*hV_%1DBR9EktLIFK(Zw^2}jY*2pm9?GwKevtCe zVnm+fZ5Kht&r4qtKd+l={9J}&O@o)y;pbS{KW08(#o-Tt*54V5M3fFDy^RQh(QtR*fV|ZWhZ_V8|`mb}3Ny!sx zsHQJeXvQzXa~aRIA`8a(*HS%QO9NfYo@5DZZq`)&Sp1}oc| zwVDh(yVgJyNslp`*^Ht{$m%}|=SdKt8}VMy<$vyX)?z#Nd4kRx6Bi9{qfyB;rAUK- z8IH<`@4F(YvsEFTgYn<0Ra2nyQtEZhh;^LcfOPJNY4SOaCO5w8%^pg&x)0$`H#t2V zV>WwC0bq7KU~V2d{ebH?+xDi$n(S=GFzsvlvquGZoc#Z8@;}?;Z@qo`ELhZb08g(pOLnCXtTdeR_%~7wzDNkbE<5C38$kVLu2Tc%mU;Yr1UKQpH*A(j&&-SI{s76OtClOIi|y^L3-mlvgSC5I2K9 z>JXQFmn=@r3&Q51L_?_Dj{;w2E#H(z-pi?u2B~pdVIK2XmBw7>-;969{Z0Hk{Y!!U z%*1~9%02coLv96c>wgGW)6xB)>Wg(;uUf~Hq&uzSS#S-H3eAx8$Y-oisfdC9T#0KGQt z7U+rp?fU||*blTd*`Fg?+0}!T=+AD}ll507-^qWKd@r7y>u;K1K?^cYriW2=Jbii; zhpBa$vh?RQD;-ULzD)Ab(B2j(VE%qK0I3P>NC<+$Ze8c|S_O)NYCyp@o$}ydbJ$PM zW0&?Ij9UtU9406UNpL{1)OW-$q$&-;YlxpjYM9wxdpX8WF#yf3wxstL7|k;{Q1xFQ zqB+K)$w5gC;^{L(K%S!g*Gsu2%e@3Fe7wUIwD>d;Se8D053Gu%*29136c?dUd=Zh; zB96#=mAe~H3OF9pd36XlCQfTa<76Q;mv0SIqe42rY;|gl=|44HGgJn`W*mp|tmZwU zw7F&rkaO&I9nBAiT1(8SXJ6lKzV{7wge`oef0F6j5>%@dU7O3^sRi&<1|gTSlEBaU z<9XsytmEw=mgnDL>9LL%c*cj=RD=5AD~38Ba`f+=54qz0(1+Ccm*nmn{EKq;_5QiJ z`$qqa+(JJ|z`)(7_n$%Z*M2&I}=gE>J!I4f$-4eXPrtOO?kkH@C9J6}>5+C$CZyz%;4+ zu2KiH4S!4Cz+qFfU|tAdHVB5T3YyGQyQITE_uV(sPferl1!8SYCa2hh{U~v(l z!s`5Vd2!jNHg`$+sq(_0%JUpqrf`M%jLQ%6qlX*(8j!xm55Yl^piDRSUYtlnD=JJ0O@=- z!qxTj!+u_4m|$tKfd!7b4FXz8FE%yo#ms+O^}=o4h_p_v7PV$J{)F2NeaDlUuEzhn z%>&QgYmtiuXNUaG;*6=@#&bOT5T(Uc&Wq-hYt`{;aa&I~9G0@f)VnM>)^Q}*H!Tr< zDzEYTe(U-k97#J6ee6#Eoz;E@i+-MI(6*k5%`hHy5%f zd!igJ@kFr%8v_ZNjut8B-h$8bMcQRr_s%X+8B1m5@^TunXXWh?oOUJ-(B5AMcy3ny zn5OKxh5nBDk3Y-V9nfOV?s*V2z!s^DxoRV9lIez+Z4!B2pL3b6GpaA>()f6}VOV#% zVbJ_QRhp@Gk1;|U3Ut#i#hteOZHP^=I6d$qT|qGTR|CYP2@z-;2h*Be&r-EX2sZ&_s&@oJ3)EY;%I<@p!@Akebn2=CaRN_7tiVn_Ts18TVT#Wn&vj=*b z_y~HK{J1_&U5c?kLaPf$wI{5#QR#rV-Rh74z~AumV9>GZ9M89@!ArvCYR`Zx zUbNPc$7QzeD{CS(7jeZ>BV6dA)Tjmp7N~0fty64;^QsqC6|r%u;r^mlidt;csUWz3 zjj0F1f<_D=Fx^6BN0&A?woqA)@2O5#0Li=0pqev^`q%y25%P6qL%k7WOG9dhVWF|Y zUxe+1uzEFLn`A@=8-pBf$BcZRqT?JvJQXx-2nyoqh<{*E_gh$_)yqzs95Ums3h*B( zYWg1?c#UOX86NUlv(q)>7UcFT^O`D2nUo@ac86=;BhEdyP`iD^J>R?{ zg2T>nkps{1T}~Zu0>5qy5Y7fd7J`9?_@n?rpR zaZXM1Qd4>+?|?Ox<69XF&-qZ6S&b6>sEr>!bd+^Vv(n=dBId(9Qe&CuW;sHYV~T~d ziHW7=c)Q`ZzOE5}h^S0pkXn-Yey}DJsVeXt*t@@LmFBbmlY5iJVnV1zS^qkytqA82Z4efewRx0-Xx=oah^r+o05Rc958$}<2a*08oK)u= zwCRt*`t%qRoqU@Ny@l&oGIfPq@^%Yfn1YY--vRX6xCdtJ*fT;6CQ~CSgF;O>XJfriV_J}m!zXe z!Y;{;Z)^NpAIYg!!#Vl&Za4ln5-xTmXuf$un$5TEyGk!fQt1=|hcc%q6+BLYmU6Bw zToty7HqmID^(&WSuB*`BnqW#Th-Vc~Li-a(8127S9LeJ!?U5O_8{LPN=BUd{GI?p= zx@5;s+sUed)*i=I+hA3r9G+v*B)fC9J5Bcg`Wq3Dy$sE;c$9!+IS~kf1zT0M7g~ry z9k!4tY=$9-`Zs|<>}BT{al!}w9ap2lqd@24;=l{-GwTPuDc@x-Hy(e}Dgg^{9#d_{XG=UlG7`_kDT2ON_9t|AvJvT9+fx5AaR&4>9;- z^6&`}PeWL@wQ>)fmMf?Ayp3ywe@GslH?G_wBr~#cIyryJ#nx_HAB6_D5SXj)4lBR1 zc{loIu|qHb&(k;Adk%+xiIut5m08!mJswNh38>qL%{kZKn{rM)`r##t?qBsl)cTz3 z*x*Y}Z`(I$KdiT&%>VHfKxvfEMCC(loW(VNPNml4L#e;kwhQIh+WxfqDHGg0&|8lc zy*3cqi@HYgYeKsoj@UftufFOCxjaA_tT53m-Y1~|#cZUN9s;k~d4;t}VSe$spe4Zy za=z*dU4?tBxPyu}b!eTkfZka_p-{yJQrkkI?B@eR3*=+|WO%PcJn~c%(Gpalt$q7G zv8y^YGm&cF&Z}mn&-cF++Ec5PE3#^sRyyW|mMLy4EFe!l-TxQFc)b^N!QiR6wI=a{ zqjGG$q2sYR|5PE$l)w;kqFh7oG*6YBe*Qi(fBBPnfmu8Z`Td)I-9@s|F>m#-l9LvJ zg@k#r)N8V;lEn~im26r7jX`}lDb4UwXSATscu=PtxEf>hc+`FB>;G09O5JVgv~;FJ zsUNvN8tC4)!9~6i(FZdE!8V(V0`k^Xf@GJjgR`C>b}xEL9hB38o`oZ#2atYYzxW${ z{n@qnfD5|VH9nX9kR7gNbHUWH1F|W}VOo@FRvT32Pgngr7=>L=K~gfT#rnT2AFiIo zIxnx6JB@zC=Wy;LC%BN_ckdRSScmK^lXjYD+wAnUpXgoqFpFua(fh-2Q~H;`4z)Uc z-QpGqGnV&ir>E>{YOtag#3uo(9$#sCGZ#I`li+kl`2EUOSJ>+fi!ZZ%BM(zgzuUy; z)@@5Jg*8@V_C^<5*Nad!ldBUWET+i~V$;(X_4Nma=y(1us_o$ou9>mauW1}*j9FZD z(7ae&7J+G8qa|SD8o7~{xmk;Z|LFe1r3k&WBN4k+^TR5s+NsfmJ8Tc7smQ;Q(kdwh z`GG6DTkS&!FYk|cHLtXqI~AD3Qfz?cjfc|Z_tKJB^Ez#%?Ko)wUTi|G_z$hpa6RE~ z+|OvMhPG>Wh_fW3jT1^(AsG$>+U&64Ch5Dh5vf@@G5M+AU^9R-4NPh*^`H~XghH4T zzhw$wosQXF;4r?uGAfp++SC=UoN(6&?~(WXTbk|l`X77^OC#l%7jd;Ny4wGa?wg^! z>cT#m!fMde#8M|YB-H}{;cqd#VSfMAKDPBmj65LhK)Ob~(T8wFqyP7BK%67u+ESGt z8?pL_Y*V}mZG2YNCA|tNCH0OqRZCO9*<~okvf+b^kE%2sQth{w<=Om0H#D>PApk6x z?E8$uLcgz5{NUx;?dEWZ&Z?OAA|=E7e13CW_K;x@h+8d$A@gh) zs*cw>W2??zdZ$VUme--lT_}lHIrmb=ee{PeE%LUm5wj`(hs)XX+n;4Zsy{v7eYak; zV?pZ3*Nnw6I%~Ri90Zdd5vJ3G6^a|~$6?W4lY1hTI$SVVsVvngQN&Lb;27%iU6=}g zXp7C}PisI8^ijESW$iC*X$;ae_*YSNovTVfF+yrETN5>Xh`_qy`OOcH`!$c_D;*R)k_Mb>1DM*-WD}+ zK0sGhyXy{f`l-c~1*Trcw@CNwVURP>wuBVV;E*TP8?xb)BjvYTE=K={@+GAS}bx-a_O$xId-bEkU_YI7%j{$$!7o1**s1G|Z?RK_2y&3!fMz ze0vRM%-}mC!1p)j*BYIAq?;n`4e?mVeKPGP9h+d&K#_dVsloUJKXtzO#@@CTgkize zhNWi5tJ*%xXdK!`-{ojKA)s;ek40l!l{nj+pgq%^<33_|Nv!0gA$0S20N5%Ed=~8B zZO*IgFxj3a!6+>?opi73@v{3lAJo*oeJ|EkX|ukTms-OOO4sba&lzh}N7%*a&$ZN) zC3W03rB_pnJul&z0@b8Vkd|H#tjc&?r4MG?s1esBH26=SqEI`Q`a1dk8+WN`p3Zi_ z9h~K=NqS7dQNsVr12k0C1k=vPZ#7|Edu#{?y5CRE>+xeNhLvQ?&`0*--=^vj))D)f z(xi5pSZr8z%vazDE$~mHEH~D~7nHANz$PX@{Eq+xnH^fB&OSsY%yZrHyY1G?{dZNd zS;7ha;lp5fzAwJ6nIkE)M{%-)#9?%Nv3{Gn%T@9ovD5)%iINM5sc5~e8_KT4kqbW! zv!S?`bg3!S`lsHWcXXQdBrhr*R^DyXtUpO)A9^nz7Xgs-hK5A*VeDobKhfF3GO?Gv zn87UPsi+&Axb|n_C}7|JinTxPtpd@1?q$XQy`0hNLuvG z3I^RHZ_m9cy1>Z;{u6wxTT~4fRgDQ3@djM+*PTm@Nd?k<=g`DGs&5uk&bWIx@04*; zMKB@iz7Nj+-v>1Ky5%#wjgL#GIc^^HZP10oY6iz&vI4VQfj2=P4&2wBM**F6#ExoH zxra%>gh#Pg`bZIGY=NrQ0(!6))3m;!JKQle9f=WLd4lKqS5pzDQO3(d{H6`3xOMOaB2B|n@JE=wcZ~en3 zfmfL3+_&jb8%Ktv+<+iAzcAjY`$~O|e`du6YdR(0rL35TUP_!(OxA(91yL2Ngbi>ee#T_|De@Yq)D2e1 z=efm0J`;a8Oj^_&Fgcv>05twMDDxd~IM?wEsZeM(4Tb&zzqJWTtL(lrj8z=zL{lt2 z6rQJx@Ti~&8Hi`?T})lv7tVj%{KHlEiNn7*#zgpPTAPW-ngZ{diW2B$IS%x(gb%(< z!m1#53lF?KxTuHi#*0=)*UuR(y`xU^Gh$85-(*2cjb43#L5nRLJ|IKn|q zZkL&jD<3rd_jCF$`TySJ@2LBKE&q4#h(p5vE`NsgVTGpdAW!3dTxN+5BZH=vdlK)7qCmo`DaDtLVX!n?vn7jv;R*Ti&E)SVi9F< zvQ1dMeN2%LA4ceZ`S78l*`)iJA|IF3`Vk+O)VHSixMT&FDehy6Q{BfDr@4OQO}5IfPh{NAZ2!CXS#Nkp zHv%%>7`wI(^-wqV@;P>GU!!BGBmOHqN{TeavcGbS)wn8_S|^Sm=l9e~o4*Z$9?I4D zSKsbJ$3ukH^(xgk`9?>1#6JW)3e?mYoC|I6))a*#|E`}iiNcLSIuQXYyHq_N3M2Xv zw-i6RI6wnPlAm zDhqnugr5RFq~e2sia}cJzj&K@!GtI&Y%hFuRrnVXl!HEw0|+tZcvsMN{{}GG%4|3v zqc+&P?jr6KM?<8512nbFpGqk_ZwAp>IsD&mWo*ZcGGp^;a~S_zeuo0j=c=rER% zr7PF(+_Z9lzqkJWM|X*Y-yUrwEQ5sU>DCJE3H>n0WlF;!#aXA8a75Ir5JiumC1roP z-N!n*$n(=jI!n#mDaGN)6^9};*T-S2%r$oHMl#@3&K_^5H?6)__AU;x>Q&;9P@e(^ zzvP!TZ)BDx-Ig^LSR#dLBy!&8F=|)Gu2m!z*rWfkpEz4YOUlg_(IlEW4MVj3$)rcs zvJ-BJb9jxJ9Oofk+`emAtRtn`XzAZG@AYTr^I-Nhk{d^%=pD>H80GjE{n8y6bEKr3i{mtjTyg7g+1G&c6V#&Wo6J8r zPWMWlAOEyCbom)7zdN6A1QQ%GJ`cnE2H~?@jsKGKpsQoo-H1A8|0r2Scy`J2};3SqZCqknq zo?%Krhw=_c0a7FuUBG?lxNjbzBOB+;$^5}qS8OZHb%FAQuH$ccf}|(@&u+!pvDFP+ zWm0#p##V?1vc!LA39MsWtGcdNevtm!%_bZ^ldau_gd@_Xm!?Auh%)V2Ooh8>rhUy1 zxCPoKt3tLQ&DBWi`;~lZEM=dH6vANUB+MV4bzIk!bD=T_ zKIms@>Hnw?4=y%+sCD{a{llfVOChdHm_j^Ct&>1!X3n)xF;|9>)0dD;>vhd6mg+lwl^GExtz zCNMzqY+oYjW}Hf&@N-j(@Fnvux4-*Jqd%6~-%(E|qk%xgKbNtHCRJjouOMmgO%bjI zYLn9j8`>xLa~jkXXwdd)p$0wtlOj7WDD!By(+0hfM9dn?5xb$9+W>60~anyoDGkcR%cSvfWJ@Y9CcWt4tz@z(Ak5)wSvgK(miRYSDbg z{lAp{K6O|S-?SyB%QxLT!5pGZ2X)B%H`3aYSZZ%Ke(+ZLF(6#n^Io9F`+eSVC-iSW zL#+cfZj`zS1GvqSd(J?LTqdf3Ud& zVroQ;4kpufHZ}Ne+ujmO&2Z0XwHBo!ey6iHwE9d$o4He3N)NYyf7A0Teqwq)ApXK$ zbSP%mV683CcO$QRh2z$Gr|&b0_1$C@w)C~duBE?{zTaULxOh?h_nKRz?k|0`I6hLt zhXu-VEJ2@B?0+GVP|jQBPw~+mKQ4@qVDHy&7JCY?)A;99rgq#wcQwta}lIUQMZvgxy`nb6vtKC6a{pB`KL;2pRb z?BK=pS)7sB_DuWb4W$QfSoq4FByZ}?&v({!PxSj1tHzkC@kMH^CCHegTHpGTtMxsu zR_B~grpFSvbB@$lSy@&33$^U*I+#fa)pDAy-VhtyY^o3Wz;KB;u@>(uE{^6&ny^yW zNPfQgmK%fdNkZ*$DBkHhOY}`P`Yx_Cjs*0@Qa4MC(0E!v;}>%@p6zIy=xCf^H0pc| z*1K8#Jgb3m*Ktgl)N>fsFkQV;=q9yoZx}~H0|}Tu(BnWsUSrs%S}2c?AGAF^1KP9U zM+NP1&DpB?xT}95X5VtCHO9}hNAB9yFTvhZ)~C0Mw42g2H1jYB*^ha)!Ot#+cTTBF z4O;m1mmh`MAs(rwrb+6oNuODGptRm8zC6;a4#Q%Ir*&mI=W(uXf5L`&L;0g-JcW8 zT7A`BiK2e(u`;bGpVVZg4HkazLvY4Yx3ZyW;RkY)vD8%{mEnGsr_3KhN7U|8BRA<9 zI3kU~4`zEQVLEHjF<#VCxpkDIW67;~lNQ;Fw4jv##`lS*I3BdFTU!(UqFS^cQm>AM z#a*?V9`Mg$k)N({72j5fr9R3AJM_dF_KMutnB3#L?0s@wsLml*%X>O$=NNXgainmR z#`Vj?$5Ouo$HIQObzaWk-aqOy?0Op$t$Rz5BY{*?nt9zS{jI3NwT0kIf6usmiEck1 z(V@KG;MTwPZF_$j&mK!%q=fIe1ddyXrM^T$V2Cyq3ERw(>lzrQHRMZ^)$znSW&y9} z&*z%wdN}j(W0fx8`mHzEG?w~`628V-rm=kVcdC*e*Wc@Ui%RR2cu$Zhp1jo+47<2L zpVz=(X06iCxq#=ey6nZz8mHt>5~y7J2ucd(Phb?7h!E`|LAmy2#3< ztf_A8Wb}WYl~>Eb!aN3#{p^4{a2CzqflKU(=M`iL*E73iZX?Y+49dzX2a~MRlC^`S zvsYsUwBHDN)in3iYn>L-4GUKE)u~@0cd2I+1G1uS&@ynV4E_%R3fbahS|iW6v}cVx z#-$rep7|!Dk&n4&Ya#bDa+3{+C0by#2=J)!rY>X=C6-ldX)XXOZBjt1NO_*VDJ*#} zsqE)dCABmS^HWO(8yIO}(Y%;NaSia}hAx({^9)WYcG)8SX`=`haKa@JE);}-j9m$_ zc^%$r@#`08dh(PK@kRmi1FS@e*U`4pTODiLlCRz=nqev~1VCsZ`$HLNITmu+rKtX^ ztRGe8_o;M>{dZ~y{x%Dhy zOJ?C25tPYp)i|8~Jj$T%YJJwSQ|mH#EyfgdKQtD@nO}ZVP(IZW@b$eNwDwv0(YDHs z_iBM1^&KtNZthCjrh(#A5Ap0iPfsx`^4$2RL39 z%K->w9HP(SonKBV@jZ31>Ze7*W`NN{t}H3PC#t&PZ%s?-oM8B#w>J&Rl4Pb4WhLGVSpc`P>qVgZS7#eQS;=_?T zq{NmN^#i;q|43`(sks5f!+_XzkI1=^r+lbcVl*Ou1!NN?VZC&GPVtICSIC2{7+@ak zD%??>UC0nOmUu*r?aMfCJWGV)XDA&1+a_7q_;z|ez@A%l?x;TyL1&I|o$EYTRSpmq zP3XniN84-=f7V-#|7S4_&U$eim!>cW@qwD)M^0Y&LOMcDXo`$Ek zaWZ?nY5x0%bH%XkB4e25YbUbQScrcFNRl&=V~MZyG$kT`Qs%?uv1YJWI*;OlT%;xM zQd_f`aVS)T5O0P{dK+(rg%2Z;bzr+}pUDVP=|&tUvP~z6h?nZSfWtu3Xu5MB4uwn+9R? z5z#XMVm*z4U}vHOBDj7WKmZSb@Khnz@LR55ucXX>m(Vfq)|*IySMnYbzt3lIjZwiK z{E}9o3hv;ZtwA28uruoVr{CCj-Q432AhfvrDCkTbAuHzMm#?Pj246J4>eR*2UAe}8 zCVT#RJ3aN9{?V^>|8$itKZ3tPR!49ZR_mwkg^*Kjgpkz zP)IKA@Y_^4F@ZJ;WyK3}=oELwO1t;P>UCVsclEUPU6XG1{q&sgmxbR42JKGTn$ZB+ zU@NXYRjg;VfrguBI+~1bpJ~{eXQ_zF_*b>%@hL~Tsco^#S@UikIf&EsI)_}L!29^d zx`3URMnEi%tjsByu2F*=h6ZcR7m`!j@%}KHL}#*ZO=qnA6H3v1Fa0;akgM*?n#4_C zxb6DeP#j~OPM;H`_ZC?4g4tP3;7$#`eaNtwZxwtif^%BQ5COLQaf4m9GimspvBX}K zCDn|=w5Y83AIML+==-Y8y&B#V*^Y3h8C|8RbLR!-t4~xWBU+zjQ?z*kBKo!R-H!3} zI=#BVoPSNNLmXTNSjf%N9Pb@#y&4RaE9Uo#ZxXwIz+^A>0Ph9!3*-G_3nByNL}FnX z16)^XuZ_hrfO2STkz*|Ju{|1h-{FzA3Z29Jdk8CH_H^2w207KS#1f!8h((a9Yc@*C zT37ujmisS^48D;YxYW%2<)k~=4%-OSVCK!A@_X`t43s#3RTKrqXU_ishr7MvSU(-FJ$Nxg}_>{U4WeV)inNX5xcq727 zdZf+|yoj4~J}1J@zY?(jpmBSZN#j!5U?OH+oC8IbG$h*uNOamGHXH}vz^hFZ58{Vn6OHCCUSi|SegZUs}fg}}HKkVB8=wEYwUiEjUxZ|J$ z5cIjm!+ZeX^~V7q;)TcPfxs<*YP$11WN~g=y&8bZ9pfYJY{yr8;edeNf;ep~B z@J5#^Js!I(4$o1giGsihHS(0?kdsS2E6!=ekJp$>fuBOTs#s!@D^lUv&{`^81O#ou zv&e@36)Oak6PLpd64?rJQinkThNu0!Uafww_UXMQdx!mKw}-_RkXXn`H|^64=N!i5 zB8(R(zyAs5OUbBI#b*eaQulSsCv^Q{ReTpXWgeI~2|oe_sPZpIKFR^uSmJqo;Dt=Z z6#;89c0)z;`>>U>0-JFv?s&HJ6hIPAe%2Geq<3vta32c76!T6JP8)^4LPVxCWh;U* zEo+kiZd(2J!dQvk5f*PI4%zPx5H(wh6LrJjO!{B7 zxhiNZeFmB$Auc#JEPf1}_J7qtUR)U9hkW&aIKa}>d9|JurHP)Pk&w%jF9g51)*+Js z+O(A`#SSj3v}&c@uBjGz0xrDo)}J%n*`-b1`-npG-k$<^trYSum?qafKDu=s@|?+Q z<>J+}dWp{p@{_&5e|dknxw`9*s^+;l!V}r~lu2h! zgepceT2rM$Z8?R`+(4lUS4gMHs!)4QAt`rHn7%v5F#RCL6Bf4d(*3RC_%q#uRm-Jt zXKYgERf%^%k%cKIaXh~YCfL#|f8f6@9=$9+oSOS10f!l09{(NJoD{hUknQU!y01*m z)#L?$W+KOWy=-*pj*yyce(Ag%!dn8uFV}A*Grw8~;Q>K@0|2?n`hHdW_MFn{vsLZ< z(h*9Flp-r>$M@K{MdRy*7pVHr{%F--1)=id(kee=wNs3zsj#S5elHL)qB@Wsm07>o+r?3>c>eFxl1FcJg5NBElefqfl1n6` zr`Mf@JktAVK+&hBr64Zc{+?K0iTWgvA+q#R81#iICJU11F9aBrtsu9~U5hVnJ#4B`?kd-<`fYR~f&vOcDh}u)ZCpfqy^^3s9 zJfBk}v@!WCxSAqZGwsb3f&ZqE#p3j`Rxb-=eT)vXKl`31eLd{EKwr7-mYn7}@;eN= zObJ&==0_E245bw-YZ?aiYS{!WkrMo!1b@{#uBEc`Ls=W5UO&v0O^1m4OLjNTEo(VP zbnKliOdE8O8d)qRM4T|SdE@En)?4W0W!s!bo}yzZDGmGlOdFNy+5(I192cZ-)xv}m zQr2D1*;2OpqM_+InqYSLfi*OQhCzU~D$l2PI}ZBi_iFi_f9?Q+s7}vMCr#+Z4yvVA z%L#jfrPC1Z@4bs^*AgR3@n|SXZHLIXZ{V<^P%)c|ojdIJhZc zJSKe-bQ`oISJ9@i*y61Xh!|Z4LsR^3kzrh*X~P)*!|6S9A{KX?I1^|t-Yl6#IJ+LqiKX7)NQWzZkFT)k=kEW+pl}f4M8^l(sl~Pf!X3We-;_7={Iw z<*JXUuIyX94oReDD^I4~Hvre+`A^Vqjssoy;gYF%f03xI;H-a{Ddj$Wttq$d7X(cy zme8)K(21hxQj10ilXN6+7T(Fio1Wked83$bsG`Wh-xa(niv8F9^y<()Jjd++H->U) zawh%xRQhvvn<;8psK#OI4ZZ;s25N7!^4u0Omi`@6t8q6py@UHI`S&NktfYd%uG@z1 zX43cE(pr@K@N%NhDo%BR;x}9I_!e!Sc&l3;&6LgX6+bzvexWg$n^(Vs&*0wcz>3aN zJ5FsO*UxO3SdFd8f-)k|pnND1piroWMv;zJo|aQG?z zluaE7&h&aUlh3FblF#vLOg=BrGHQ`gJu+%UHHIg(dTn1clb7sxQWUo;XzYL4NsNyl zT(~EEEziC`GJBxH%)hmVux8ifadtHf2+!lpF2}+zD;G*6zuZEVyD-aspLw?GbJ^E{ zzQxfsbWWkI-JQ`Y0kc2~qJGVY$#|I!E0)O#TH>(tO{H)vaU^S`rtx|T7yyR;%39Q8 z!QNIdme?7Lg?nb*Sf1|hqIad`jVCCa{4e*P;FKu0{N@2i+<(V)HC`sR_PS);9lp9S zk6~8}P$bifTr|zb^U+1*Q*Yt?qF^vUHCmm`1@J;G5O`yO_`ARE%h)*S3Hw0XFaJ~Ux>B)cDe}I)B$)ZW2m1A zxQ!$(5RF42WsT!^a62M@bS4kwrQp_6rr?a=_xtG#&mlI|JjEB@-K`5w%(QY zyC>m)h`!-Pf-Nr0e+7?{=j&;XhppM4YU_LLPSK;Vr8<>X)z@e@lC1Rhg6clW!y{g? zox{N7Q09D9vJnc7u-VbsRcHTO#F6gLjiUEyi*5thR2GqR$9Kn=?&7HHej!cWS3G+A z+cHn@6x}X2*p`3kJj9&)CRzV!z;AZI9|wOeyt0aI_GFwWUqguC-QZE`c_ z?t5>tgK5(vm9m2@o9&>asDGaov!e@#h^qKeN*!S1nfSqQ$860W&shA?+^ToU1uKg8 z<+r`{oLk)L;`3cPXT`aoI@=lw+xVDV{ILQ8DUV8RYbN& zD7pVhtQAe9qz%6ug&-hBt`h&6F^=V>>L}$sz_~K!2Pmg0Sc#)8!Z*PovXX^Jp)yj} z)J7~L=&3K?%{VMHJ5CC)zpSmLZ8`w}gvF^%#OJwawDao2Ugb_OWo&AZKka1Gzgm)2&PG4{ z+F&HrMk0PDOH$XwdpW9VjVczd=u@~rHRCVyH3x6;JJ69kPnl1_r&D^QphA#BN~k+C zzhf(n_rt`UwR}eo<$500M2jZ=spp%XwdWyvzS2Eg>~{{&YPaXRG@H_kyXRWvoucon zQ`^fo75|3e9y$K;7M<;AiTp#q5$9A`{}1irLeT$bF}(PNbj3#mh4U-^^-2G+;>Jpl zV_-6jNCo#jl+QlE;yMsP&23F2zZS>gSDc6?K9sgsZ0xismZ)=@TP;13`M!$5s#^Ih z>>~-9*-M*=Cje#_F8D80Ja%HHFhH!ardC0SzXBiDMWnV0dV^0zgizYsc!vt%p>$gG(K7ISi|Q_K8O@9 zcLqOLKb>TUWpQgq)H`@>vhjQG;O}czw{#t|P^IjCc0fk_qpt?TlJmeYd)@OGMRzd# z>~$~OvxXV7*S%)X|Fq{f?D=kc*3=&HEPH;=o^P|~m+bjgd)9&#w|{8%I;}d5CA8mi z_PRIi`C5C{s(ZJzVD`EdmadTa>~&g+7E83-^OKgY_)g{G+3U0dDBdsdi|-oXs+~+M zsb+)EV?^7(QvdHZ0;T3IBy&O6J98IG*}7hxt8qj@*K>0h_R;T(xeNR1cgfs^8sKz2 zFn6JvRM*{e7jC5A+vYCBHWYOIdG10~rJ(EDxeF0eLD%JT7xve$m+p_pakycDZoMD) zTS;xV50M&b(0=c&bT3}#mw$;RYN(OrYQOi6bYgub@$PiuzL~`P(}}xg5+6<{YQ0wg z^RaYdaVBv^I#G*igPhN#6W2gy!nHgRmsfHH=Wd6ORo;-s$iEpX5FF zt^r+%^nBFLCrj1`{M)>*1o!sMg=E_Kcz*OdLBH4u9w+LN-$}vml;C%&e*I6kH`BzV z#tZ1HdYtkd`L!Ttg};ig&f3)aFO-GP)&9ctbG`q@4y4noCEX!U9^LgWBQhYAv zxC5$r03(@T5Yw4#DAR`{(;uKMdMC==o|Ho*Z;7n@lr34?yJl@{^ja3h&Sc0FIj>O1 z5s#-d_=fp=A5U0C}=S#{Q4ucF6dOo6(Pp|QZu@s5=D1Bqg<&@V36CL&2XryP>U^{rDztUtFogeU; zVr|Dd84T+!e8TG_RZ4mJHU3EDCtY2k)?cR%p{q4}%u9FbH@sEadulHpbvJ29yc4GR zrxhqANW)6B4OLN%egr6J|5)1FPE_k#@{YB>H~f#VF(RSEM)yqdYVL5D(<&*L=2xU$ zTK6GI$|2-@IBR+FLFh`En>N4C`rpbmT^|b_po7)Ks4V?1hJQqe|Mu${ zo`JvaC*d#opYYFG5C0MV?UPjfj#XBDACJ4BU_i0|6>}?C^FO@8m;8(|% zG?cQuqIGRSy#K6C01%#wYOBIocBde6ADGRZzb*{*WFG=q7F*s_6ON1Fc{+ksqGV$ptV zx6Waq*ttI60@hB8NJm(GN#V|h2$c@!s27U?aOgPVBsvb%m{_Q;2uptQR{Xm8^DTsy zJ9g;<flI^)#=*IVe8f{E_^wpVeR1$|lh#ubOfCz^#Per3sG+fXDW zfXhh~3C^>4d*DzSKXANAEUFJ2EwU5%! zkBOr!y@~i=J+i3eom{f{HBC%xm^?0QRjA``;FYA->i|e z&xB&vWll>J{Fy&d>aq9@Q;$`QNh*Sw+VeIQUoe5&8)p#c-x)=Ldh^VVi9oOMmp?&2 z;mlyant=$qJh}KQy`t0gvb6X-0BWb>H~H4&pN;^0ehe8)+$$4@+p?M zkrFj6C2kqU+D9^Rnwj8*y7c)*-0`Lb268y5hK@3ih$XyAh47AOIB^EF#4Saa*0Vs{ zOT)>|Gyc>7VeRg^IHa$oKt^_(X@ukAx`8CeGrYQqj^^2_|wlAIBT_s zztmk;$}$hF)UrKS0Ux+kP)gVlYdeOFU18uq&>!x^_nr)^aa98M0kEh+(D#K zcPuGdXKdbts$}WW5&m@s@19pP@Zj|jr+?cgwK_b$b#k-h759MwO>B_R15HFNgtHe6 z$mn6HPa5uKx55*S%-2J$$jp?hb2W(Mm)n(cw6=EFe%<`X1hJs|l|a9kkCZNL1vu;Z z+__cBLv3NZori~4E-~Ke!u1?arXI{KPS}Q0E{yq`fB;n|oABGlT4ZDhpUs}{QjIDT zo_`L9MLHz)a_+M1)zE!iL@Ab7LH?jCnC=$!=;9*-6Te?k6WMy11J_;LLobRdUwW~t z1}iWjneXNPD+`wnci!EqnpjCPJ(gfY znrff89^h(es=K<#nRi*;=Scg=S3I1ILUsY~>AFPn>#$}_Mr5f*(W|l*IrUeYCw0BD zizu5aQ5p3!D);l8a=+a`xeHY8jUbF?n-|s4#UsI>kYJgCkvrx1gbEm+rq`(UEkl*F zE(hC&s4U5@;bgFa2(E|M$A^Hot#oXy59n&h0e;Q~s&fC~S?t@0q8a;-++|79^O5RL z#~-ccIPFDij;nFEO6gO}l6`Hdd9Ii7v!KHNmQO?*8ePh-`9^k2A$nJ=&_q7Ik{o>g zc;PF^$7fFO@pd=b(aH1wM%^%EIX+IEXkscOH?=%)Z=bv0wd-#m4m=KSPBemI3l@te zH!BT=)-u9%!p4u{9QqoKzKJia&yT_RxOWQty*4^Ou_joa^}&u}i+sL(wmADY&g|dw zx%Te?YMeZ@NV|D7mq05TtFG>5JrfjA>$-|(|JuE%Uni~!ez4+8lEW{m6!S1$d}0eR zj*$2$eVDnAF~#iAG(FQ+sl;xAh!VTGEH^+L%ePSPmX#X;WNkUoF4XpK`Go=UyM!ID z`1f1VfYmYUL{N7Q$uT*~8QQ0RLt?f$-uf{02P*1}uCq_jqa!cFiiTCaqJ8UmB3qWS1RSL&wyy!{I5@98&I z{(|iCHiS|zsLTt@_CI4`;XHad|H;bNWtVR*lA|0~w4ux^G2Z#lSA`IQhUfMVxcZc( z>tpZKd86jCu)exNJMzu5+t-!Z`TC2-s=h0qwfctsH3ztBR-h)?DAX(BWxyF`HMfP6 zq9iBo;eU0kk)s8Cp&c-f8uNFwAvnz;2u}ZspJ^*u`h@@B_#%9T-@Nmd(=f2W66d zdJOzsp3d`HbcEIanV|km8gs%3H0^Gda_8jv^U!GCcLG_pqc1b@`z-LNv)y-M^+olA z4ctKxAbnn%4(HBpr>7Gk!EbvcP`to@HT$)*k#v9~=>^6IwMngy8|my1ePr^;lJ;p9 zc0FkIk{^2`sgqdQaz^E1VtkF$6$dG|#?N^SFjW4!=8~r2_v>Vk)^*)2Z-~&{dm*$i zS`nQTv|O87jASNSR~&4F-fsQ9KnI?Wy|c~Z@<8GizdFMI%^30Xf`4t0pYwkzKWlQx ztP99gP#~M1J2*1)_=*0#dbkMs{AnY|^v|LIOnAx$Iz^T(s`9Wne_RNU@ITn9YHAiA zAdQh)rTx6(gL3HU9nd33I-8y=4l=eacHHrQeX9Y+kj@e7>vLd?*Z_<}fg${+vBvKs z$5nPyr#@DvZC#y~LVPno&BNr^A}^}Uc4jWU{6Bpl*7dX#;fXt+aqN@kf@|B+F) zL~M+#Gyls4*whDLD>aHItV~nbI;o8;o!(kcCm81RGlF|8aLr;DvEKxUU9;Ujm+>xL zD{<0ml()=q&7asv7cquj$O0JI_Dt<@b8C;WH3gBFU4n#(!~d)#c;F0<%kRIbwWUjX zKZUesU$bPr`b^c^O&UoIGQG4&mu%bsVil_`5Y zn*6;fhe_ei2L#;7@%L1ZoM_~5_8=t3MNQR$keRnX&Dk<(6zSYODw=H{`Wb@l9D*0x z?|90^8>5GyMq)f_SivJkqt@>-k?Kg|?ZxWaQvMeBxBk!{2MSrn68n+h>;87HuRI=w zIpo;f`&n;Uy_39I5#)^g$LzvB9nRX|id+F|(B`rNMZFpZOX1X*P!-{p9{Ok8W&yCn zSZVhKV>Li+LXX}3toH?vCsVWXoO^uGiQ?k~1~*;$L15b4h_ChQjFDeUOi{hQpF%}s zhgKfrJsZTs{MI3SbjNEyIST{RHDH_^zs-#3#F$!`XjkJDC4lVG6XA#x{XGL&#E) z?1hIU84QE_w8pV`vvcMMuA60&gQf$hw3c0GXKQhkg)fgrQ75Y4^<-|BcjuhaX333j z<^0MB4nfr2W7#aF*3Zn6lG}eDC|Hr!#p0X_iT}k&+w?FNNjM8&?NOCU3Po$Elz--p z)W{nBI!Ow*e|mjS<7inH;jZbJuJa?ta%PR@x7I~a=4S8HGj^_Av8E$;|9=@Bl zGPa;(z?_m;s*z{6ox0_Cx0SkOr1zX{qwZRqWydedq4Syz(D}rHvg4`Eg~09I{V3eK z+jU!P!RP{Z?zXoSwtl3YyIq&%*$4SQhe(>Ib(%Ck&M@W%5Q@DpWf+ed7y85N%>bXw zqObAEEjWkhC_L3j@~9}M5aF?SL=}%J_L@mA@tRALM-9S{O&&E^-sw@LUUO;kC_L3N z4wLnohj5mx*Ib@Fs={lo;1F4_xr(Dxz2@rH#z-MT(@Y8T1&h1B3=C+{f8Tzv$n98e zbWLrf(C&7M-Y$-rHlQX_F~59-&1j^(VDjtKB%>FV6v51ciem1v5y@k@oCKQ3 zveLB~x0?s4AGIuX{%QI>?XL##hL9C_+C&MwitO>F;nRk0zE|h=2ec;?NMn~`G-wb^ z9^Cc`Ifrm^Y-7|L&1?s2i>DNMd&2TQ$+L>R{Ur!qHcCz_p@o%tmHaKk2i_>zsPbjr z02yeVp47{Xk8=zH`wSx4x{W{)AvEn3=k+hS-^N zXs;7BXx3EyX4#!}2UvTaOna8GBG8gm$TIg(XqhXdsb>`;{E+UcMy!v=zshCrMfN=Y zV-F4*CGP*~F=r2?ZOMiS98VJ8kvmqkqi>=|cl#Kl^3H~d0GAhGYvaYg;OjpR?w$8F zuxn^ejz41WS@S79zmHFk7oqRA2GO^K`EC$@Oo38qz3aoRKk(>-OKfD$x_6$(|Jh=Y zS1vX}6%7I$G@I9&SAT~;n#M=I_YFm{N5?Zp_bv@KLlCql=-JBXsSN2ce#w!llJTT$ z872M1?G})Ll{QFPcGG$!1y(MkE1O?g@j6;uV2^0I;e_1v)~UBA!jZ+%B$j{pBN(t_6M zPaI|=rrF|q{xKO{|8Vk)E$FNMmSZwTDOlCW`p%t>S!iq$!H{zES=!W+7?Tt2RWZRpIhnk-g%rCP3 z!SJ7uhhLG;pNd}>QLK-D$2|NS=iz^%&g%b2P=8kN(2msOC;(H$uL3)217Z8B@X#pT znSoklHfRR?X8)7HyW%IpljGYnyj=}m-A{y9wn2EWjZl5Rc=)H)ckBk?U2O1f4&ep* zQ;PgHL3g@?h>-MSj~?ZtrLEce@tc}l{n*vu*X6+<0{np}W0lj-NH!jwo439m+>wW; zR~DYk{DIk{`)kFbXC89)NR~+FAN)&pV5Iq>U14QI)I?MNJoI4Od zL%EMEwnYu}3*F5ssQ5{GA%m@#b6XN_0+vOkKH7%}!E26ww_f22J_%i&YC!uvJFh0y z)r{BXJ9{8LU*kaK*p;j@ew6&F7W(3BB$ozA!Z3PP0ks4F`F$x=t3vl_EE?Ju`XlcE zaqG_y8n?prNJBJrqLm45crWt*0S1Q=W&ktdcmE>2{3rBx6fdYYfXxn|#S8HH&JaL# za}FRN9OwN-I#s8^!sCZMDlf?_{v;?3e5b8$O#4m)coZp`lM}PGbCkw>CUhuS-j0$1 z?*H1+mLG3`yleMYeeYhBQ{M_!BGqwRPJ9nZ`dOeAElSsyw}`2S)jR5U?whW6vJNJ- zJlXZHfUQ=4L(uFH1oh`kV~7(H&GIDLM5z#E_;8O--f?^wr3DR+51P;o_^|yAX+CVh zqeu+qS(*7Ll|TY^41qj-J6+{Nit|K zkcessXBNh%CtC({c;LuVJE%~{H~*J|3e_W=Mt-lZl(SbgK}PS>T$1LgvyaJ<6U7PP z{1xLPRn4oLm|8+L)A5?u9Bn!FGfQCp<9kI4LVJ}pvuNeB;BUG=vCIJeuR{1bC0J={ zZFNzR@!FrvQ(wSzhUK;|=Cm*7i;|E_o330UHgQGZSN=TkD~kfZGW9m!*YgqI%{xbp zeHf+&e`SG`1MJm}k0lhiLw8augGqlGmyF8R@uoJJ#Q~@<@;fT6T{ODsevd{5ss2OE zK!%`ERc$Lr$x^qG%lKpMGBr?zEKDtBc_)p}u|?-xnuOlo)3jnpr`GyHMO~?W?6^=k zXZR)rRq3o7Z{KzmWZd8Idy`H@1YBpGhT#RNVQI{6zqst}Of-!!Ng+H=Cjk!Y*bnPBH}NIRuI?)FSTaQKc#U+JAC5Kb>n`Juot1y45Jh;d#=tqKm2M_;2 z0KLwZzvC-45;2iu+bFfW_XIYN7G}xK$E-a_u1#xwl40?S+JMN z#`%BU)Nw6-f=E1QAjOyg`19tLx{L+yeP^E)apy4q!@!q$?f?nDzoTYrVKf>|tRHT# z1&FaWDZe0fmNx6oc>Yr<%XOA|sDEnh$td*GsdE(N!s zk6W*Ha!_dA2Gr-f-6`}Cg{03ve#Ngzp>2i?PIu~NzDVmR4I7QXT_7;v=>Dd!Eranp z+^R;{^~67^RD)}clPK*UUF=lBT(rMszOqANsy~=_uYtuT@rl^%s6kP9*P3_4|Af!T zesd5^uGF-g|Jw`znC?FX@YD}(L2XkO%M%bOmg`t&s_{BG*bp(jpzDdSHY$DGHL8l~ z=)IRgNO>9KXF>7jU1#MJqhW)c5v0mPpgxL>`U3ZTcfR}kUIZAT(Z~j)q>jfg3%>W~ zyNa^ZMAafk8o$D`K-zj+QwA>nxeIlWdaR8B`;%DP)xxb6Vp-#P*{eZSvR4&%<=Crz zlJ#X)k^RCW2;G6XV3>kuC<~LZP0WKMZALlHdbxGfnfOiCc@m(zZEvAla;KqtgO*u= z^{V0!;pSnqRX>*-;y5ds|msE`hLjN=KqKK#&U=W<(yBmGkvut4 z^BJRxPg?FtPAzN1t8ckY56Rz!>DTevq;&1^YGSEATgG;f<(Y-$=^8|5-#E0N8zAxA zq-PtOY9&EhPoy8RUPb(>bBlJrWEFPn1Ww7RL&&H6I_zb2NbL*SEPG-6`fyM2tNV`i z`884ex+{xcvvY8T{5m6#U(0vynO}$Z$S>;T__7(M{JPxsY86lOA*=rE1-5n;@K1Bt zdS{><`i;R+s-fEw@+F_vt&P^yVFKXV%PV_`9jk9&zr9Q%&~Prcp+?Q|(jHl%HOSd* z<-wolv=wI;wsLl1Gwi}Y*Q>9)Y0B&aa>gj<+kuO75Qp{3M_gx!yV`Q$oBi9}>|YP{ zn?n6s!utI&2TdsI>3Q{geW#yPzd)yZtk*R;2*Y~iBm9ja4A<|gK0~ZNwYLTGiet}p zgi+sQGp?jtH%~ah?D?TND8f4JBp)b}2`BW+t&{1Qt-ITlT}U<0V$WBG_B;#+&7&_y zdo}4=%MuQa1>AmC+xbXW&Ig@#9qn#z>bljn+c7!B*!T(WA)lBTI9JT4+fkfueFk$` zJ@kM1m0i8@IH6vBwUG^qhG1mDCSa>>-|gyTR-D>raDMzX5oX z=XirS%|XoRucl_Vzq@nT5X$n*JpCNH<4@90>iu8a-`{f(hkBZixMK$)?y3EqwW}mB z_b=<~Yoqj4p^s2scgjH()=?V>vh{VGp$aX9vx|Yg>W%{Rbw#MJCT|zQ?9uPg{>TNn znWFwl2+QlRp?TZN^RAZhE6*WJ@lsMF`Gh^Pz3HwlchB-;w$CXW@-M&a1+Hv*gPvQj z#`$l%h{SVCXZ-OP%I}wGuV&2>|(=Ie-#oC@hD^n@{%r!## zF(TE@{$k#SiM?)O)(o5x5lfs2EUKb8%m}|jJlHk<92>jZenHY~p*g?h`Zg^1c7Q8a zWr0-E%YyWsMH{p(eamP>po@4CHR;hY41pQ8K2}ov8gf;e&EB?>l8xV2&*WR?UlOD) z_b=dyvtc{q$BDg~(Kp;BoF_5E(W{H$!~Xb6muA~tyk)6B@X24@y;h>1Vl4?EQ)F%b z%=nqgP2odD>dEkh8r3U?oL?sOUVKwv&$Gsp@$CNUshma> zHubYmf^1u!WOZoP*y{hnUwk|VaoBqE5pQOQ^ZP4nznwd(f^Xkw6-mp0Bx$Bcx z9iF0vj$rIUurn6~%1%XMKWnw2PF)0G>9&4&qhI zc3sFfYw&DkRj`}GqrBx^xA@b)H_McK``T@9st1P;WVj!#m;O;OUkWd?h7T8A zmy@vnxm3cv=Z_}b$HAp)Hp2(e!dwltD%W&m6H66W#{SUJu4Cp{yBJ%ra{Fg_8A3KU z&c$%^91Y3kx7NcjJs=Y_Nhg>hR`x#`zB-4`2N%;@$;O#TV#nm1^P$-JZ7bsa0Z`_Z z7|*(&0|JXs#m6wspZhaTSNSk^yvX{W?Npz4uebW-z~3f0Cjorh@YDyuAyDhDu*-Lq z0q^5{cry&%6(KzJIj)jM81$63F1Bvy^RxPDx;_P%e@n>Vp zze6TJXAMMce^?Zn{nyX7&Q`n-8f%{~|4dc>?7G0-x$~(f(667b&=E?qi_{ucOI3@c zhIFjz<+F{*eYOmOz_d)`KgFj{viA!N{0^0)qx>yO4aC9HD_j${yQQQwgKxiGEBS{z9bJ0_JG1nv5!{UUw|=xXC>`(6q`!7DswI#^i+`PljaOC} zKGs94?%l>ZQP*KE@47S)8*06a+M9m_ST$1=|Ag*zsEnHH1+^ZLRlkIL=RO7b!61R% zClah}ev<+lRkqEa)rziQX1@y6@3XqKc2Hq>9{sp&#s5>UHU8^7;tFDI=@V>54GK=M z*<{v6@L{kyNy#&d+wa);UQYR4!!A5sak`bsld82Y=YFF%u@0oRd`3oC9X$bBT>*)2 zDlEHVAd`ulRst_NpJKNMX~;);WrF=P_?*U;v8Sdle;q7(AHBxty$`8PP2%HXQe}ds zhGuH^r_OCX4KWAvBZrm<2sjG;bCdG9q#`AKgY%S0Dpu0_ zBmrzuuI^n9 zyS;Di-dQ#iOXv_pOP9hk%OXQV6L4x@?oqF)90x>Aj=XJdA zZ^rf+nESQAH3CpW?)8RsKt@Af*F-}PUh3jtej*%y1P8xSTS)>f`LO2z8&wNSn;xs& zO=;RxdY*%_Ug?8#O9$;3E@;4|s{4%}SO?PNEjz~ZgZ)5RbuOL{WSbmJ?>ft;@Pkd6 z6x2Z@bAfAoyfSXXDh-S5ed&psKJ5j*aA;8>c0YZtvD?o1Cu{hvO5g4dzHO?e;5>3! zCoA`2@aRB1546jtR9Ix91D>JJ$;3|VFthb3R1E{sgqOFf+3E9X~6sY2Wkgm2m$ zRod%Cdd_#=jk+`5m;H;iJ?Pk8{1LylBEp$7$wynkviO)jpf#U+^NZo$qw2+3r_>OU z8c8hgyyon~1m+?IPMhw#?hNFogy)6wcvmh9Pw`^X`MyDERSVx?0Y0ij-Zb-yFgB_p zHeA(q3|DUkTh4z^Rc_f@xIYu__X5h^*UL-1P%<1H8k64o9ndtF<}M;tx5#S+eU65q z5r2Lnd}=+nq=30`DW*CbYn@U5_RpQEW_3`3T#jd9wty`Y2^=hL6lz?rag1C< z%9-n-Oggp_fSTHpMJsUA)zz^%N#2-Coyf;(unkMb%O-UlAb18xv#ep9z(p!1dd#{$ zE0`jnl@kjKE2kn^%D1j%_lvH*PAd#zc<;C0cJHmWvWzSeU6H#o#|&RjK3;_&O2Qz?6BNpe(4<>TA?l}o%sODac|0F8UflIOqRnAEnLh8$w3 z{Ia-tI4dAFASCO2uJ(nn-BpW~^Cn$OL^P}9h3u1UD%e_ccqDhh5T)z0PA%d9$4 z!+3>KsV8_bv_dIfIzuzjgE7~=FO>0iyWUE`V7Pw1;_fYy|HtG@VumP_*o zGz9T$gnraaE!UfHUAff4lB2X~Y?9?dd$V%g?{ZB_9wvrWaU@>lbK5^I$dw)5;l@W4 zO*N6cHIW3MX(*QN&9aR$B0nXA@Ysf>MEJ z<$wO7F{TWXoDy0CDB@Lhi1@!US;gAQWw|n4a&as`bS<>?ATR$QA({vxiAVQxq)tL` zR+ZF2qB`6EH2>|x&E&szUyA=WuPiPVN|fCsE;uJ=K8h*El=dYlQKs%uue1Bvt1^1X zdF7K-jd+4Sm28y$l&qadYOPYa08=1&Y`Xzakk<%x1-7Pzm+^Yxx0WCMP6&RR^b1!S zdnd~N#-npv$q=>6jb%FU;oGa)ln)!zxmSb&6Kw!gqmXR0Va{FJIYa6HC0ubMJ?YV1_SK zQMJV&tu`8$p-xq}^}{%Rp(>VGNMhF(>&J$aQgfeyh+W8P4l&>26_LBd@a<_K!=Hhm z*oA*_?rwQ27)lqxTf#(l=?7|tbk^TRSy1#Cf69Qwh?<%My6-QoSq=M~=U> zA9~&;tK=z-huT^@R_$`OBF`ix5~!OE+Mw%{qpj047r#Li0eL9qEq2kRf|~|71QMna zqM_W_Al0kV+B#^#brW(T!r_;QmL}AaQg4?e+hMd)kjoIE^as^a8L8IOeNBbTxo%MP z5Tw`9USILO_mXPRDcI~0rPqKw3O7}*^j?&O0tEq^`N_!b?Ty_wN_>8m7<;wL*U0Lv z7rS*KN%g6mEP{shv@8tSey2KlM4+hi*BBk>m+iewEfr3<7(V) zI-av4*c`=(O)C2f`m&=vQYOm$k02SK>yfnC21r^LF;Yc@O>P)z2~Ez!d^EHSeH4KM z0|NaOD!@fpE${V2`yKj=y#W!A1;TlU=i<~sQPPU53reg;f=-_dQd_%Y6r zSg-VLv(gVBo&Buy$}XYeZZ2c^c6^UrbSnwNcf*LpF1m-u*0m#J7oEmy>)Mj7R4!pS5QllI5IV> zPZ{d^5RL`8&vhni;<4l)4G|Jv9^mT+v*G{*CNjpq)VI`+_dJ|SmHZS zgH$$@)>6#lT}sgb2l6M1NSNoo$(Y=vM|d)lWy`5wGk{wJvVw*Bqk5=5DbL1rX^`rW zu}Yj$0JtbG&HQG=+9>R&MH+jflcOT!Xabw6AZ%w&#+)8jWapSB&y?3Xr2U}o=ii0K z39&n0su@?pq$rID5{kRff=mxr?+A-zH71%c_aAe&YU&NLQlybQZoE2PPo&fazd1c9 z>CH-~292q^@dHf0vfF&ImWBBU+GqoPIr-LWqo)-1Y&MQ^>4Djp_T~nfE(sUbCdWs zfmSeq!{5g{&tVFEtUD9G5lU4E7!|1xcnIS^5WwjTDN* z?~WYlJK5`}%}xazITG*3aU*@_l=K7UL{Qdr#18BL{X|Hr)kW>G#P5LSEoogAAxk~U z} zWYmvcH)&VRSvufE+peQsb7(pfAZe=j*d{&(PDtqweG5{Tp(?_Bc@E|g)QQyWX5pU( z=F~62D0nIor-)$oklBo6Ed@fnEm?Tye-GY%S%4H(5uhIGYkYu7NFw==n-ce zjG`0&3!r~w0h*izXbS;q2@J$h?!yM#>B(6@bR<{E&gZ@ZNQJ1$^mC(^+MvvaU(2Pe z3^nY@x^4}Ya*X}jv~^-Q(5~{nMiADc1)&=hw7MWR z=Pi(Flkq*^uUtdo*n(I>cEMZied;ai`ZY-EpX*LW@UR`>LB9{}bCx^Wm#Cqn`}HV~ z^GLB;W+>Z@;IRDiEgYg{g+tl87)y)+6)1Gyd38SP=NS)PgB$j_r!PaT2BlBrmc$;|P+HV;z&=LIP~Gg<#|L1tjly0$QOVWqqw$SvsF zR$panvT}43;%r^0-5OZ!ruK`Wa18|K90Xod z_0gAh68yGF?gOZI4PHE+7Px)F=SI?dJDF<^W-{umcX`YQ!dTm|Bb#|5No zG6+1fdXa~CHfL1h4gc)5*5g$39HJqUd8|Tr-CIocLXDo^dL7ivMJ;$2F_A}UGZx!( zwVqGmxqT8-lJ1aP=Z6|#Zq9Kv2tjwoekkW1uF8r1s%zT$HNR*rDQ85_|9F;Se=XxA_Q zCd16Is#&rdjqCtt%)IpOvKE^(&`pbjr zlTu4Izw&GPr^$g{4=?5GRx4WHS=+j#*j{jK8cA5vhlgfsk%4_PHQC42Dc#pE)qAFH z{@69W-LkQ%Zk(;kicL)qoBCS7=B$8q)h?}C0+>V^0;q>TgcI>6pdm{4Wf2gko^Mqi zgf5eaSjIY^vk?b})LN=q4>1~Wj>i#nT0~Z%H@2(yQ)~^E`0Y;%d|apNRkxq2G_LdT zV9xt6kPo%Jv3*_rC(mtN7OD9mmgpnYLDQnKBu9Q9fOH+}NU4H=_>renzU6W1J=S(d z27aIa-OEVPL7*`r+E`n&bKnEL549k5r^ZSU=EPS#D$u5IgrY{7&GC1?GEFio0F0iR zXG&9fF5E1*$%NEy2?C)ii|4pW=+IN3hY9|1cgFe z7(IdWm|HLHqoRJMpCBtrRmr~$l!3{kj51W1zb0ikpHa5-O9$$sR}<_Gz_bdHEoxa^ zZTvAo?ybq)`dMMiE7W+x+|=i)J6@fbJ3=A~h~PJp-ALj@4fbSFoxazR&!%ZGmDhjX zS8KOABq{k5Xlmu+))^D}#3Nc?l^iosYlY|lv(^XQzwS%=qi3dDf3y^rs2K{zCO1va zXl9{G{m?C9iJ6X+Vt2;c&zL3=;uBqJWM|YmTbHi-B51wA0z~lkYF$;>@=ppC528@} z??VuxU3JR_f!hJk%l*RuBhhvJb8d1(G0kaHZZ50wS^v*&Q8`bO=dS5h7~h*b6KBte z*sZK_T4s^jkc2)#qT_cwztQ;K{-1i&73<;=wTp?yvYzvHznt3N;QJ3o==1mD+35%O ze}5}x-P~f#dIdOAN+BB-Ad_z_{reyHo9t)s#{5Kh8`^K;=6}|T#O}C}n6qAgEQ5u5 z);*pjK{QJct)U=7S)L<-MAE&C|HSG*mcdyh_x+p<9Ewrca=(Byz0>%Ol8D z?zrUozm#FW;jT`;heVO@&(iXB>z}?6{~kSK{q`_Ezdf9iQ~i*KcBDWS4=>~}U0Vd* zQ+v=xsrB1KHi)o28~_+9_Y&yK9-Xs^>BKx>RjT!+kieW z(Ggv)6SNxtnomL&aemGNn~__)z{Y$n7X9Wl*C^W`tfW3rs{wnXw>-R}beHF1k9@8n zzWy@Gj~3w4LQXBuk!zG6xmw!?sTU1N-`Hd{sZzRk9b@kTj zwU7mY9?->>f@Q95*y~Qc%3s$%2=2K#a5Y%!3GV5@P2H3(n7y8U=P#uy2b^lEV(Ued zXO>{OM<@HX-ywP>oQ`|Z=7y*qU%u30ZqegFCB+RcY?+&K(d6TUWPBEXrqV_ko2isr zYw9R>`#+rh`@-zsDNa?bapyW8(oK`EVjbB@XUQo zWi0=kQTRii{+D92|*-cit;?#DTa!eXpRw+2z z-A84O?oorY(?6l-3(||T(_c)dGf5rXSHyVQvUqfYct!qcw_$nyMn=IERlXZBC2e-85b z4_+ItJ*p&iZs#bu^T9Am_e})(vIV$_EHmYcXm6d@ufxeCylge0A7M zrT(rieN;5$i~lrTN#`gl^l_K`)Y z#v2jy2@_}uTNS_BFRyrNlwZ3@$G>1VYB|Z>ErI}Z?7v|=z+qgvjv;v>?UpU)l0wNnp<@CV{1ZX=bcEHaVq))o00Rb_VsN>Eg<)DYQ5F=uI_+r%z2D znJb-Xtj&>R+T8*}iAD=4i=3n+nF$K)_;ZFJ(Z#c3qF3;|Li1%Zq)S}XGy5JKG44$0 z&FJkUF$^>Intrp)*o^ngp9o9m#oz4whb~pO_9UzBDyXPPo>gM&T8{P~x)6#dRgqg!&DuDKgn@2M5bZW7qO7YF74gfT`L?iAsAz02OG>s>sl3>BRtT2 zeKS6>dITitIBGVZir+Cl1t;ZZ`FEYZ`1SUrpgn1y=9wku&+5;_aS%VXoAF+O=Wu0w z^3cIG(Rlw{d%@}c_)1?Z%P8}bKzH4j`TM?Ya_WdBHV0DjFm75d;lNFrBf+%{M(f;X(nimVYK7jL`hu}n z>jvosmtk=%6dw#g)zaaVjqFOw{41_=-x2Vo3O@0z%v+-S2DR0)VGuv;FDsGFwgDy$ z#F&v|OWXT^6C?l$rj*DtL{e9?_bhNB8!aOk@gH5qcxrX(pEv`73#xr|TzD;3>J)|K z^r*&uZ|jk@09rkz=9jFqF6=I`)7g9tuW>#>K^)LlGHH}+=6w+zwCbdj+#qed*GsnQ z7}GG@9OL|!hQVF$1hm>l8~{c&u;n+R6Fag@mN@D^_7<@R9+>Id3L7o_H<2x4?>11_ zznFrImKMu5AP!hJDD@7Hm~De2i}g7DhKIy%nnybJHmxE{*7go;Z)oINPDja)3+ zeMq`IQIS5v{YG?MZ5HW%5!h388NUR3wc_8>{&#+5+W!=QEUMIwcEQ{t-Yu%cZ@q-Z zZ>NWy9vB`FrMHL=p#N2wV25Dg)O80pK$$x<$s&wm7 z*8QDkzxFkX4s#S?zf{`rQ*x792N`dnp#7`?(q1N~VvU`_0VYe<^^T3~fI@G%-~GC^ z8zu#R5FHMGz0ALAa9XpQty{u3pyNKr58}5;DnvIJCBHOWwNKajlaHlL@!yHX^@0g{ zb@jghlk!p{XR>%PHvR1u(@}sktZ|6`BZ5l|LCcMX7$PsZmGTaWaMl9CfBZGu0Gn_B zqLo<$%_9$5HdSNtz#lFyci(gDs94w(>^qvw&yDKdW4G zgx~g_bm)fTO^5D-_^D89Qzzmgx)cV3r|>QVFe%{bM2|{#TBS9U`VVln*BA6^PfF&h z@pw_u1ecL0ri8~be`lx>L*+ozK!&k>9NjB?x@*(*R=Kt=VXbkm*n-2my=RxKi!edF z;L5G9KK|?O)(>NIj{31C#rt-8pL0}q%Ss3<$GsdPOv~#lepCw|Mq-&LnJh}of<^q1 zubRAvSTv|9m~IU-{!$s8(%3}fAToEo?7TSI+tKfeSEn84`~wPA0evuKtPs2!?7@@w z?)=uZuPSnc+zUhLg9Gpt%DF<$`*LzwxuGLiLavroW-ZIw(}(W}WB0L!F_C`IW$ z?&eQz?COr$50(8<*zIj`l#9dJnW%|Vjgza!yq2Y0VDz_tMw1pxW|ZJczDF5 zd>aX>on#ORK*C-Boo4r4<7Ucp zzx)#nU3`B~4cY~hp>@lJ3CqGB0T8INAryxw;*W+WXky#uVLM}G5aXydO}4{xW@aAV zoQ0WL=e?Ad;dX21T!jCF{r4dgWn*bV{2}g_dkG?cikOZu(7TTiI-Ip1<)N`Z?1Q6^z-TSHMswkASw4>9b?L)`5hU= zLHyS9D=)E@Um41LCC!=diL1+*)YJK52OInoLilQMb#&p$^OsV8*s&A*(P+_5SL0Ws zN39vGpxWWB56(~CngZ>u{|F4nO}rtl$T#|pWa5__zij?`aQ}$4kIuJL#kYUytd~Fk z0ow|XTdYM=9!;#_LAT`NPY?6U_(R6$I=Nz6l*#uC+te+{fL)oD%03C5Hyq?SouT-e zrN!>3WAz!A-(ZFC>iQ`*rX8`;1`U;`T6Ea-)r|&=_*Cwn_prGz@~#q_I7Ci^2=-G| zMV*7uqmBV6_aDV$hf|jSdRnYtDSgx*5yljEU#bt{3i+H=03`3tVM1!HwA@k{6v`;Dd)(06Mx(diZ$Igr(U;nFYV z-c(DLh2J7gYlhp@7!AXQf;ZOoci9&tzKiu!=x0X6r6T(BB&QxhQ`L$5&xB| ztdlND*o#QddQVs zn-RA(J*(`l{DciK)E@HvRR~o6o4?3uOT|K4Y*G%}MdEZ&ku~B+pSS)yXa6@`R6UBv zkx7}aPt#@45pGBmbULakKk@g69B+Jidq)OPB!wLe|$!W{`cJis9% z7(&gj>HE*CrnbV?_$>GihN!f_I<*$1^+18fqSP_6fe1-Xpw(qcfCufi93d|F>uTW7 z0*mNRJ&ZUU9^{$9Guo9jJR?FpU&@isLUTfZCd|-vwH%&IyejpYT6f{Nbbl*vHT3M{ z-^!55Cy^S<)2s4m3p;Kh>%+nCyCc$eXWb(HvBYB_xYp|>LB}SUQ7f~tgmYslUaQa$ zS~ZDSRwZ|T1>qZa9){VQaYoUpM>%_woXJ@djMt=asEWVhe6tIfA8pE3%FeTu!eL&t zDZPJV6GXAZ&dvr*f^KW$2LQppZg(7jPXG7%;e0KAI8|#2St?>zc7W$f>*8Mkw1!hp z2?bS&FiIj%mC!T_4QUg9Pnx-1)&7-Lwlhu6F4>0pi37}eZYyy_S9bdy7!S3uMKU4~ z#5Vm&L;+#tkbhb`Ft$Dg9=@96GFK(m!l$N8zbNh6Q`~D^8rbmzd6VX>)vwbVC@Avl zo-;e%6hr|6w^Zdv<&>9N^i;kVvNb3v*`x+}Hu@3_}Yy!hF6S70Re|DOQf{j9mq z<$xl7D2*|1B;t?X-wiZgaEhybQfg*A7#4h6$T!&)iFeT6F2AM{$ye=o9`Wy5sC0K# z^`sn<{={2Pb^IA5rH%#kT=At^Wqu#>^~N5`(9=R(x&Og4Zel$n8e(f4^TaTgHjrfFV(tyY^6h*Q;joUsUr6Ty_+YUFlYpNI|Us)ey5MW^WW%lf7B(!eh`=>z7sVy#o?7R9UjBH`__t z=ip3u&$ZVLpo1CKx};z1AahV$9zstTG z9#QyB`&2G@nOAaa4~LNA)oNJfB_A z1#asL^`TrDcYoni0GGfWC&rJc{`ekwo5K26Z4RgO#nkuX1Rb^3gp7(8!h<7b6` zy?bc#ui$|?tFvo{HEakCtD+&E?)!lk&5E??9wc&%70~aQbfAPCYBfi}ydZt7W`?XU znB>pd!*ER`U)qkvaoeD=EiTU9D;ty2Y_-`PtsrO*8$>!X^)0E{_WblG%^n-~k%HM} znjl`z{0TwhgT6QZk?BjC_p&z8D7x!;_I&JBFvbd`XCyMELXOk-H3}1Zs#fV?W<^r1 z8Y`nyw4^jy^Dl?H0y@q%$W^RdYW~&>rcH;x#-`I_i8YRswYhm@exm*u0#}ma&5~jk z(lofJe|&)PLkC85t&h=k+b;=%R}Ya@ea8Fc4!ZgnbZ!(nrx2m6iH=BUPqY69u^qwX zv;WH#*riJ-?c5a=eDr^k+ad~*JCs{Fh4k+F)u8~iepT?SUpL+0Eq#kgcK?B+?*GQY zD}EC=^4yhoR|hkjXunPbzfK*~@U7oZ!ygfp$%ntOgFl|nl7scaeX%w?H+ksEx;^cA zyqLy_xKEt?jQ&qN?UA$&ylso9TzsboSH_ ziw`F}PW|NTrt7DUu01Wtuw1?%ccmQt@8@&|^uMj|_FIURF4*N+({4w#f@%J{kDA7` z^$uu!nOx#^ZugZB{i)83v{T0lhYJU)mS6l&5H1EnYDY?@>(x!UuH_lMGe0BEpPu{- z@uyC3o)6`ZJVJY9QhXnORjq9rwafZul6*Y)HkNOU3n!vwQ)sbMlWagp#%)`|q(GST z?VGze7X8!t*2B4NS)tsyOWPVd)eq%w?uTr{1Z(#n-6=|19s&A9aYWWO(R)5;e%u6*_Q`!bL>ut!ftESQ@v63Q{Z$P9|0uOos&5ByJfM!G`b zi9MPt$`E%TZ{le_reaq}C;K2B?Ga2bm9zFsS4T1DLk4pM{r~3r*e3x=nP$oqr}H30 zgQK<|bd#fRbom!$@`rN?%44c|vg;}nb6g%v+lkIv-DeweBVW11f+{LnE=|%-nW@sI zkWP;VT={q5YWX$vPuUFh4pW;)#G z-E$MJ9|W4UT%9!Ht&QF1KC828OkJ}!t;cr$|C4f0r;RfAbQM+8kx8{w!v(x1)OH1YqKQV^2|KF({FbQxmmi_}$B*QFaKIN!e}MFw)qorvKj={gW75TFb-ELz zMJTs_!4eDMTagCP;X9Pt9cu0#B#K+%F0Nu{Tu2{luN1Wtp!~<~{!-k(h052HC@Gcb zBflC>NZM5%RPKiL6)j$8N+%CFn7>cQSIu7^^@JF5d_xcq;A|K9%<^I!*J6s!=jss57v)1FO#LH(pEmVBKe{EhE&1_b2NIL5;E5y*ek_PE6=>|bcBqgM!Q%Vq}q)VivLrOr9loBZgDJf|< zvv2UxC*Jov=lZVe{L&xpo4sePSv70ctf{4%i{I@_CD1P@b_B?w`y!!8Lk@(U;2kV- zht7loj9!dNjHw|bcGi!CwRu<;4ciu!IM1v>DSn^{ghS|w@GBqd(Q+9^bb0PMRfmAy zP%!k$1WAtHvI7@>=~r!Yv@j1A2j0NOcfY>SlffEOC?s##TTxht*FtsP#ti=cIt7LY zD@f}6^)FoKP?O+#F2H^$bnrQZ3<^oWZ8ks>KnRewp(qX97j{0l459}7LJbnyIUo6# z?}PeOPz-$qcGjNJe}4NZo4>MSO`yiJCB0_QW~YD?{?$KP{0$x&C&O?z{+#E777qTZ z+v|Uj`z3(52C8B?`NGAk{0;7BeDP0xy#rSooWmJkz-j#rPV9fEFYYfmdH@Fm2WuXJ zlpt=0hHmE2Ag={0vJhei%;`mnA%(WSfkKy-L-M@?;CLbD_p@mkhXOl>1LF`d!U3bP z^R>?a3m*)NH)X)=dDsKM5E#0EIRRMYrHv|>E(84mRu}=$B6%n=eBOQ`O+p%_hmdc> zytKiyrKSQn!6|L@PRQ!0RjzzB^Q z7##KmfzSj2Sb!Fa2eE^&q;gIoIaE)?esFU*`4NBDi>RloF&Kud%UJ{HR42Yf-K+m!bFk3(^w2})Qq8R*!dKyRrFy$eF z(I8-e=WnFE0FV$VkpBLQfz5hA%7b%KAdmJNzEMJ$;lwv%RRKr5tOyES_#?3Y2~1;v z{ZFDW=lv0AOcb2Y4ZHf938)KNR0pkZ{6EcLL97u1!Xg7EFY=yHt^p$R2zny?@|SXe zOt9Lk>)aoJ^RHp`Q~sJayFr$@tvQb30<=R9e)Z-I{lo91T&|myR z7wd_F?%tX6|4QHgr03)x^gMX;U-ZD%f5IpdJ*VjNQg`a!8DzpYuI+(F4rXZ7fl{H} z$Up5JJYlyLLwaA*quYaA#l;5Izx2O^OAI_C2n9Qr9$w%3J@~7j1%yGigiQyYkpajR z=L=CN&fg+HOVoasV{Hvgj}+(YKOuVEn;{9t2*M=zd5Q3XUPrtOdgcE&dJAb`^uq3y z0emd!k^ZFf1K{_!AoUlWJpV~2l$Q9NPMp8d8FS&k&gZ|IAcALZ0fMus@gUz?59U8X z5){lzLGEWMG37jl1edfz^AjLl3H7ZBLJvsvzMv!!Ig|&11Fs+z+0#HQgT1LB z=LU)}gA(8f0Pu?q`c+E-{sVu|Lw~GL|I7#cvy|9xrOwrHK8-mF-UEw71{e?$pfbNX zNt$X9RDvLqlpHo3q;G(G zhQSM1c&!dzfZykxFx2J$*8f5I;h^T)i=G!o4^|+wF&gS1!EE~y&v}g?5(4g+4=Zrw zuWzDDDbP1qN6NQE<_@Dw5*Q#f?Jf#Yl7C)y$rOBpIk?|DVW3tBRsj|(h%UV!gTVu5 z2yPYuEJ4x30prP#CBKYVVK|E~NJtY0z2KKxrNq@X#S2(5@pmtUx)4 zv3eLF*e53n0x+<;3_{}z)Y1g~7kU6zL+RB}KtIQ@lrAa(ed~4s)Wcp>1yl>o?jS?e za1y{=OVktqi46E~&Igb$hvCIa(_daFdH4sUo2XZyD0??hfe9$$47!B(fDO?V5wN@~ zGC)9P_l(~enjFFg^nnjhOOyfoqu3yegZd58-=~!hYIl*DT4rG5ioUb&@xnV#gtZ6JG zfQa*N{;^gJR0Kp1bEM!2b4bh6Ac=M!7eXyi1q^_J`vHjqU+^9xnJfIt76R35P7Y%$@CQh~MFuc{ z+S%8BF9NN%1;y3|e?Wr_n2Uosl)v$Z6}1jL1Z31;i#kLlY=0E2@ZaRIJOb4Mi|2kK zgMD9a0PkULbon*-_4C`W9tno}FKO0+G7z79_~(2={sAlSA$a@0^Xg6py6_8MB7cD+ zJLjk5W&bVty$>)~205Q7qQ9X(Z}hgXu`h63IskTA9M}S&@qB^>{(tmUFdq>a;0}RI zLj#t8Wa#JMIW*MzK)d;emLY?K)G!JQRj{ICfw-4FKoyYz8o(ZayqD*o5uWp3>uaER zC!`t*AJRE5;vI&#^Z3jU4O034DL$(s{qOk9Y!3(@7N3oy{||8w6!ia!&yc`hKr9G} z(DS!YfT;BM_zaLcUImf6$pIsG6|hVJ>REd7{u0<^q5y!wLj`((SPKtY)N>wa{aR1- z6bAq5H~4TVSa&tR1A+}Hl?yD89G_nYi`CDuL3NaZIxevOjK2UqvM_um|HkM0FMNjA z{)W$}|6lkt+1DVI>{dcNVw~eV-!XSiBlEv-9s-=wlO0!5V{e@4*KC zgi3(6067ovQv+(cODX^t7-gFSsbj-tGXlndg@M2R8e%s<(nR<*c8vm8tAg(^X9d>H z;eq|vpmr!wLx=@gKhV}9K&_wxdLX8YvmwsKztn~dBd7HzxHGh*iFv6W36uv}63|OP zd)HtIa)1{aqAd-8cnkUlda!sH{f`vD37%Ri01z4v>qF*s?&r0^^A}(A-!DP#iyqqE zfEA<#IpTBSZGefRzbm)_54-`#G+ziW^l%x<6Q28}3oe&oYlD~6qhYC3V?YcVxM3*` zv@EC@ftio10OIfYVBQKyd&+Du3mpceiUKPIcZ)-@P9Q4K1~^6wB#4)QbRo0Ki#gAn z!aadS>7CBdw8qcNrj|VLVOk;stb?)&ap&39ct8%2G4n;F8v|7W$uC^=A{&ITB<2gD zbA}eMg7bl)T?^PiDtPCALYKNh!iM#d;0dK(BtwD8%Y&nL0Tgt|xFpP-LNBE-AsVm( zJs{!0tihW`N>2$22D^CtoWVD5K=F(?E%87Nn=^g8Nd2!a8mhX~<;`FDti-}iw* z#=l<ktK)$xr=V%#K}Oy98E%IO~T?1CcwEFS&96 zE0uzN%ZA^9+By`8EMdcDd7Y`lrB%Qe*e19&AnZ^n=ub>Q8Fmd|2RaxV+{1QmLB#;k zg@1s)pN|USRzGB5G{4I|0r(-%z!I8a41+A?&u$B{1L(q&f7korAN6kK z{^I+W{Fl<8wW=*`On`mA{g$({pNRj`Pgp4=pG>HLIoMvW0a}_QXmN5Hp)wjUbpW&I zScY{};1a%z{z(%CWOoiU44NpkgIN-CYEJ-JkfRz3-#=Rt1_z4+^M)p^m(;)wx}djF z0wE2>H00MsL&Y^fRnU=j(5iXJ4u5(h$Tmd*;F7^N;L1B8eCmLttfWGIdg)2%h5s=C{zvaG|Fbmt8+_?GJZ@wF zAN^nO%i5rD%+k2~=29*Q-0d%s<5_G@TPqMVni{nHFEOGuS4iC`~ zunKzIb608$=@T@|;PWTKyMO2xCkMFFEvVZ$cbvbiNA4_!R5-%`Q{gbgH_!;|ARcgw zfF0OcZ4KS;3PcWFBWeI-tHKU*=SiRn=r1T&0mAvex>E(nJuGcXLDFV6*x36&g&XEs54~xzJS}WA`51xcyUWVl$Izldbv-2C3f%z`Y z2Ln9=+5iPeAZ4!!q{Y6rG6>6ejTJ%sZqQ%w3-JmDs=)fgBV39}h|D2NgHNybI`2-pn-eqosZ2j)A$*#XcxeV9hqpmqz* z0G!XA!hAMxv(Qxd@4j0&`!XE3(HFAM?Z+^Fp*{+VFTfo5d3bApsE3{`vPu0)Hg% zM*@E&@J9lFB=AQ9eNS##bpv*X5lGac4JrZC;U z_1xkg5h9YdIBb#czDb2CBpxIZU@J+z6;6+*O*0*oFRMoz(Rw-9a+BrS$F(H<9*(>1 zSYDsJAZoLGgct^tI_jKUQpg2#9if!dyJ@m9wAB3`tWE@Eh{tJ{fsbz&TF zN>(eIysO`e*N3AB=O?jt?DJ(UFsm6*@3mhmylyDP{Bcb2_14LP ziy&9Rn}|4W@$k1@w!>t1xrgi?g2THTMUm)Sn7<+PW@!rHORHbIa#teE>4 zTy-J@7nZ+ZYNWhMCQ5H}151TADV-)-c*}Z0A zHmP4&iBFg3T|hsz;p?i4kA_HjTg>$J_Qrkprswue@+!if0GXf#MUA+fgh zT_2~c3~z5~ZfNm=0}Dj8RbLooBX`7e4Layx*}n_&(Gn?&roob)e=fTAv4jnyLRwTl zi;CC>>ukn>G`KuIou^J6m#j2yA1R@8Ax|uS?K|>ui`-g@GH&}?Si-LL-nvVbVr{eq z)so6{k1=`y*{=#-9p()Y_;_fQ^A&|?DftY61+~_1S)1P7!5HGXVFHJnFu$K;?tH1T z=`qr$yE0UtsS^brmmlW3RM3j|Br5I2l)PLRxXu0*>vK<2d_1SJ1;SDDTM^Zl+uyoI zs4PFrpw!-@Q&}w;Wc+fl@QK^L*WdM+=lbl6PK=iBdsK}Xf+z2DSz~#qbSY*u+haNO zO=Z7^qhUT{T_-<%2Y0MF_6*gfpiC-8lS!&DIjs;A=d$*uoRyAqH?N(;mm#Oktm(#} zcg`JEsty4T8NP6E?x?wExpS;W%ItN-Pj7JQ*k9(u9#7svFGjY3ldUwoYJ6Yz>|s$Y zn~?R3(xb7Jxju}fH}PHeh_}pr9i#oqv_E$?(A^uZ9=C0g#oR?x#QQwJFW{7wc~E3un`zTWc^1EOulUa0);n&jM_cdno&BWu zbwgZVNw{>q?J_1C`#|zO)W5?mGI(h~5BsC0Sh9B|+W_*A!x;KI^UKmRkkEuN}w*%~yS!Q*Y)7aJu4FRGC=t z{TXxi;Bb@kO@3+0rz(g>Jx|-aS?`Zp-FxdK))Rh0m3&pFm?8|Lv|wOvg(KVnQvzq6 zF8W8dE7}od@dOE~a7?rJHcCA{=f>t%pf4ku|5!rjAhO)ft{nyb^D(`5{sXeTWlRun3wiDRYX zZ1HQX*!PlT1S_)9&2O}=*cQ<#OT@>zPn{GqIiG^ykm4Bx;?@>QNjkR^4KW$mYXSL8|-I7szW&M3x zd}PLp$7NDaDBmu7MOv9je}HX0*ZH1#SbgfEzn1HQ$nF&#LNZ_JO}8Qr313uV`l_8J zubV4*^7nKq_uZ_9AKL~`y@gYLKly{J&G{1YBnDUHH(5D0BjUas0j_u>j(etw@~WY1 z-7zz6PMCuF4f^ZjZr`ZH3trkBM7+IkHH~JG)w$q_8X8379r%?0OHHE>J60fi@`FMJ z$+GN#n7SuUNJzD2dM5X014{}7^DW1+8De+ z$nT^lxS#Q~{^{e;?bB+XCF)SehlxzBMwFRvg)`JhjtG$~*Z z5$}C!ww1MP;^f{kj&GRaq}}#4ot)A1+Wur6pYNR^as@dGwtNqFlku2poITc!SIuu3aVi`D2VWw|;+-*JS!UT|s`(<$S1HoxenRUO@iOjmZ1Dbe$__ltVdBd4rIyQelMSq`2nyGU7+B|X>?|dswFs5L8iAlDc zmI|`ARhAq*@3UZ0WE)bdeSQ9_$|H|*-O4|Dp{Lk!Lw(D8E%y13nCBXVY^8Ge&G(+k z;)FYNN|R-p)03kQ3F}x!uwGTOwYJ1QqWeNp;vgCP7(;j{-FJiSP0g5epcT^=hiB-M z!2m7pwkCb*)nb-xS+mfN18P;0)DJyu{u8frXB86%Bqd3e#=JdLS#Q35F^Q;ttg5y6 z#zu}=*tGqb_nsw|? zzV@;@SEVWP)-W!TgLw=Y2l`zMsMH{6{I%=Si>L6~PPdCuXjH-rr_f9wdJuR(EsJ z+)nSSG-iM&vLOTaO&4}ag=&-R%dFSpJ<_GvJtfBRvbfL#p14E_khIP65F~mWxfRzf zW60k?V4e0b>o$IsTKtLJB21egFd@H4ps1%he+Au3AUQ=ui%L~nM``zt@t3syy|pwy zJgdf1!o|u|qXkt-c`EVgIHJWz8*YsuZe(E%jBc+mi08w6t~oyGHgaciOGPhs6||YV z7By=~8uN0rQ`10guh&0yiqto|v(Za=!Y|f61e5(!u)Fn@m7h}(!^yM(Hik2$tv;gY9fl$0;+I94UHRItOskCpNo6- zOFGT1{*=N(Ra6VST8(esDYc?fyP(o+9#1PoZ?iN(;JH9$c2lfR!C&TCs4BZIt`>4Z?bBmiLfnjO1#< zs)>u|+W2)o`wUomKGprCHb*YqYUb?mGNg_AzMS`T_Luz={lf?aEVYDfW>;yCrOD5! zvLSlGx*w3J5d&_~P<<_UxZ!*W=TutX&1sKSUi+4@XY5Uk3OhJo!h(?ca?kPVX%1=A zT`Z{t1zY&LM+;0v34t`IiwZ1q_HHLDv+5w?g6Ftm*WPUq^G@r-M^Q#q#e}vy;nSwi ztUp{1P2gj0u@l>B%X}vB4P0EWB~=&9Es9B?%D`V|cWtXrgDSy#3bmYeoMv_t$D_CqmX1$$o9V>YMjR++9}5o{#N$g;Bx8iJ+v?<_z0O9HLd$z-Dj?Lf5kJJf zm7%#5C&_E-Pi!1~H^_Y?&?)*nNI(UDQ9Cvo1qA_530fu&I< z2(%iUfz3rXRL4@D*l(c(w{zzumYK(JtF2+yPv#&BfBkkxeyp9uRS2VvJW3g7Qs4%o zb!+^DLTqmyPw1F?p7TSqxE20eff0)xwBI*+TOPuqd&>(pCmTGtr!u(s!KT|<`iN4_4u>1?!OJR)W0%fB3piXT3VGL=(!uYP|Sg|H>y z#Z0j+d;FVrw}1~HT~}}f;n=?wCGlS$@jJA`))S_f4bhk1Mi_2;v$|M@yNjZ~L^t;- zwTN|Vk(pCod9@Sypmm5?(a#z$qaCaKPI<Tiwsd*AW#vO?#qc{f=H*`SI{^+C0}D zroOw$Hi~Sb>%*$FIco0mplqhE1VO9;fjNNFw+7xR3iMPd#bJ z`N-6eZa(nq9l8N$Cc`IL!@Z@v$Qkh(3B5?jX=(noM0*9tj@XPRqCm}E{PtBTw&rXG z(S@)qyuh5mP6PQnywAkHWK--JY}}ah)v(*GY|KjNPu}N~%8a>#5?y8oZ*VEJzeW~Q3tOWd(a@wWzJ$~hKlC63+=+@$elq&?;?M1D{m)*iz8V@7^7pSue8p$b zt=aQpQF>Sn%T;5Qze=>Ny`YutQo2^MwS_sIN1-sr#3O5C${4dGg9D>?9gFWz^{( zKdM`EsCG!x{4`YbCW;43=v#0fAt!0x`f=Z)y5|h9EQ`}F&$M_)2*&PKEvw&J2wmi& zNPyudv*^1_LEDU}w8Bht4DE(D5Ki^pe9ZNn={FfIO~vmijdpz9nwFwTDolz`(sOfN09T@A7&@Xczt#Ad~lRn^hpFCn^?(ck`lfi7$% zLg$;D-#B-$w_SPkU0(95#u#f{Bk7(}j#h-$Ll&gcn~$!4T&+`U^EB0cZG4yYKt_z%%c;Re6-UnUeO>p72V8JazYjHxiCHt=Naf6SY#f50W+< z=9P^OR%s^t-f=!sanc)j@oi+BVTrh9U$jYOGKwFq+IEu*jXZ=-{u^mI50X4({=ohg zZd6j*xcbnPndsF{=jY=A@FhGw+$rdl*HCxGUfMno_5FUW*_R5fF!{L9?{m0GEWsd^ z;~IxA?c>Dd7(S6b%P`AZa5C^XhcA(ON`yHRc5??gdW3WTx@qoBm=4ayrl2~#mJ7_VaX5X zGvDs_KDcCK)S0hiYA6U6Z83K{Xh)ZqG#5l?k|oXdfntdWcKSft5$LaO7I;l?vO>x1Wh|QTvys^gkb@)AxDZvshda z<(#%qtND6}qu%uD>umq;ACDhizF*?w)1^|`D2>NHcHKhlR-HH>m75|T8mdWrQC9cZ zQ)MoJkR?*IBpEw>69ti0FIzLXX`PZjeAF9s$=9gt0v}Ni`w$BxtF;+(j<%dy<;e;? zQeVed3r$J+k|Et$yX~a6!KoTS9+6$BQ`|8-%$7E zcFnU&+3!nU?`ig>nsr+1r@slWuC=0q(TCSgke+rtpE4r6OawRagE^sWu;8ekXxp^(8Q&)pwh=9V`5!A>%~PsL zp}x{-j3tFWr|MBxj_j-aI;A^uHZEhJ@1zjCv6pRvx2-iuM zJ8}*BBHgz0_Diqlnd9XTt?&zmvg|pS_^IMkE~BR?Xm&TGPDT5?Cf{|}ng%oTTQl*db-*;|9D6&e8DwUFPZcCWcR1gLu2i{ zn;!4jV!LSZo{ieI3cmZCg8RVCkm4l$UHKYs`>@g~xiby#T;nSrHClS*ON;mDw%40H*_T5p0Z zWldib?Pzow_&9wY>>@}oy{VsgWOhvo$w*j@VBg?2TGd{=(Deee=(OuyPjCloJ=BOi zoZh}WLMU|*K0ISUnRDiDIlj?vwCAtsLf0MJ-t@()3JV)EmaY2AI~_TnvLB_J2How5 z?K`tB*Hf6AMOu<$tG~S3IykhWOXduB^08^KT`=wjIUE#ECl_9{FqOc@~Y}DYizjW*Ieq zS@+@->f+HBJhJo_A%7kC)V7^H+V^oPxYD1u564XieR0;EZtHO!mj{-MOu0p|yf%Gv znWc&mzwbz+)$mRK=#{x5k@qTC8Nzq1q|gg9rWk3-DT#BtZ`mdp=z9}M$vuq=3g)(T zPb=dey`^ScQQOP9JR7UpqSk2;n4m#3-6zVO(e>!eU-O0eMsCYPaDsjw31R``6${&` z7;jc}L9JP~nI0D*o{*CVES*s|uj;bqkMhd1E7_;Zjpxe{sJx>8;e1g6&u5i!!k zw=}f|?=us=L2&uxvp%*TsHAsXUIzq8$1CjVpO=6Izaeu8+i55e%GjG!jdDba@TQXgB5k>1mR7zamZ2KdW9_}%m?7m|(#2mv8IZ7=9pZf#*UlQHk zk6YU!78S(X-65v0KvE(6@VNHN7j|b-p`|&`({8a)3cY*H1lQNO54E_3)t??kmbfUl zN1joQi0}C6hdX*umf75XoYOIx697;DiLbzZUw5llu-(F)cPUI~`!u}o2fNhN1HwJ0 zBK^(zlOWaAIDzf4@&xsVGD8f3tL>=yB1xN;y^@xBU+c-=Io{C@q}4>~L_O8j9{5PObE%kFsbLmL=GNO$ zDgm>$U3{s_*(uluMfacKV#iP5x7P(@r7CM^+T3BmLCbySW_P#j@=QmjYa)6PTYaV` z6?}=R%5dSpy31yw%Pwn)8ao18yGJm&BloR6a?6OA13PkOX|dfK$r$1$H_%LVIt{gXkJjtbZ|4P; zh%t1Bm|MHF7@2v&k#L(lFD4xOxM_X|JJ=~NoIjO>sFfI=NQ_qdN%Y#m*VA4)Vw)Oz zT{MLBcq;iDMz6c8Jb85Q+6=a;CmFny7qA40jmG2p--ylQ7A*Kyy6mJ7w`OJMV_ln~ou9|#q^?uf;aKP3 z6knU(aUzSED^QT0v0<^i>8}|}%lSs2a}#wU)#i#n7ABiB+BYm&&0Al^W#0JZ+!OtTMscs`lh-Z}Z4w3-a%uo5h+5SFT@o}>Bh{dNz%Gm8l^}~$;16b`lU`qJQj;3wZon4gzd3yowVkO+`X;HC*3iz z&v8V!;A6sZQG{;hu^;lwd1G*8ZMsZm4(e|{IPvkk7Wdt8G~HR<T#)4gppL3~Q1F?=CX{KYD9gmW0TUGYDDPNDx zJu!V9g6q{|X1BnnV1H|GK2j~vgb+uyag9UBZ91b($KqjzO}&Nf{3B!8hJFW=q~u0t zz7HrZI*UH1O((|0iEvU{ihc_Bb@(lDwZEDQ91|}dTppG$B-NsnLwPw}#NSBA|9YwT zGty)1_xVcU(vdZ0H%*Abhlfs`{B=k3rL=PWmM7le=XPOHU%!WQ+GY{tRv0QtoE3h8 zwBuGV>&WT+WGY6TUpnF&!R)=Y2rcBB8RV2(%{YD4GgX44l(u?sSd*4|8r(9x5f7a| zlwE_T6!5~2pg>H;wO?-y z0$ta@0QUPAC}+EQ`wxF$IZcG|M9DmANOrw*sK5GBi0w3MkuJEO_S9ry?ZeS=tU=X% zW@a6{5z>@5%p266*pW}o3jDv5ETzM}%-wJ1evU&>DxS8;^uU(=W3=rjR^A*Z#IG?D z51*QUz|WAd8;()g>P2&seU9fP8+QdWVxpShd+)ae4(-l{sCV3IFIElGZ39e@oO$K2 z(~|=PEbz?+C=)B!>gq@c!eoW8dZ}NhR#CC0C4FVz=dtt5*u3<~tJuvT$cx{kb4=tu z$tCEm(pY=@j>v zD*Sc@NK0tKjayv=P7V}fJi-Kix;Z$vEMeL%zTG;$1bKZ&v2iK~j$x ziSEhgm8Czck*i`Yx7jg!p;75TyzBUAf1^BZuHT~KQmTvmflUVWt#3Z;$iq{GIL+_O z*AGodu&CQ28oCC>_sCg?KBzuE%1mgF&@;j7UO>v&c7Y3E>s0re<}P zK4B+#_uMJlAX1uk4XcC}3X5_0An)#4GYJo>xN78kN2OJNGONM3WnP6wVEF5|%p z4J0+&LxfW%$IF+Kj^z#%C5aBkI7Jm=cH zJx;bN@dHZa)4eA|FHCWUuabZ8UCDm6!+Xp4Ba?cG^}Y<>4h8+}(Y;mstE|jArc`16 zZ#g}uIG>6!C}-FU$l#KYXORzHdN{lA=4rOdH}ym%f3I~5B--GEwA=W+CXbBX3~CDA z-dp8F&Jv@JE_V^D%DizJ|A_3%W&52KDjijtr-XKU^OPUOutrKTIz*y))?=vdUhbJM zeY;Od{!uu72De)opEBZ!jfgQ(!{LiB61Qhj6K)`?HE3%EYVmAqYD<~gzD{S*J+25g z3Vm5sx7xIOrKiZ$uexd3SHYO9wSk-yA8H`yfZB&T=v>}*;6mGO!M{8P^qB3?Lebcvt zH*Spi5{5J}F(7H+Myjl|U_pQ+aa`1@ndoSWjF(~3!uLQPwyS7f4{x2#xc%s!l$~b$ z`YuIpV>ob5GJHb`19!Bpmf=##u_pDQytiZbCr6(8B6j_Kis_n?%R^;TbUy88z@xH6 zmo)6h(MO@Tl`3(5cbqI%Y}rsF37o>%E_{RbncyYjl)IP{cLHxg5s6aG-oS0 z?(f$MJWr9O%L6S)FLvr%B9RjdVV^+`MWt0& z%>#_;JGO5}DTnMGsjO~a=A{$T3a#_n%tIM1Z~yY+ftzqym=J!$2*#voE|MiTA>$`=znm%~~NZCS;mh`e2_%lpgleDh*k>#3t@Ql4iiN@=QJ zLEoSJyuQEzjy+7t+sn4sO9|x^-FdGeM=*JHA;4N~1E&Mmo)Pa&6knvx#-%RH@9qUT z2w5*lCyOpoDKNflvdoswk5U=j-^IY{M*2t;AK3p|OWi1dl&vbBXXpBZ2s_yYyC<(Q zlJ2`m3p~oIbIq% zsQ7vlEBSe_D5D9YWUF+kr1ErDS$SkcK;jT1-%PLpiFuc@pjhX=xpq!!PoLW)-&eM( z*pQED430R@XDGnzWqJeZ)4Qm%%e4c>adjO{2s+$KDR+oRA8)%dnutv|IU4d{A^LboZQrc?{U&2Q302w=-E`zauUUWb zmu2OeFbZiGClNX%gNO)wkJz~%BlkbTEns4Wpd)SP z{gto)c(utzS9U@?+!#IG_|Q2e7W^Oech^;i;Q|&3UTWA5dXP^#tob0-y%1=PKsZRz zoWH-#b0T?Ve0w&SnPHVJy!sPecHfLSn&}Kz`fi4GHyWJZ&Sk@m8d_OL!#>wcJ{t14 zwx-F~47`Z#t+zflXm0t8jBs&mrpKj{tUJhv+I+Z;B2qdvTjY|$xu>GcEXZbU9oVz{ zZYJ`Q0h{Af&yjM?>1Q`fu8P6i>?O=k%=c#F52zd{urn#`$=10<(-Xc3^>p_YQ_kYL68aJBtPj75C6qROqsF_|1kFNCZAUdL~&%7djT7hFzobOs~L-LVJ-+Lq-ciZrNaVQ0MdmwPIyVsV3bbglyGpF^pJ(rgo8OVw z2nzdvfr9I3gd^g=S!>g>;=32)Wk1AgXmLNNyZR`yNw}-sdQ4YA z{xOZhvOw$jev_e;^1E6ZZ72UrVPel&@{ucy8Lu+m6f(5>n9oXbI5lx}v|VmFbmt4o z%Hqx%OSQmzYnF7`f!s3&1Wsm(U}p_v5!CHqf|cbCH0Z_zW(FJz<$AXiu@ws z4Xt%d(osq8{6MitYwI}Y;9Fr$q71hW^3)=pCVaiuC*sWV$zNJ5XIz)fmLgf?$P(Gf zYPRo0P?^(4JiE}HvU1$vX;08Syf;HwM`K8yjrYcDKP4A^Tomoo@d*)BIy`NZxlt)P z(nS`gHNHwyY{6+sutrjjY#gE$=G|5Z76`G<(Cb`bde# zpX+>o(p}4~|MbV>=ga$nzE@lw!uhH`&!E5Vv^P~>utsg^*9&xU*W!Lj+fm}m+Qkrg z{evZW7Rb*RXns0W}=LzA*$*I{z}BLY#u19RqEKm zwOr(3dqM1OuC%N_`vPt`%Lm|Kdc}n zzQ0@b_@&U}(YubslL6&-%kbah5_<%8m0CagUf3SNizC5lRPd=^!O6$Qmw@hp>5>ph zeC#3T25!7hmHPac(-q;R+n>ltv&F8W`k30kc(J-1{Mn$c9*sA1+bWEDHF?pXDZ`kl z)mc6~NRs~2$eR*4UNSVPFQS`M>Bl7qK2=g#ln>)3Leu%aXUe%gM3+*`|Kf56|9Szp zRejlxd^)5bd-wXr6&=-UviK8cn6KZIJnVQCkBq|hg7HMNSuA1^bG+1{zVkI^2AIkOLsiFR!Cwf2a?P6zlPt^`uW$))0CUL(}9oDN2 zOS>C+Op{Mc$u};I#UT{eGsjWVG67mE-C4&+ep${KJ3_jvE&UG2Sh{8p(4-9be7{xW7`*4DEf~UhBF9BBqN+h+ zsGh$@E67mV=*0E1ttld`jV-h^pM{>=+a{2Tay`Nyp@CM7*2(n>H~Q+HMmfIKven%> zjATNN+{uFt@vp6O{Lf12CS&RSL#Rwt>`eHb_V2B4=QF!w=&rp&j;3C$&YrPIc_6_5 zY)4`$EK8`8%yTi|DpH~8qoP8!c(l?P4T8<)7bKjQ#!cILOF2-u-HIQKRPb)=neeq5|39WKT3gE@5a3At22Ea4zJLy}QGQ!sjP=ohmLo}?G?m}vtZUr*w4 z6!vH8bkWs$Ejg_;Y)AY;ko)bzRzg)wLhjqk*xo`b&I|?ULv(!tL4qM8DN=z^JfG(8 z(KWRV2xnoMlFuky%Doy}W~0*bnLxK0yOX4fr|7G9F_)P#eyKNXeQzU(%Mr1d= znJfw|&CIZ`7(b3WSm~f-}{58ijs&6t*Mu0_aSLa=)^h9-M1g{|j+wL9b zaO@rmc6prnz`^pif%$lX%&BO_HdF~DW*af{X6|U-)G_zMfhlq~%|genr^#>(B!z-T z{)w$!sl!$xLSJ+hNIX@u9xh>qxlbjV`8so?c?mq!$W_QzI(`|JP53^rF6_+{ITn8d z(*2u3uVXk&>~J}Y>J0=mZX>9$v2|)Uu1#l@*e!lqGkY=26iIIVX+l%v*4HklW-Eew zuaDlBN}=}px;qfINN#+xrx8CY*T`|(B6 zY2>lAnVYb4!L|)KZ_`HR*<%y;x0MaL60*M6w-i>%kg&vz9RvmogPQe^U&s_2e)hJE zlG7zOeaE7*$a|_8yoGQ1J$`Aq>ID0Z=FSA7N8{YkVa;C9%sT%R z)xb?rWA*iluB35C&5+8O z3|LlPe}B8V34Xp@wN{;g@r>}BSY{EL%23O_XJuRt={=nt4-N1I6tb>Q6=8p;E>6+Q ze{{QVxi}c1p7Dy#hsnp3qBF0~A_e#FZTA=-aOa5o^}D#DZ0kt#NB@2`G|L!x5bpb%BqJxv#^7C7B<(OW0!wbV$CbYipvQu zF-5k1_(_NZHSNjm&!v!XFFlvGt_@;Ad91SF`YN+AJl5uxYgYBH&*^6NcAL8SM$+TN z@V6z1;Y)&3XNSc-J?huCdSA#K+_~3RzAn|=pH>Kz z*I(%*i}Sh?kFw@Y-OhRT>?t)SWl6lnijsL-SrMVwrm00a_wLQf!SC*b+z1ZOc1r!M zl*5A#*{Kj$cpposz8+*88_DOaJ*mXBONl-BN>_dME`Hu$~W4HPUxT!94S3f5K&h1 ziPRJ8?D&{{(NwgHo{hcRzpznd@swN^|KJ-{r(L93+kH_EG#QWa%WA|sF{5^a$E(yn zH&}-&jU~qe%7k6Q?x7UsDa!~lg|abB5=B`pgsx#PN#!0Gd5eFJtQS)Jh$weZmy|n6 zjdm;>XW+ZPcBhlfe@(3B#PQ9`t7_9^*_)R-HN2*HU!3wTz3eX&q7k7!-7-rO#GPVy zN7{^9?||Ds2~<~%%h(urg@cL{yP`I2e=T`%R^0>hQozuMPY>+%FG{LA^Ze^MJI&KES)i z)I2R^4EIUgCT}vxP8WVKu|>`mQ{rv8d*nqK-SDIw1veeca!)uhWif6mMp5c{aC~`p zhM9qSjgwu)ktB#Vm2hj`T8ZWCq3WE{ph_Kv3-=ci5Z zn~~G%St6-P>eL%~b=ZQ_@ph5>KlBFXVp)H7i@=!jUkpjnzA~>otx0AdGa{IigH64t zoixQB%s(aYh1#6z_WuJrK*Yb;0UP!>Xr5wI0GDwDwL4VXwaYM(6wZ{@;FfTirR`}l z$F~&!z}^{MG25rWdX(&7{8Djgo7ldW3$<{kM-exK+B_rv@>8u;Cv_Uk#y)Jv(KZ{@wpg71zi(1g3-Sg ziAaO+%v`&5esREa(e(g0e-N0~xfJTtKM&(!8eSpL5m;zP^5yAen!)s-n2w)+zJAcQ zh)&MIi`3JTx7hOw^K;1vFVEP$rX76xM1r3K%2qqSO&+`k!Z-Wg)2ZXGVeck=y)W)9 z;bn1mtDKfk0OH=)1ylgGuM!M-8tou*$2&R@6?Ff-_^OXOgE=JnQ!T?`{1R(aGrxn$ zSpe|dsARmg!9NQwe-Aqr)=?|Jt|5m)uatWqEIPiVvMGA2&lHDN}vO6(6kr8PrP%-AF z5XUv>MC^20bAhW_}u{-%L$>W~DfUhK**-e=@S1#SJ~Tv8KgyJ6_4ytTpL$0 z(zzC9_!j-m$EbvFHR?a4a*eI@(G*6^2JLY<2bn0y`NYEP-nf#k#rU#G$ud~%pRif4 zN$=TdQ%#F`o7yv4t-hdi@m6OrE=G197mb-ApJcp0} zm6!gNR(rYwJt+^{&}C2fsPjSzwShFosbIP9KApuv9(i3W@n)e zDlGQyWI&1>E5Xw!(9bQxMf5jXWBV9q0Sf5iLH89$r|HNAyvL95!^N6T4SVn)j3G&x z4fiyJHTw}W)zn|s^F97+7UDzqYP)R z^=|g7Kdl3`5i{TMSfw zVI+=FCD>H`FzigIw(vD)_vAeN$UyWh#ZAL0!iZq2*(&HU%nYBGs4l9dw(dM}ssE6) zLoOD8jQ+KHKv>n7e#)suHMN`g2p$zJ0kMOoS6I>Wr13fc^g!-4Iv~Om z9@;X(HFPP?Q9tam*CVIK?{K+@Z>aTK|HbvRI}&vuzhR28t^u1D^z$wIMChz3fx>N2 z1rgap_{UgXye+_k(t$x7Mq*%YWl~EVh;kbaj(wuFPAD?+vHI~##f6nD2zZ5P$xC?740}nh)>&V)y)H^3%UvAR-s*;Q)fG}% z{5^XdKNRfp$UKO@iPa;+lsqT|k!&_KOLh3%^Z&Yxq{oHD8Zb+I#V@%k6sl$8lHB3# zKeqo4bl|heOVO76Npilh$V%1lvsfuLm(*Ox3nv{E+qYbPZNXNlfO36x!Y>CXwEyp? zH0?1&h33PgU*hPi(OKs*Akob4Z{ZM$Yz*^X=*Jv8>prDZEl6aNpzQN?TU+9ThXkkC z8$|m;?%48}|1ii2_!^Z)E$2fJkn}8%3t(;QzZt=uT)_XahP(lDH6PgYq11mZ8~LVq z8ZIp2%!^;UxqvY;rCo4YuH&q$-Z%*dS6{#Apt#TjtO5;xehkvjMga$(7WONYudZeZ z%1mE3Q>IXYItqKUQZ5hVWUD|SEw><><1g$hvoT;%F1Bc_uI?=;Ti~aKtChM_jKKI7 zk3s?O05U|5LCFPM;6LHm)R&H+6ok%P@4lq27?IgXo5OmK`?Ef&hjfI}#(c@n0j13U zTIiIRR4Q)SSasChY<+_=$xbyaQ6^{~l^}vt3awt^y7{A2B$G;F|0o60B4UEnE#mBE z#qML!_LHbLzun-K3mKuEn)s9&I#8Zwb&Msw7_eA&e=R)*0<+Jf6mI9p&E~$YlGdXB z67b)jo~?Ix`}{Vyf}HVD!dRg5pw@0=D69#Od+!;CcDYW<9|g7mN)&^y|Jk9&512a7 zg&69lnjWrvs;=*eUKCv~bC1#Rcg;nTf9|<_!aV<0R;8s$CCgl!PdkMg$LPR~gQ_F6oC?>}4-3H~Pg z|1ise66zkQZusg?k}M;cHKkd~9cFT^TYR%he0EIs!R%;XEEm3#;i2w8BqeLb3vUL% z1&kvkcIxT5p*>j@=VeD)b(_e0hL`k8qwG`;X7AcTxI3nXW8qGTl0fu}GDka0wC31L z9IOMY-Y#R7KPRCw5j7-g=?imVPT1U$m;s6nVeC1+JGppw>Z+m=Ad;9CCp*#lS?_^3 zpF-%gt4}7H=L-b``r+X{MXY^5%rEk=GeQ)-kv`$K7bU}z%br9Y6O))9mSj4rQ<@mS zG(1O?6mVyDDuUB$7!&6Kjh9kUjtJgFuyhAlHNq*i*8oN_G}j;9s$3_>H*x5`t%>on z(MB^2FD4;g$=W5&&=(_z6~dqzpKkkO>1p427&9+N%2XqMPi{B{nfuKm+e<%+1uk4x zWw)zWi`^)zes?kt#ys=hL$DJ&y(l`1)oUGHAR1q$0qux?hgCSj4FhaJYD3=%^H^yU zq1HJJj*mcR=nk8kLNM2^1a)TnN~hrI>TM`bz+BYSw_sW|!RTMZPkLRA!YOVxP+Njy z^4g68VF_spN1a&n_Taz?**lH(y7t8IWr=&;lWT4vp(_bWW4YC&x?k??$Nb zSR9~b353Tkx>4EGQy|A6g_A4uLX&$U9E~D&&)#aGcIssyFD~1K-E%|u;Nv>w0#}w) zysxCy+MS(?g#mnW1O7Qis|3tqarLEV*Zjb?m2}@6{v2B+u0nMHaXjq&JbMr9M91u# zhV?y174RjxL&#_qPwO>yEd;llxTg)XwDOaMvABVJ)?dBC%=8YJECy6BUP+Xbc%TY1 zE)r;-A7+l53XA%Vk^+^pPux^e0s&*LwgNA7@TOB!LCD#z7i6 zJwQH+1C(PMv4^(dQqbtT4mWb;-iE;6Tf)W)XQxa9w%C6iv*U!fTm%*1(5^(RIi;e8 z$gL-!Hlc2+hk8SbTR2KT zH-&ySjuyEd3%`8|41-e*%s1geyAAvSB@n)~gD<5*n7r0db=op3Ki0t-=L>)bZ~k|l z=^jO8Xp%IG&hyQb7vMpXmbKBC(IwG6c8G?t0f5KeU?8{y=RZU_vA7viTE?Iljt;i{ ze&>FQ>r6FD4^n|>668iMAhbbQvlarM+vw{3<6RWcmr`cSv`C``t89SJAAT-LB1x1PUz*4n&y zSNRv~>zFx6zdc)f!Vyc>wu%(9^}`td-eQI#B(UKezgaeWqO!Wj|q0hTT|X*WT8-Xoudqmh~L$j)DBjcjAQ+lgIK8ce{M; zAbR7)cK-y&=6a$2SW+A8C%e=qe8)=r2V$8v|88+Fy(RyRmlRebe-nui*eM^8R#Jth z(*()l38D|GD6x6@2=o+J#8lU5us864kj{01=XDQ%aacQeQ=3X&%p(Mz4AI~?xA`@9cMl@Kd7R8^4k97jSW7;UXn$Np)Sg{lGXxMB0Nl?!T z>T3TWImNDUdFt$)3HVVT{Q=dV>?t<|qAdSGoiJTcTmcDfMRKXrPh z9Ri3wrJs>uPBQHE)8u9M4m*mEA~A7~@n3rci1~$1l~g63>)GmB0Sr{zf&uLd_n!@qF7AA8v*+jp?~PvmJ(fCU)3OnD9B(Sq zCLdol0t=rwTctXXJ_Dan^4H`%(Zp(JIZb^w&h7C;Sd+MhjM3SU}mt zH=9kNMcAuN0x?gMR?sGy9LFodfV91C{-O7e6Lc)7W3fGLGD?7If6r`DsUb8@6B&;) z{02q^@XztiAmBjq3efh<%)-Y9E}jY=Q(3#?0>~hrJm&28ifud(vlM1rQNDu03lL+e z)PE9)6M>2bihsz7=e^ER+>-+bZ;a;54MnK@0^&ZW$b)y7kxn0t?WH(W4o*`X3`Y@J zR28*Hupyy6s_*WeCOkQH{~CVQ8;!e)Y{ujlFk|>zB&wEpQmK3k+TP+qr%zI_wbAe8e z!>!>z45z+0?E+`@`W>*U2XOcic?^D$qKnTS$Ii*XwCmnV& z!ht;ln&%BD2LlXcb66(E{>(FfGp*`@1$8A1aComPhqnld`Nxe;cc zP0_FszefDe#Z?-4Q36gALRLfp01uW9+hmOcWH!ox9G|r>cKST4NtmvD~!JX z#0I0b8opJTS8r4#lX?wO*1OW2)plwkX52%Xdm9me0t}DF#sWeq0K~GPYJaIN=G5sJx^TP#&VvYTMWx~mcrT?*7xc^7RleNXa~7G+{M zb~=4k1=$xxVzeDGG(gji`6*35lbSB1b!PTrkNJ&xOHqFN>zam^0eQaULbJ#yp6#f% zZPPLBFrI2#0!zKK^6;Hd2|#iFOOeUe2Zx^9sm%+O7+O^js^M_yF2XTuNQ5utd)-U} z?Y6dLBsh9n6*Zk^2u-FumKx0hVL;xj!xfCm=3?n#X!c;!eqTh-2?1cjvHUMVOu+_n z%-$v7j5N65vg-w1o__ZpB+VNXKN}OkWH>{Wx_e=u+~D=mai4}S4h`9r+#`tbj-cWAOic3Fa(93DU<3LK3;spAeO7<(03=a5cyl!mf*|r2g z^kBTf9%moUTur)osP&crxnY83vK>OWh-O3C{@{l1T}{mESDGs)^3Q0)1(Hoow?=;b zw@OWKtjLY>%~H>icP(fJddc$_#*dG+k97Kw%>1uT(kaWhMyP zs#DMF(TCN1PG%f^$pcyV2|gQ?OgUET{kG8gc8gtZL>12`e`%TkmcD>qyIKY672QN> zo@C9s@^5Dl#i4bDU)*6sG{aH`)ajq!)TWlKu_4_cMj(k_4xOmSbvjg@d^**#Xm9p`3eT z!Oelll~#d)DX>ky=8dDX`mPhm%1vBe*%$bS+gsw7G!I^wbr% zP+&h4azUL@V~jDC^1KwsWGwCr=HB)*g=GL#RD^|;hoHliPISvHf}Tcy^<-fF8aM8z zwuQA$FcCRR=~oy!ENi)rT2!eq_u=5jQvPG}2$+V65CoW4rBSRotZ9e@ya zaNdve2a^HdwAp=N4G0IMZJR5MnpkCCDe)w-G5fcz@KBB=8+FBkh>U0yEGVM3lN949 z(3Nj_kpp#tTp&gbQ$Q?;Vx)}K@xi~|SCO)&W-0J%xL$Z)(RP^fR>EIMAEubFhf@NgT?WK-M(ExGG>iFDLhF&FCW2R16C; zcYQwXZh1?4nIE3M=MsFBHXI;|(5u>&_D{ZVL<^&PO#t@aZ^%%dJ`5iIxH+GLPqQC> zQ&eOGqxX3Man2YGM^3JYYUd_SS?)Rm!c7b*@RpsxqqBnf#Q2M@Xh%8R5Z4K`hKKro z4CL-QH5v|;h|cGp%%xbENWGjV=DGLEX6{sn&~2+R8do!miJ-t3nulIk0_9Lg4`5TB zndA!kO2cBEXxX#VS$N-Nmu@0kBqsSP6mzHSW&GcLH4Q`?ORZ~<4x>A3K(pi7 zLAt+{yKa&8W3%4d!f*Zn@l%#Jq$fx|`7$Grkl+E{2(83yC3=4^x3|Wx>yezIocDj9 zbenxtX8GWAv=u9=aZu27UCkT`On}VX5ZRWq+zE3ZHcT6aB@=wo#+_Qu)*_c?dwYbs zY0`(A2-FEv0I!%-zo(E1O@bloXk6J3&%m78gX% zTQpoJDN4h-nhYQpE0Wpqc2U@+N=r%$Grjb6?Um)2_fiZ)ccMrr)yk(!oRG3Vfip z|NOv+YBaCaMkxA7#7aE)_qy75LbVC2Y6X~+=xEmPrvmLQ#3bgq+XT_xV1o?CqG>xWco!_Vwj&X+DngiICm z_36|_BOve(+Lyw)vf@PQy_Iv!lmiQw>jS}2$P}i17%-vQqs@3{u)%DI-PTe|g&j(& zMC?2N0N9=w_^eNJZO2Pl6@`Za*zxB3W>?P!giyt2l*X2_8aD<#A@Uxy=gT&WqvM32 znlaml`LOQ>{;-NNQ?x;OYxjKjoWbg0^L4Brl66E_njoYg;~5+cC*>}^6w5$A92tE1 zk`o$nhp%@JP?839Ep^~7H&o56%gTHXW>XMQaGIofc876FRn(({vjpv_)`Wc;WL@`9 zRhM2SoC87%7SrFz2e`B8tf`rUGFyY*e=Bgx6$vvAD9MS&rbp3M1VCNV7acMoZL-IS z6qv?X#LC(aGTq_fnk5M_7V$_x9K!j~y6gv(>KD&$y!~*ryFjkPuJ=~;6IJ_5fnBTe zKi8+`&lm3>aT}6n)6(sU6pxLA?|;f=ZFv)4ZuwoBXjE}rodbMxdcqf*T75+%3_%m* z%iDX#`;$n@(*bBdHo!|A`ky5Z%+U9sdK9eJZUCS0z});h*}rK0Wi)0O5|El+M zSRv#8BM)OA^NR?_07mEUgrL;3U}{Li6L=uKaAH>iFyra3CM_?3}DK4 zmg@!U>tI`GQ7p@k$~zc2D396~n^SQnsTunoO3)OO9PZ&E>a!L{uTbUX(;+?CY_0S@t#c{e703gE%n|q}Tf> z@X6#eU1outF`DU`UU2te`IE0Jy?CD7Vc@CJppH6Uv2o{~{ekZA)?@5S$}q3CEvhY{ zS~#`FKVM@=(-`aHHp-EPOK(?ZM=#FgL?-0@jNWwI7Y==D&xsCy31#@}SO7i68x+OL z$|$_IV{bd8Vj~XK1a=JQ>SPc)b_3SxX;KuYUO;{n+ke04_VC?atW`w&DDxJ}?T-)v zk*q8yMhsEb_AsL~&|Z`1PQbLA!RR1;w`kq*#9$zo-CTT|>cAp|EM<7T7@=Z*21%CQ z(TN5PHK5EQ)AgoHw#q{^T0J?H3zfdy=3#QaFBu%@B3>BDSxN|_gZ>HFb?ZRo7jxK=zgU8kZ!v!I58PY{%Ocy0{1U_>r=VCb^y<|{HVaLdcUPVMX%?7L18oqZV3&Y>X5!- zd^nP)WBLPt5X4hP3q*+OP_}~j3oVmlf`BVwJ{Qs0Y_YVx{jD4jFu{1#Um;0UdI&2e zJIS{S@;8IPLv!xdi;@-I{uJ^1i%Nx!c;+@5yE1IuLw2obkOGbJAy z{Y4Ii4>kph@>32x`fqzbF!RBpM){fEa8-4K3_K_$G0uRsjtiq=Es_+2IE1v zrl^|dcJG5)fTZIL1fmO(Gc*^Z0xc4RXN7CPIt>=`W(0BR?54X|LXvRx4N}b>Ez~Fv zXf@fSKnXDEyRUa+Pr6o@=#tF3+vMQi86j~aJVHzS zyH5v|IZCfCv>u+u3I|x!r9^Y6geGUW565e#DE0-BJ|fN6_57|PLY6yMk=*aQ3oE&DqALXz5-s}Y&WqyA0=gdo?W2}m?u-YyTU$=EnZx|?PloFeX8%u4$ycj zi3fJJ!;(TegdKsw=o+}@@k7jdSxuh+{%YkyaXib&MHuk%ft^~njlMC zkV4|a^`%S0)aPur3Asc@v)?|lEW^&d=l&e+EDNeKc7n8P7^i3% zwVvcnX^oJEs^dHR zh~nrcWi|)1kq%mGpAWr(vs7hqq%4lwM+DCP08;Vaf+uh)v3V~if3BWfHte7(^K^It z7j!BiPq@?WzYWAt`76eWjTWT?OZ1ZqZ5=N>;HGNsRPQ*Xd}k z2{+T0A?P2Usm4@SV+kH{@<^UgyR-35EggAj3Zkjq8&zU!4a}UeUdT*OVm!p7wB$7G zoeUdBU})6@*Bd-~m<-v6D^HhOR%NgTZk`4=4$`4g^{OlEy$`m!NMlz~;{a3jce13h zL;*g}=_-2l8D2v+;5b3N+O^PW-_ius_&7HlkTCK+1LQx1ESjW>08U9HVg|IGGm4JV zy&Iu}3#Fo5&#`5Nk{_@xJF@eD|D8ci%_Ru}g|nzh5)kKHloLx*Q#G8tdaVQ*REoSp zbMXoyb-z0jsH8_+l}KQ5T$(vt+eGMel0GXt8@C~t;fFG>O5@r}M&1=n+{R$$*ODm( zAtIZv#Mf%-EP`Fff#PR{(iU%nsDfXQ^*T_x1j}|!fEE&RsBElw@r;wJ;I-V*r9ci) zh|--__Mp^7&+ir*q^glzqmP96J}@6&Rr%9BxMaILk>m}fLlkxA?2HmtG_a|zlaVz1 zc%y+)MSY)rUdLWh7y1HSviEsQNzxl{{ht4IbnqsA*JZHt3JlVsCYS>zwP(b@?SRxE z_I?*s>)ykLQQG(A$Nv0rgMhx?OWK2WV*~@;;NVWSGS$$|*Q(85WTx1j#g{Ox@q&+h z80;_|Ewkj#F-BGKlA_Vf0dj^R%mJsZf0>iQPmQD zSvf7mGt@{XaLHr?9OVc6+*Udswn$XX=;A?j+D-U4<4V{<5DMmOPgFG7#* zEQEqXLoKNjP)1bkcD)cBo1sFNXv%~x9dCwbueTt1=v_rR=hAGp1H^5rQece6oEN(GJJd@iW0H)yYVszLosF3}CVjO}OvVl_;l|6D zlX07>0YGq*D(EN0Ag9s>i?AupPb^yAHODHBr>+9}j!pA-XW+|(X~qTQgyU`kY&(-M zK8Y;HrGBbdSta)WR+>t1zlb1>QC2Rc_s@ zF1#l?jHQk6Re=m{jo8v8UM^Os9-Nqn)4q^aaOKQNDifHQy~&?bg$KS=r%cwCeUBu0 zXR=~UYQb!`-030XC&yF&=h5n5s8$GEDGCG(+Inz|Jyk!?p6Yaqyzuclh9c!ur*Oi} zxSvj+NT|Sq4Reb;{2=tcdESmZCWYQ~(c{&RIdMjey=W*cHVtOM3zj|+E<_jA{ta-1 zmLN1QzVP*%v|6c9YTDar>hGzl2Eb^fVH->M3s#ZHZ#fm>%)cu(mJEdZJxdAW!b=5S z`Y?6HRHeN|9u#uc{os##Mw<}_Cj;Rv%nAWXVZ>p024AWHTWHrQw4T$i$3^fXuPDuy zBVn?%A(mZ{K5?}{@hS9MMRyheojEETIBhnUm`sHH_3>GHj3N8Hn+%O$w#4I0GfxCe zC(@wdaSLrgjk>cDn+KPI0Y|DT)XW0YhK9A*UA)i_mt5tn##6I731}|N^FzAr6_CE2 z>!kZiAkPrFN13pRCb_*!_NBcqtr~Uc|Hf--F~025#5tZj1wSOZ@l6a21z=zz3>yn< zfYs=af$o4oN@+*NOzZY5k$j&bbbCXUR#m!%BeTQqYRpM2Y=&)MU4#rgh+$YA`~WP3 zNlle?zyktV!0CkQ&OeKGzZt3%8;zf`>$3uf?*4Pz#2F{A6^-;*mqWQlGG8Pu2>$Hy z@iduwW<)*I_kz#LZ&RNNba|UaTL+Rg#`MvUD`M=Edj*hnx3<}AFx{IfGO@a=8f+`r z`#Fw)m~7Cq^LFCqUhdE-*H@3j6U#-AKB82J)lk!Q?JcHI5o@rv@EyrL9V*&hLqzoN zKF6uxZ9F)?gmSOyU=;%tcek?@OuWBUh9q;BBAr>FId(YFA0@D4^AKn9d=c`_zOP;` z#lZpkfcb~~T>WNH0m1;1gb&>O5T$NK_5WCSMP5+8AIH{c;sbe&nG zp6V4Mu)jRiS??!c_rF~oHkzgTQ;@tVpF>1zL+KIJJyW`CmbI2CqbdsWwG3TiH{jNyzs>nrf1>?VYN3#& zVV+;;HQqK;3u09$po_YHz5Gi4#lbxyQamDus6Y0G!EezJLR7hCD zkvH^VI+lUlf&%}^_xGQlDABRwD?Nqp6@ojO7w&)4rF=mr$xP{bFrURVugDyVe5Ul= zrrT)2p%buFNhL$T)RWe5Q$AnSLT-4t6$fgO=Q~EZqJ^6B<_&LMf)oLO9ROTqe@zTx$Lr^dkO+3&X_I}W$hUfLd z2F1jv;?u{^y{n(&Ld4Bw`qRzdRm9G2==_!s;*!eVH+;!}N>u6nJWGMN*&6YYU7hbf z(Rkt>4hdr2#<|`py0BtNQ?`wtzfE_f(F^b~F6D797^J7mrZ6NCjTRwsY8l=O}5}FL&zd9gxxNa9GwV-&R#U+Oz^F{z{U)qNiTrv>z?L)LzDb3rh?52K6%vI6AbpJD3hMstznI&dAFmI;_YzNOPKOEb zt}0DTzp4lBAQ#2zd6mm_tDKY zbl>`20II5jZJYRMQJku($Sk60S3F-3qI>SimyKLO2n{gRD_@P>+$^Y4Zt7uo%5}q5 zZWmDw0Ja#Q<()}RAb1{MKJ3FvLG%8JWUNe0sB=#-#NuLUD?s1x?eJnw!)46N@4+Zx zajd0@QhPF4!WJ517_ivnD3bq0!6a6OW+Qt4_cJiu(S5II5KG=ZN^rh08aF8J;JRgt zed-6!@=-m@vNPE8q@c}HcKJqIg87{eDO=BW)LcjLm;zcB81i9lK4gEs6Bxop(uWuS z@c|26Aq{hy>w?6Zv*a;ESfc%Q_P%d*%)8^Fsdx`d9Y-xPEJa?;j}zjWoubZjR3N}a z946ika~xM&njF<-l^ zLpvzefq^FF#Akd;Lc|(b1TDBG{7%RG5nrx2t!lY>*20c$UWJ@M?Os<-+eI zOjow`?&WDKbDn0Aozx^)OLA!TVzdn7y&nrgZ24|#WMpZjZRa?jvSl@E*&u}EUyJ=% zt6$+v_t*93uIRyN{tU6=P|k(IkcB7g^{Wvn5mcw3e|mm$G2Tvq+-+e}+Ds(X5Q{KDP_fQexOQn(uks%ZDC4oskl{c#08MmPC##(&J4h?7Ht91dUc! z5p=-JA3b`lc}ZELap3idiI2}7V|S5}@eCZycL3KYpJ=?coijtSN^(9|CeQ$r$xO*p zQrY4$#eep;!Vpnsu46TH%+v+52qQH&j`6!4R{vt66MF%5ZL^Y5+-?YVB~rhd>WL4Q z%z4yu&t-W|K%=f_41$FP{X>KoBzdW)eIgxf|UH*%j2c2)PvHdiDT{1GRrM5M4- zK}M9vJDj8BiP_tGWNCz-$O&)v@K_L5pC<5h40g+%MLp+~RHK9lwVeOkx?*034G~?I z2G;EKKAmR0#ANLQ;H^JSwC@((?$!V&Vsr}NXmU(#VikvK@Fkx!9g;hvr162@sO_(% zjTsM`U9~zCYd+!iKX(V*=a&e)Lg>^oR_6~^R9bCBa#EKzyAW%QE zi=U)Lo(EteET*x-(#yu!>6B*s5Ob0xelbGyN_DJwL(9O)u&=Ztk5M)cTDZGJ0}0Ui z1juuap>`+Ua`ZZRV}&vatrFzdkB%e*Pu@AKf#_rj7uT8QVz*NupSe1@v4Q$-Gv`Xm z*Qfe=zY7YPJjcE7$B^1$FvgUWYwo?b4TiS&rx_89a>^9vqO#b zohC0zCzc``Ovu@DOELiwds&6rP?8r#)F027_AF_-Ln7QZG5a3qR3r~1OwGRA*duA; zm-S|{W^D41&=nM#M`f3=@;)^Q(mes3v;FfjMotl{h@J#(@Zp_E0VKnR-&nS7ZBMxy z6Yc|BbvY<8kZ?&5affy=tcbAoY_D7N^XDaXjHC3Y*pzt4cfm+(V)iVxL0R_Gt{YYD z-_coPb^~S8(9O16j~aN0cn1_e!_*vU*cBzpb`>Oj?P)5t1kyXbda|wrQH3iTus?0Q zpvM_Nt94OJs9M*x$Ef^D c|E;Ug*1wli6A1)SMFR1CxZ3d@W?FTvJe!~GRm*l~T zEVQw;e+uHCf;R4(cD$W8-(G>0n=8avAZpUbwu0uOQgceLH(K^<#4A%y%0w5R9P3T; z(XchD!~S&jZZEli>BYPNdwH;4b((#%C}FUb(q_ua`KQ^dcZyo`WVl%#(y56)uG%7ab_H z;*TvNnP&ZJsOGmB80@`N!pyg{YY^SF<2$!^zh-5EYQ_yF=IG&;89nT z2+Ii9_Bc1BM$z0;Z)`uxp__cBMAQf~()cpcPhfQqN%3$}Ru)@6G!EpH!>QC9o}>`Y z!D(AM$4UjvFX0T&=}{&{0|sNHvIgLeqrdfh8Q=amD43xm7HPzvAmlfcW&B{sXTuM7R7OWyob{%qO%BffSxntKD(- z+0Q8i&8~0OLACuI55IB3V3@hUZi*~@>@lV48nNWUHp}qzKOF-B&8*O!E~CU$Np+B{ zejdY+t5vWx4c3{pK-%3fS78QRI z9Jio;W|!KaJjm$WVWeb>3PX?#c-fYUuon+97ZHMKoqVbNo8#*ZL>`<8DG zuu3cK6{q{3@-W2C0!@RsT@YZnyal4v@vcTzxvXe;L6Giw+B%VX_S@s?kw|w+qpO^m zNgv70=Pu*tcx?w8#t2B*ApaSPa~;N^)Ri;$MXTxsKHuJGvbOJWw9yGmLl!j}w##^9 z%AT6zhO&-(Xo;s>(*_}kl-{ASI_S6hSjETz`c~u)YwKNS^kdXS;^#vC30U9R9k&#b ztcXeWd;^jZv}R~*lqw>xrm-n1uHC3*lmLPAjD@Mpufz+|kl3TjG|1%0aakI7+0_4y;}2L}MGcf!1jpnZ?`P7{P5QeKt~p zsu~aho$-4KX;!f@qf|Ur`GSlFS~4xbe14H_b9;P63oI&6JnCyJgm$ZqOk8B6m!DQ3 z1^L1t^U!L4eG>d2QeFR&uTFoDFVJ%aBMHtCz#B+?5m5#X1(nJ|afhR$!6*2!B$7Cl z_K!PobQzlnvq|Y!)XrPotCc3{a3Sv&-8PBkp0C9y4AW<1y!#jz6&|Ozay|VJT%y6h zVtFg4xgT@p5!k$RY(Ch2HqiiJ1y+f9sa#;*yB0ip`T~3t9iUx`KR9~b?P*0CEiIJ z2bCE|hDLj6FmUXg1-8imXb?-pf|O8t-6+Z5-K< zDV6d}meUvLmNF%bWjMSuSVZTz z_x;l}?yKgR@`Q$)XGI7HX0B>gqI5>u0)l6gU}Rk%tmihi%`qr=lg(7=Lc6rH6><_W zg%xNzF*Vl74L_huHUrxIde+Vi^%NssW(YBV=owzI*R2gYFwv2m?Zt#J1tD&js;uYM-LfV zVwBcyMcA1`c%ZT0Xo^;-`z}&W`XTIM6!nnXi~^_sDI&N)hgjN9{j2MuK+gPFMmIkM zPBwN#Jp5F+Z%bxsN_dYmh6m(4wGW0aA$~;87@RI=m;mmnHP^LsP8w-t`}*YSrTrGD${TR%i#?1Fga}7LNhUiqZ^gvSM?Y zwRG`IF1(KIz*Sa2t|an)AG)2y(P`7VA%peAzj&5(q1cQyx}TsAwQ90*Qu+dMyLn-~ zsqP|t#jI;mXRE~0jV2r`uMDKlwGo+3B57#g#y*5S>#fOKwY0hhn+md2iSn>tL9~k@ zF)5T%9;d{@m$`J6qcHmdcL7f_12m6OEf8Vu#V?6MJihH_rg{*@27a&=@Zqvjdj>U^AoNJ|p^ z>*H zd4TYBXr8MAxB$g74eGIx4;NRKBaJpqiIhUgVQ%)HH}0iNJq8HwntXGqSk23LsXbf~ z4qDl;d&EA2+~N`GZHkK|C>?%98wFZxmmDP(gj_$BMAc6`OH#25YO}6R8xqeJc-PA^ zLpg}_UM4B$lL#3Uh>ui}6Sh~;ht!?-?3*HMk$IhLGDk{zReh|7m|2&lalF49@Nc_; zj>7MJV=sU=w#BYlURPcpI^}C?UfYh+hxe3w5e`eHpGn4O$5LM?hckpyU&vp9g%IeH z&J%0_C|+5QyQ!Sqh0}AOTEANafSHiU7DNpR0nH@mS?5CF-2syyo*y>b%}Lwpsbg`u zEX~RqWZ{**;bbnySruX7`9%*ZI)(Ur2Ch?t(&z4rzj|_`SMkCUK%A4|1cBbhsIE_3 zF_Xs;9f@#-)o-g=sT7(2=w(1ZB7q-#`Cq2u@|+38m_>tf^b|Uw$ieDXT zvJ;+!^}KGaW?UOx60qS&l!KrqRMP!Cje)E&nia;_)dw3PKLkKJV1QpALO$0kdS7vq zw4LyaUh&2m3aLY^vcYo=L~4>E(Aq#0eTdOs5Xq!X*x-G18!O9DB)w2d49q+xA!1C4F#!39={KfJ~?8HT4)R5MmgHO16~3Lv&b>yL(+3%XuUI)bm0e4Y8|m@( zsk8j%;Akwn`q`VoY4ci-XVsh$9s(dB{!7V=Vi%hFM}MM=!8-zYIRDP!R6su`T%Fxk zI7sR_zMytPg70)t-`Y&dM@D|d|ITLL>sxL`cNwe!A0VNv0bhqcI?#g?7gIp~CYeI| zRH%Y^r$o@6S!8$Ya1PD6vBKgxlef{;XP>ZJ*-(oY?7V|yHL62DOpI28cA|1H=jfk^ zHI9uDF^;uybuq{&6;S3108MpKd@~f5|LF6ev7GCjibc<2g6q!erMVD;RC)N%XM!E- z&W6v!l%-r*jNV!_tyIWHYhCsWDlw$qWD-N9&#w&7l% z>b{tW>!^43X=JOJ^LhyXjHVYGE^f@&GcfO3h6hQd69~N4h<+L193!da3a77%>487k znWh12>=X!)v33?Z%QOp-Ch6?uyw=?Csr~Zl%%PosG7SnUlK;dw_?|I%N54NOap8J1 zNRjA{8fMR-VZvfCd}%cyXPc)Sat7Ealx}VCB89YUiRdmm#oXiL42rrOSBCFZY9v`+ zZb!JS#Ss6#Et3iU7XubeN}3folsFhgr_baT(@EOJu=`BGR?$4 z;^?&B!b5rs7jmHv)@C)2^da%%MibY~$9uG!IUX}S7!`Wzcg0st`8A5cwRl~_KGprT zQ0_z|qE)uoJzaGwCO7AWv;S~inT?scoe7unXXT@Y1|hTqn`3q#_zBofBFjk6d2-1= zgkHEghbNLAS>M9u(!^h_Zk(j-)qVCWo0C?}qs97yIYud0LkQyGK7c!p2<6581sAX2 z@V8quGgI@*GG9$zTJe;bx75HpltKJE`suNdNz>l_9kfV|@<| z31d-YX|$EoCGb0K#NCX54Lj0H;AhLteJ;IWOAIm}{n9b*sH&Lsg(18M6fe8K0lFk! zT=R161?=*Xg3q^9h=PfCRW&Pc9HO zvarTLm!)bXT5Ffbz$8$OWg#Wbxf%RG2+#c-#4ywbaIA_vKm5b%-9uJN_E3_Y&YbEM z-F#j^^?pHc-N#}fS|G@A5SP^w`Z1RKI2UGfGJ2Eng1PY|#bgVqBuYoD`|(xRvzlaM z3oa9$8tx&`a9j)}=QtzRFKQrJ?{Kn?v=#1eaL{!bokFJW<{$fs>&QZri%Z}>A#0!=uR&A|L~8u|90 zQ~dYhOC{Z>O&(kq!=OPOXGQxBdCnqnfz*0nJDKajRmI53*v~Dv=TVQV#lVuH;0sHwvbhaV)!d<_S zEA_EX;?^WrL3+#Gww8!N96AOLD z%ax83|^`LUa8 z8?P>f<~~fK)Ky2hW@dY%vek-?hz|Qst@Jt4);aIs?ho^nN2f9*ny`WhX8=Fum3D** zT(@+=WL|u_3odUa!yqn|!SIY#N<}8-^Hq4g)Y}KW|6x(yf7@1bYn-I8a;MOfO&vOt zc;0tq=m$ZP!MkaBAVaGmE^XgK>vKsGA5(P!?auTC1uMrYWhv;-TkyeK*r=?#JJ8S8`iK;}0frRmB5f^hW`sX|kAgTaZfmVM*4++p7c&M;Z2xzL(y5mB*FY zhTc4l6^=z|C)6jX$Yq9u2KO_F zJHRZnJ0qiK6-fyKyAcTEH=3Jgj$^}%{~@NnJEm8`Rw@G9Bv49EU`Yedx>X!x{tQ^O zu!)h?yu5|xmNJPSph(efrvrwH@?XPRSBj%bVUQTI4abzZK0u2dRM1T4D%FLjlLru3 z#EKXSNic_#4$sGxpV2>?2IKip7FYzd@bL3Gt4cNT>?0KnB)X8?(f&uuvXwJ1MY{vDe-zW)mO9=ra4*+|!Wko_`75Gq#PbhN(Ix*!9R*!2-p4xHlXu5@gJzaEO+F*zD zS~#u6KeZJCSsc=nW>jVI=bP{_EuOl?hV=Hwl5-L}C?Oj?guohoHH*|WIW?wH*%^zH zqw0))B?TWHk4?JYAdHRTtld5F1V496k2!q-w{c5*;cwI^8dsK0;)M2O5W5e&;2G_b zo?sPt(J;VMOO(n>T11Pf+Aj!jl;l+5C~n;}R#dRmhX8UOMi4qDUBP}Epx9s}hHYepo|M@k4ei=9>O9|cInU!MxToX zOHU~)vy=h~;UMLa6>6ajah7)hfcH@guT+~ndy&$;uM?#*7ktXlBGu)CL?m3yBr(l_ zPL|DJpL*vmi5AsnYpgL5e0Ij(zD89b-<>QorGR#^$sB|iO%>*C&h6^Q=Klc@U?%rt zUy+G^!F+aSdw%*Tpr?WxD1vHFcwtDt6AN(+t?t+O%nx^TeJhFy*hirJML;C;&f9^Z zP@W3VSog2-2@6nj z1Tw3cZt?I7V1P9xMTqHw2I0Gf5kUA3y%~Dlc=^IcXmBFqDZVpMzM5omTV?ib)AIQ*%z8d z>DN8p{eJY=e)x|ZwfpJB%DPft7w&a^9Z(jZ79IeL!7rggEuK5&R4i!ThO$XH6IA>d;~rvYc4~hx=5H zr=^9ditPR=z;ni+zh;`n`0k|32}E@MGWA00@TTl^>J(foq=Dxej6mUlS#hEX$mZyfm570q^kH)w+2 ztHayA>no@JP;R7?{%)2EfC14tQGfL zfx+KizKBWV(TE(&&L9C2U{?$FGFPuz@5$%CV)M4;kZN{kp(LnTfth3W5nejGRD74Vs4((GjMRA;5 z5hpA!5T09#Tg4wX$tt?Xr7_o^D+&qAd{3g>#bgcU{;-`p@TVD!gduC59JPC9chH5j zB9m@}DVt!BH=T@>m6bd3Emm7oU@hf;fN@r*Zf15LstvmP4$mNHbSs$?;ixmo_Po>d zMganaC-fkfqq@9DFi7oS=E}czj4WzHGX0PQmBK>H%EU9_(<73h-U&F)0F$%rf{y#n zOqvjG&Pq20bvIbUj#p5ieSj@d>Ilsn(t(8;!RXF07|&EUmUlg5`@*T)xHkiXG(070 zA~X6YaK{QK5+1YAS#P7obCpaV@jSD_qQ*rRQ>gp^|93zr(o>L<>4t2jK+e2*Z;ul1 z8#o`cB=B_?Af5x9D^XXIM9y@{66eb=UK^G2O)gQ5Qq>{j8#Cwf7-6DQ+jFXFZ29!> zJwT%XfP(GjX3^H^lh~5_-}#(+`zyz%b7w2(2J6`MetEiwgmdC~FV8A!Z zVO5r_w9qM<8b6-(^*!yyd@P-3_)UUtDw_OX+ybyYr5p%dN~+K}`@Fk45-a}Imbd($UXuc^sQ9^Y7s5^XGpF^F`Ef} z+1;;P)j&}yp%1fe!j%5raIb9YUwu4sg@z;`3VP>hGG=`=6JTP;Xfob3FgD1Jw-aXZ z&R=>u{$kd0wi|#$iarw+f?NpXngg0dKh!G_BwJf%=EBASmyE8g&ijuVE& zN}Dw&lM55b@0N6zg$cl*GXBHkk}l{}y}~2wO9J&;3k_IMMdtz37XaH0)GnajIP|d| z(D0*cAq>5)gnmLcPcBBTBayiVtcHIn%KPcw+mQZmyxTlTJ#GeQNxMUhoy1>7%XcW? zHPN&svPEsQiBl#sn1e-~^{x4*S+;JdC8h7~_G;B^V4CW9p5&q_3vjb;I{gR7e;WtK z${V-{;mMS;VtfRarrKpF{rPYrw;|J}I1e6(esk;unTsQl6Xs8Jfy^J>uUN!@08Jgf zgnj;n=XW4HWljz*UBTJQ_q)iAzZR$-WAzYTrJQ57n(LUTu~~v(x@v4RK zyTA;QjT#S+pZ;PiHLlEz3F9f2(Y}8r)&uZNQ>|N8W@wtD#0PQSNrJognk$yiQ1$@# z3n$(6_QlA(DxwA~LO-DR%pGLUytKq)-fPpeVc)%TP&C6JMFw-5@cX7K?21*vw2%uLp;1JFAtep=wZ{d^NUZ-Qx!3vqE1@!W<-KUbM9A_|l*{y7%r`p~ucw1{D(sKdCoQm>G~;2C%XD{%w^ zFJrzy^@2MaYu;@hhKGW~F_$3S-OgcTnfAWF>^D@4k}2B7drif!xK2w-D>X3n8J;rO zF2Nc8(P6Nv1y~i?4o=EW5QFCCSLlrsv~Pu3@`K1Xs-oq{cLstXU4&R?o6Ma28z?WV z$d-{NMnWrSSFm{=v73@C>t_JeCVk39msRR2AaHyj6gWUVPxU$<3genc%(8v%TS$-% z5_j0sw%2B!NV}53d`^%})s~s+hAp{TPzAzkrwl_xA_=*`R!3jouWOOw*F|?1dU0(h zlj6n@FUUJ}coD7#=DK9m2KxCObe>Ob0{lRLnl988G8O2T3e;t4htpR0W=}&srLPahcJPj3Xw5{pIq7rvBLm-vGw^4HKc%ZI4 zuC&zJSc77z#sNJP83zD7f);*?k$9nH3tKusa^>*Uf&}CN@q~w#CXr@$_gU7$$|*Z& zDkqs_hQgM=5j?02_lCH^KouH<R~A z!mBxu?07$=6zf1Q0m|#GbA`O&k*as8YyxI#Wn*kmVuOS47EdAlD2`HQTW^oPjTgDq znfE!-yrM(b3V`ZD_&8IQ2XD80!4`gV*%ASoVu1LWO;C7q>3&qj- zgOG-#>s(}I_?S4w&hKx-h_)|^Kvhyl26Yxjoc}y%m&5xI5qr7>%&of5@UFV%S)BDJ z>)l+2C84&s9F&-)d4f*g2|q82P8(XQ)aD_x0vS1}E)K4SFvp+(?Q-04cS3elXtIr6 z!(4{=v217GBtU8_9lQ-CeV!b>7=_w;hFeeEoY^@d*UDhif-p}&Tnvr1jOCfH8fd;GXXPa;ZDM=<|HJxgGdMrbLE_vlJ^7-=e~e^|gp{jJlFAQ&>I==1}y7G1ap(%@ZA;taB&#>c(c$GLc|4^e8k#YIKYRDugusgr&TdTG7_3&B^{RbNikZ>cL9gii?`DY5?ftGQg}`8Sza?rX;bWWKVmPhSvUOrbzrXb2)|ct)>zJ!^+=||+ zJ8Au4Z@c^`!2dTc>oHkZ`_m5X0cKERQ=-u%jL40E11cU7I=O80Us$5nSZjr0(dXQd z2Q+TE3k}QFR6CPqe=DlW5;gwS~sT3UhS!rH7sdc9{4z6K@j%oZkF!mUw9Og64F=Y^jJp9 z$aPu0(ByD6rAqx&;*oX^=Ht6DWlI>SwECufdZ|Y}D=ucNTRvWlCk!(L15RJfYn-YR zgE;9p&jWB;4;c0AWb+K@v8e}e_udRO_2SL#=1r_zO+Evbkb6u%7(&3OBNC2O!J#jL z6XqXuu6s(PyWGHN4}-kg&Z6hO7|n|{1*1!E@KX{(FFXl{x8pV`;i9%+1-WK`>Fhu% zRd`<Uc2#(j=$WB#ANGp5>p{5)xSe=cq2VK-1Jf3~ z79{P(5*7-IBM~CP{z;uZ5IsxltIHvsov~zxGD&uhf4L_Bh)W8 zaJ3!oM^S7wDy=ni8<@2-ENx8qIR}z#$7K*?%~PYx%;d60v$sS6l0*_CB|ZS->tE$| zNKQ(BHt-8xz?Tik&(*lV5skSXF%N_`F5p7u0-dDWqIUhEmEcL{@zSm*YY_!Uu&QAJ z)aK2deluO{B9>XV#ZZH!W>&{TruSX4MZlJzTe$76DYJdO0p7sp%;{A!GQZse8?a9Q zQy)vl>=vC{cyz>dQHmU{Yt5W@N59cHKAym>7Pl2^+^y*oyhy>XY0kvVn{)Zqe5>&B zo9f038An3FpaNtU&WKMIrtRDQVbj*Y5il0gMYDcV(3E%Z4!;(_N-A8eRadb=wxei_ z3T73w_1T)KX!5)U#eC5iRhli7E(A+`Jh9^gdZ**%V@Z5J3dOzC4+Q<0_vQsPW)}s8 zJD8FYCgLGd8&n9$@J@9iKj^kKqykcK!p>R%;^LBwm!};57j8oZcCdjv(1;d>sTWuv9y&D9_|3%Bq*jo6{4EUo#O;u!(f*bEQBj* zoGQNvy2Lm(s)-RYV*#Q>Ur_K{5f#XQ$)@LBaHupwmnvYHAf{lzaE&iNiWGo~z6G;T z7Oyh2H9j3NLfug71cFS1J&(2?!l}|Qx-;9CZ7r8sGr;(zS;a)0@dm{5F+Tse5&%tX zEuqJQ>Q$2tiFUtMDw$$btt{y9`EVGeDDq!&@r*Q0bt+^@ub9IftugbEBRTc8^f!oS5?%c6lKA<*-u*PhZ!b3`XqI2hq4AM`IDa_Y zn3f<$P$1GE&Uw{=V3)G6>sWO>negEK{E)@bJ!l90p+D=yO7m57JiCoW?WF@0+*pqsV%fj*q*qw+@k7+EZ% z3nCp|N2ZJhoT1DhXT9)Sl%K{BjK~#I;~Ale{h6K#)`O9Fchb1klkVpx6L3V(;MZ7!^mPf_1qbzTpA zQAvmodr75yK~5?U&<}X)Li`7ci%vfBLd78gX5vuxJt!W(+;M-!Zo#V>GfCZ|xl+E9 zmzR3*BB;dy#&&PEED3;OTZ9FFc_;*Dq7VGL7vhEEpz}mWmS}*ozq(^nIBYx3Jfsjv zfY?b|@LV_o0$cKTr2Q8C6Ud93&Ebu3wml?e+8RP{kYt*h+Ehfq;MeN&!fZy&8Ya{o(LX&znZv!N>oMNEu?F(k8CFUB`6VVnFE0BFIq}sCiGgSEs1SbO& z(%0g_sBvzHU{1owp#3kAWa~uErhUEwSfhyVS@CVH7C{yc+BJWHXU{ zkwImSOboJl!vSdg*1J&52c`BbUJ%x!Vi@eA@@uWl0s(cqHYZjORRiEx;d1L{03rXH zyultUljcp6C=h*TZ1JS#I;JqlP#ueIdv=%b*Kn*D~=D@C}}#=>E)S?EKdLgI;_qvqJPO zn!X^>fnw=d87SYE5LEZxU{Pw$G6Qv7B_)EK2lp+g8=uoMMkODy#k(jJKJBQ3AoQGd z^yb7Z1&A^INXl$~tF(8M9f!kCxUIB3H+s@{|H8|h$G-vsaLJ!{ihZY=5YY~|>|ySA zB>}?sMOWut2yWBm&Z}GUO(oi%taWYYO|;dea;$}N@w9bd`_*9 z&nl0&ww9`z!*k|w+Yy`D+5Wmp@OPvYwaVeN76wM&#YqQdv-L3J`$VjOIw9FxB2+rA zzP<37jkPNG$@0_t2YlCcFe=S}s48l?N8+Kdc4`lwN>)DJvxyQVV;Y_6WC+E0r&G@O zvgMaL>(P?oP2lyDIdiRN$qs84N&u>~=BA}*m5>BpO~Zd{p-`|pat*WWni!I03@s0o z)(@4sOXkA|A`L*)4VOf^RE+qSQXi+X=o<>v-v1jjU}`96Ho00pLxh^KJw4kSqQwp^ zwOXY%=f8f#cC8+@Ny62lX_rMqKI_fjPph-&NvfQjSRTk6dFd7%{#2}07!Y%p+`dI) z`$$2Ev3S^ZgHAn5 z$j8fcoTA6Oj6@CCvjKeHdG1Hck#EEO5BvCQn*gu&X@aF#R3d*%?xzFWwqFwA1Vb0> z)ZIBK`lAV66t8Rk3}pcmbv@^8+1ecw!B#*}m1U2uQ9ly}FN4j>i*=$oVcyp^`5i-B z#G1+csPuM_k?2xegy+eQeT2HPG7`=Po|uCle=*nailWM{vrti!`!7QZ?goYIxbbtb zWj6(mX!m;m=NAZG8FfARUezV`JDItbLV7ok4c;PyiSTzHB0|TtaLfJhsfUgq0h%VJ zj6t~)*795B{oHiDp~&|;jNu(Zvmjm_9SHe7Qa@q2Zu(c??7jGFL+6TCB31~cxWY#lL|}Wk~5qWaMa&)G>;*JL9qW}! z0SW_R05Y@S(Kfd0-b-IKc?U`jp^V;Z(#mmUbN8Gbm0aApPXI24J%M`#rJe($V$ULY z3;qc{Vv`weM}3k?3$DvIOq8 zj4!ZV3-ga!+Kbvb{^n+tKmJLHze6^6$8GA8Tydr;P_QrUiJvUiYx=%opJK=3F4XcY zoR~K_UV&_$%>NJi`sm#*Ewz$FUN7O$Y{R(`m2gV|put|~9Y7YFZYdiRx!O6sKtkdM zHCHdF^``(}2PPqF<|CpiaO;K3sdF)6_pp%HCc)F!%oTEmrVmOa6kW}}t$pwXISdfK z5t=riU_r)wt5k}t#Ol36>ls>&1<`|8lDNioRxDV!E#X463(1#xxMI*1(OnH!gXFq% zq9?dkWGJuFSmWjr0d8vhfmh8k!a^$IQA$ksX%4{VpY%pcV9Y@Sq!jQKwdFbeY3|M= zI#6cY^yD!k=?0VCIJ_;n@?<$L8>w*&X!o#Nbma)fUB0;YKn}F#b_^7coh6lQ1$bzR zrhp`h3u@Q=>^8br-ARHxU!C+DIL)|^EOwRoYUSr|z5Z! z0Y6Q&29EitdA9Lqi~kE>lW=xau6qqiy!YG@WV33~X+;}X{I&juvew>$BZg}sc#AHU z_ymi(6|OUpCy3+0=lH{>wsY)+l_Eu0u~3=biZ?-@xF^=wst*pVoY@nlv9(1n12SBTtU_Da8bKZ>`I2(M$H7n~B6`|YT)2Z$+YFc_cG3W1|E$*$ z?$7((Wzu!9B~Erfq8hI5!C4y&LU2L`0Aw-X&N`7^omPXZr*py;DZ2R`$VHj>Zr)^6Y zvm}`mykyWps?8?TqfzT69kPA#^YidJ;I*kF!+1*Xn>3U73~>-!@aG6kUv$41i%5;v zBZ2LrDXH6$_F;U=9^j`To%{qkhr9WtJG;b*p?}maTRBU4nvbz7F_VwST z?b_c~avsG$t6lu_fPw7=CPDv)v#@VrrP>DoUi|wK!ZBrxR?%?0EzoI z%YimDGrL^SQ8(7LY&u~ICnJ`rd5!SCF}mD|PKcP~5EY8yuIO!~VOA7`S!BYh*!>y& z7xDaU7t88;M*wvf^J4xwyeJwDh)82f%OFOib@=gm){=jc`jM3{yjw!?Rj-kvJ1Jbq zUYC)gF4CwR_7=qz@J7MJOrB93m-uP zx*I-D)qO|+XtU_x$UM*7zA2DoQ5f9Khs&rv__T8o+0_?{7_v@=MYZUACtS1UqTnniwtFA^_igfcR+`C;#LHSEmSyq)RI z>$xl7Uy3+D`pg6wa z`h(heDSu4*4x3pXiFO5GgcD;C6d*<2{qcOArnAAQcLCLDhZB`Pw@drt#!f)Ma}!w{LYYIcUQpVH!R;lm4%5;cR!%VRZKsq5YmT!(wCuZ=j^KXlM^lw?OS^7Q?ym8 zv}bq+U&7MydzkQo_I$F`sKQe@A%CEDHyUZPNz}v9%Q1HBuXScIW$Q#^pcD0;XFx%A z&ePVBu{sC;I3BN6S5?uJW7B~aS!e<1ZGC#7Ik}>`d7Wth6Im}k?-1ua0)3;X?lBsz zrrR6iO5I@lPNqq_>NH&;tb?SrBaUgaB@~UqiH*-VMi{mX&P5{YwX*Hy4>gb7p%vCp zTj2z!GQi0LR>Cvr797-i{cBAGz@GRrpHd{O#jv4ccgYm5Mqp=BfxAETf35F)I&r}s z>Pq0(-7)e@-&2aoS$eW>e!u{v4GEn0A|k0b-aFxRh0n#edkXz)`j|V!52oIy=gH)i^0gMXw@}kN&d#9napBKfgB;E z*yFS5eE2gjA*G1&j(zR`0AkMvHvnjCwJpXQ%!YCBPiU_Unk8v*EwzV`0@M7vW2x~I zPug*5Tnqg_Y%dE>2XZYhcgv*Yy)eh*+4)^BW#mCzyaS>E`T7PFQV2w6bxyrzN+vo< z#JU2rj-o>6k^^mF5OdIP;cjRDuqk42JnMk%5eC*6VBtL>sp-;^0G<=_T{v;y^IwXP zMes)-3oR1&5C>{f=;9`uOL||Iw()I8Iv&U!cv}j%1F_-f$nfU?to+wX-m1+HulH7t z?fbrd{$h1{2bTZCAvJNib3wwesA^?M#85Hfy7cL6112nY{u2a{ zW91g_YU|-?xM!e|!H@0#-zFc!w_WMda^h4cMo%*(S+DwsOIq4}6>(j(jg__uTZ`-F zy2vk&o~Wy8rY5%afY5#COc+{nk3Nv)p%yb{!+Z9&-4&E=%8S>f1^Zu4lxoaW?d!m? z;mLo*kS|a)fjompJX*3dW45RJS#XEye=s7nR7m?k(tF8CfEXvjbqNLvgC2VEm!ZNm zKW)}6{#}dxWL50!3 zL%^qKz0T|?wuLsnQe9X2eR9!Dh{o;!QfH%!(^w$ zVVg2-@NA~9`AXlEugLO-u}&_jv^9biidgdlFL(!!xfXmv`ZlViW@1Fjrd5?E+eqpP z9a^qjt(pD+@wt@R2}n|%{Is%w85a1>Xb|ii7C*Z}v=HOls^mW|jh8qY2UMuYI>=so0s)*KIPF4-QccX@Po_NHO96CQUF&llyMl z>aWYRsmY(~%2GBatVh}cJa6pc@O?KL-=$?q!uV;fhcV$=ryZ7l*@VX5OSt#VE`v&DS zzRwVRbExy8la`)On>^8%15t-Giwmk^-qf}p2Y!@Qeqm39?D3=*80+ve0OfA>(@`{$ii{5o`x_O{Y+L&(4>Sn z0s?A{S8Kus(Tdxk%rW`Tzw#-3CafO=ASQMLZ>6;}`vU0p>0Yrme3n+Rm@S+*o77e) z%-aalLI5=+*>s`}RUrnq`D&nn!7a9Dk&+}f{Vv$R%gBcsK@o7j(&vH@bl+u08EdqO z>z>bfHM%8rGGuD|ujTE9m^5`UK)cxE^{1kmp3TJg*cEJK3~Ux)=|J>)6gPWCn+_>@ z8i)|NEAA7$ir#wZFz7jVboDRe5E+RmAv$O{v`rw5ee6H?VZT!{JGg4eSnJd?4(`Xf zUOg9nHln7Ku~xQ@lm$>}Qcp4Eml)oUxBo708*1A9q0yR7Y8yszQg&wfaE*PJu)~eK zH74i_fX7%FB5*SX>(3@4;FpoV)|3U|gyJz~SH~VUFi@{@voWoN%(Zp{;Z~Q2Hub8P znK-5Ow?c+HFN(R2Y75}Xyi9DtKfXop(pSwX`}?JN^0B*1RVFW7gkEaKsnsLo(dF>G zP--f#qI}FYmHAu*Z3HpC9kNiDkKc;zPEHC7{QMoMYIbTf*9y@DKl3UMMSyt#OBhuIz$#SjaPWA_1mJ8mt+W=W=o)CtDx2nETJV9TyKK^ zj*0uq1E%<)_J;yokjpcmz>vZp-CR(U@{5O|bJ|~{Ak^nY*Xm1M)`0vi+(l~kuhe>x zWEB^`$5>Q+2trSdtDDdrS8-6Mx$-7yIp#|O23x&6?$-Q?&tMWui?9|SW(oV#zX^0 zGtO9I(~}{krL^xIlgy0w6yxkbQb*>z=7nj{6|E#8PbL9i4-dxGy1{t)d2Y7iyV?ZXo zC{QgaCi(naagY6C5`55Svt{owz?s2R{4#DOR(Ec}YY|X6 zZPtrR*%!O$*}GpkN;7=35}6+SvIUW6-;E1Z`_YXIn}C7tj0NHrFs&bm1a-mX>@xVE zTOsz?6DH)LGN_Z0T{A_4a#C3%g!X&lkRZlDGpUr#xvS(v3kJJPEGk}2SGVA}hIFgy zHyog*Av4GIBz+Xfi=B@#BPpE`LI>z9?0s;JwWP{3FavcLp%CY5hxrTdL+|(`!tr_< zaDFe;>z6>L<}Jb4JMN^~(@;SezpZ8hg&uICkZlIZLeJ6_fGs)eaf2rfh54h-?~j4R!zQ& zKihd&h^@=|W(E#)AsykA*9Pif;(c(>sZZvcx*2h4lxAAENet1N#9ycMo;{wz*bdTd z#>kn&UOTziNWeHqm5Kj;9e`7;d)NGLT_rEi726tQ!4{EagqaG#zfBRPRaG^UZ%6TU zxV90UZadKtAflpNGldDb6Up83)G{~n???J28qDAHZoR zvP^N3O5A}UQH?)weT*e}2NbD#i`oGEQQM$UD-}8Rt=yg>lP^QqT%un3aE#z<4wGz& z{vu55uztY?Y4^XAPP}kfK18+BO~Hzv-M?|8Sbe~*x&|B7w!7;fn<;N5B1l64i!r3LEoBBM#<@$Xtq@g z@)w;Bf7vDs0socZ1-HKqcM_HZaRJGgv_zD^tv&p2m#*`?)h=Q`k}iO(8ly>ex=^oBD;?ltxaz7v*&1eHHEy8$eCCFmYT+u5<``zxqf za$k|td?A&oP@+X|NDT5(5IoK5>s`nB4z3yk1r-tyz%>$=&0Aql(bHS(E1)0)EA!@Y zBg!2}WIujVi}{u_F}%HVFQ$OF3p&^M1@H#PrOs+tN#Y85r(vD<@8;)RR@62xR_ zz#|rWXhuXLgr>FRkdeXNC45v4&RY@WP#ioB$H5E`EsM9_;!l1eQ~U>285BD+_4C+! zUO=LOZ9okmHcO#2G^|5ewXu+kNY52l7Y@+BD9xmIO|A({XHgicw8=F=3p7o$?>|PD zZmxCLYAYg~?~bo>uoRHJ5s==R0*oN_$1_coh?;B|w7{v92bxO|kLV@MoAvsUiola$ z901WYnkl0-IOM0Fwuld{h?byp=Md^P=!k581HAs=vP&eG_H%Em03IfT4Tf8$QIB7# zkMy8X|KMZ^mHSpx7-8zgGw5%M2bUUbwfJ+cKu zU#hhYLUjaojPK86Ixb9j29TRrZ$6h(iOHg6divp&EM|r~Imh zv~k`I3R0NTWnHA|k;&wX(A$OMhJ{e!K_5t$Wb8ELR6_It?Qc!vABGgX0i1sV3}uwk zkSrUkL5QtbwQ`sks6?_HDupP7z3xM zh>vBwb~Fg9P{z{;e8Eq5%^Jq-HR?`^YB-~#*r}pur`X`gKmO-)#%tIN)sKPaHwcp` zbMM5FQl&8eN0kB%jQz_Cl{!s0+YEi12hJ9aX^qO=g>b{r~5j4$fbrM4fe)K2Uh9)tYI*vevlBz z+Z8KyCwEao&rs-W3%3^DHg^N;shgVQ{C7sL&YOQ1Vj^H6;R!AxB zfgNjLRd{O7)_LJ(7@u+X4D2;i?>YWgallDSRp>pN#mbMM(YmU2%_Fj!H6cp_{Ls}n+=~U&rTCV zN@ey(8VauYpM1p_WeLlLeKR&g8JQrWWU}=j(safwDMsF>N`E^AJ`uLTnEUmela+Q6 zfI&plFZBJA9@nQ|0!qBMmNUQ&Etj~|XL?L@lc$YncXJc%IWHhLg zS`!Tai#jS09kxU7SM%^GE?IIe!?x4V-4_{xNd?sW)-GMw47M262)pGwE`?&i9;3LD zAqM*KEvsT@V(t@v2eu?+luv27dfX#k8J5LO%kC{oeI3$r7>`4bcE2##@&26WV>tgB zKR~^6X7{Pt7fOnG1P&nKIZ4?toKpD|kKCP7)ikPD{#|Ixt2;cNCEjh_SPdJQsmvx$ zz&wi{s!}~oxF^BUqN;eg?q4QGUqKDwaDB}`O3JdzFE$@&=4OiaMV-@*8QL}*F@zWAkjxjPR9j!P&MVJ|Mn@|MS7nZ&>7 zH<$o4_gdF)ki;3a2hnzJWz6rQiA#`%AmdT2`di?0^KQJrb&C3 z=$5~4cDJH-SlS)3+ijgYGH#seMg24DL6MPCD`=zh#*#x5Ns17$FPabGlpz>)hp$lN zaa{_!b*dNjH}Zs=Dc?k3(5%lThh}6S4Z5@26t*7#aF~M~p1t`O^jEH^u6w86A2G%$ zviI*cG3QV-X-OMis;9VXB<%l`O*Y+oO~sAk zJQP|tbsyH4ebd~qBx&bmU@GSTTWFb}o)GX{s5ymM-sDE}-rB&i((%#-)zmC5enebS zfQ7qMm$t2KS4r(>uP3xy&JR3Tq9h`s%luA`!aOp@2gJs}P{ZRJmUd$K>R#N%mguS= zCagsJ@)mM(OkD0!2e5SZ-q&4o^yv*L24BkJyQDtc_jH+4dQxCUs_-|{lWr6Y*GXSek2FcN=Mw&|(fa(wfH)?c@qqzY6`3iG8!dFo@$~x5uKKAR zyYW>nX-013k)uepsSC1$Pd{0SQ#v!uQ&|#%Dy-ExgXdmPMKXULLP$o!` zCmSmbi}Ikrpk3R~aY2Isxjf)XmP7bt4?@Lt>?UHF6YKe=hUCewJS@piiS)omnYhuO zd$&OfUqF~;DcxXeC%LKfSB`# zDVNDE);mKgHaogQh4l>>E_g$(q$F+Js|Az^lqVPOyna%ofZ8ba!yuWvUABG>Svy`G z8&A=Z{x-kt4Ok`D(hv<`^hYoe31a?Q_ym|M(Oui`^<3j!3T9-?>}MkHU=Bv-?0V zuxy&@&=ict$H(~fPvX}>&9*c?ff)&+QM6$D@@(d=Xh*q|d&%bj#HaG_i`e|16u=3V;AeSgyevk%$8Dpf1?+WUOsiLkUE`D zmCGG09j3mV)NBVXUdX`(VSPj>=B@CZEj`YVeR(eP2)=r$SOljz1>LlVYQ#9n==Wl=<1$VI7iH63?x35(y`Rn8-q&oEdhrQN z6uCDY(A`TelMDI?Kmj)2iAJWo8QD+y;d=wg?*S$0ZIy(7_>KboZ!ql}n9#G`l4V9o zVcvH2ODO|ydG5Y?2X3e-xC69oP#;R7uf5(Fa*(1DsabpWmMz*nkh*+%K5p-nH{$PW zDs*d7pu!%ZBw2*(+|V>&sDZEDSHh+Of6ty|C>VT|n2>sQKX?`_;HTdWOCE~89e?tGMr3JtAk}#?rmU>CN9I9N6==0MWXMaZtkTrr%%q~#=EV(H;|4EO2 ziH%AX(bj|8C9J`LBXB>t&VK_&s5z_uamjl;vtFP6iV8WcYQc_LsByOeB`6iy3a-KV zBOJl#h8?(ZZla`TB25m`s&FPF{1xqI5r=7S#!TT$1cvEWK)Q5f=TYcfCv<>oQc^Dnp@%yDoVm zO|#z`?sc%;@(Bg>YCML<=U^)CwpFg&&iLfl-*Q5cZN%7M@#qF|IHLnT8x%)$leJ+e z-Xo8`h+f}^N7P@DKG1_AMwK*p5)z=j5?Sgnsp+3 zND7@*?FSlpJDB4Zn-(mx1HtudtN?1Z!NN&Ro%IfTUEn(s%q_aJdn(~2C~Er^KqEZtl4#kY6X(4W$otx`=8UD80 zPQj+^La>HuVBR(nYKGUp6-c6Uk7(Z3vTfkSA0O4l@6Mr+T;^;QbEnKL=+8{Z7d-l2 z+fP*UqyJDoLSPN^_q)dR=VMSw!IWTVy<)(DfEN8_`z|AAv$pt^`T##25Ej+hX80wv z&hjo#q9GK$EMx3MR|khYFCx!K(;!j&UDcmwoUh}FHpTjU$_Lz5Do&+#<_Vemx4Nne zoZ=62tDC-WP~-O~GV-g2qlr4|*HTh$?HiQvS)IFjh;P5IYKKQOfAotDGZHIjYsnoL zBQ8|#2PnOrp|6E{59M9=i^|zOk5A0b!)`i22+|brD4W1adOX7I;2;F``R=$il)O_$ z@*1n@-qMIyjNMNGv!BpyOua>$w6gfQNxkTpax?51BVQ`VWqbhjwz)&&VE% zJC~s5GG;tgEc>ZJ{rS{T;9CQ?9!dIH>s7HK&{FH>4<%e zo4QKX3eJ>wyCkF%yd<_@Kw{Ex4nJaYFQLg20}nY@cYIti6U&S&g#CMOV7nR%WsJe* zOJI!WK9nlVaG%iq01h^?@nU#t$eX^4RHv=(K8_qCzM^wOz7;Zr-6D0>n){PDRWGD8 zOf$pRe4j!upY|t^6>Ahvyh{f{B$%eeOfMqYfSH$TedsGOH~!I!y}t-bRz3f<5^coK zymjg3ZyGQ(TPz)qg`nvD{o>~nbIoI8kfo$Qk!5$(?F=0Tm6LRZ>@nWSxh{NdEDaU6 zYYfupsLPOC5mUvTRP>Pd$QNb6KkD`9{XJ*9#lvvmk3g{gZ~k#2yR+iVv~ zHggVPE&;AG_*C1^B&8Fvehc;I4kw!L0Sh!wk;0SU<`iW3dqFoMIj!`mJNtes*eefy zKvh~uVK0?lTqWfOi5DZb8#pd|MWqo6jnj>`jYq{#kBj01g`rxajmk~$$=-bip+6zH zID3)zT%VWY>s{(z!KE;;f8b2-<>R0&Ben=3=4Um62U!BtXr=K&aI{`j?H-x3Rq<&q ze5!0-)cO{uAKON7WhR*MwnDQ=nS2MnEAF(x@V7_!&*Y6XrsWr!w=6CLF#Y>N=b_*< zNo3dz)wp+`4&rkSAPgY~uMd-y*4*Q)jgGE|y(}4K?~qE_u=cDv;l~{B)%*CMW+>)J1}^wiac^yHpE_p$-Xr z$;n8kQFt9XFvaHro{`o$$TjdYtM(81&hI8hNLIW>MB>-{-?Eh;2kS>1-iTfZ?x9wi zU5_=zv(tU!C4$V$t=R8_b_i9T^Z*}{Bo6kLm^2U&lP5cty>&&Mt-*Px31|wu6zO92 zUQTWM@+BaPQ>MZ(ajN>F9HFzK*CJYSVO%hE%!07c2aJ^wSES-X^F4=FML5Ja>rm@_hM-7D&qw=c1WW~DS74i< zH$ivgeLgnY)%|EkjA&s@>Np^!xpv@q~x749F%TL*%!L#+|o4q+n- zUsCy<#h6a7cOl51Z6%aXks7ou;}zxRCAf~*GvfsTduymUL`zsa7gHBpyw%OrDd!h@ zX{L3K3IIXAw2gTktSS$ids^rh;peG8GAP$Q+LiEt+ovz;jsBaQkep% zSgVxypP4NlXir*^E8pnmG`4`7u?~mqDHlzcEkMxs%2l0K8P$AFE_Ge!KJ7=`u>|E| z59h=darF3#@%+`>>kEPp{$!%CQ>*m>!jGU$T^m#~NXm*rSxSXybgynRej`-U| zXrNe9pRMLABXIL>-0>}?!hi2ySi+WOXG?tG*OuD%*Lr=lPe{FoYxKR*Mclei(g1(n zJXhB{TdDIGc1H})NC&9HFkr@*ASt?Ec5P!{hkiD^qvY0VRdb7rVnD@yqca4~;+>yo z9Ppud(hFF@F6?*;$qOC(%yQV|70U^W*)yrOBz{>)zuMbenbDFPw)S;+Q)!7OYdrhX zr|ZS{>Wes8jsnMSmWqWOksFtno~NA3eETJAV#psf_()uR{5~18A zLnsF2LsySxaxW(L>Y>k9)~5G29d6m)8jSS;cEeUcS3OD;1oHg4J7DpM9u^3hkp3sC z1XI|43|MN}TI3Pb%t*ci2)toO-QHgV$B&!{ljExHoa4p@c-jixu*35U<)B|4KC=~n z@$@*d?eeCJ9eB0_8O;~87#B%l7rnkq1OU!U%tv8%h1@HJNP_g6v|>}o22k=ox^40q z4}XNtrcIWYloGbk)}+DA6jb(l@swhr$0C~z4r$LgT-u+&`jdeq&Y$zbW~~Mx@z8+|$hr=90<_j>NuUuv_JRawz&Th+RY zbcMej<+CIxOUO#>p&iN`K8VWcsY%7gV>g-LCj*vybBs3LiGVOH z0F(>+A35OdwlN`){-o}u<$IbDK~bxTRN#$Y5F2(UcRjFJhI_X~`_O@?&A`ZC`~Hjy zJzZf-n=*A~sjMbfGh^;_JdZ{po5EeoBCE$<3 z={$X&rp`NOybI-%pt7&CQJnSd}V`8DUqt%R_5rLQzPwckkI+mdk6L((^89)>$ z%<(=M9e6RUT+Y`i`T{#C*g7}Ml(IO-e>z6exBmN7d;y}HQ&$9YP6m+WcnU>l5`)(< zS)_KVeBN@B5tK}7C~l5A?PvnpfY5PDj|N#diGj-+bRJ@( zrMQK|(gZy_lQs+zRr`C$qa~-4us%tKzjlwrO#aSF_AeDP20ArK=Lr9qto9&ntFi^D zJ0ho-A3CI>^BaVTnbbi}+*;T6I-7B;i6se4Ncro*Dbu6)7-M zGxNxZ+o}gA`zs8>DcV0c^@4i1Rq+~bTU^k{$U5S$ zv~RlP19)FYORxSaekZyYw2~)q6WP0K9GX5Ug_^fyTWx#nvL-r9w->Lqp}b9JOoq`@ zE?s2kRoT0)!Bs(-j!o@7p6cWBc13NfyNL_H6aJYju+pjPSXWJmE(A|{cB(q22$Mo| zFFG}_Hq3YIR6#C*_Mh|TBfvkTQiC|+67Aa~pbNiYn2E5YJ*jGQp_$2^Xhk*h8dun`%P8AhB7n9VP{+E>?h0N5=b7z1e z2JK$XkXZpSBo{YIW0u16;2{b-pOmfEq^Y7*4Jxx-`o8NS))OM7m0l%s`4}HiWCUC2 z4j*jcPW6BA6HnT8t6G@T2Qro_#~u$9+m>If!S7ow)@>63*#w-;^#LP{uW>ch;c&aOVU#N~k?O0f5(BP8}e zo}A3i>O`CpYxyo3|Je>J<;H9Y$TLzTaW^206f6CGt2f^|J-QO#~b zUrAGouQYwA!9~qIDFCDMyF>s5SEcLyn5M4A#B6PS_CA6g66ej*)&4>Fq_b)S6DSZs zC&@!}&##+c7ekNNw^nlVNDAgQ@;_1eZpfnqi~)vjgD2v;@{f<9Ip-JM1`rH?`XXJ3 zHO9?gqVWC6?S-s}{e8f98-P6_9*#}hAmTW!)U_)sF}!;Mq9stk0U&m7mE zbTH07ZIPjggWhSA8Wf?hs(`Q@0zVU)6@Rn>k1z}F*>cNtl}b6YPIwZrcZtBS7yZF# zWzh((R$SocZ?hf{&e-4XXRX)>;CVLWR~$tmr$nd{H)I!Ms{vp^sa?GfObrU_f= zA(i1p89B^_U!`kCH{qcdKep+xfhG3QxFT97NP_`3)VRQ(H&Pp&bq+ zn%V*tOGYFPv3bH<0boibio0;C^hLo91SUUpz1=ga)?!w%=Pi3?qCm9dy^b}y@h@4Y z0c~2RraOY8v{X?uYx{Ugbclad>IjY*c)WlaFF}_epq{@(t}Z5K<0YVyslJR2mh6+6 z;^%?Y5Mnx)I8inc0N}wo#nh!4^nzv#`LhH*SHnZA#!{7!)A8QfS8Xy+$BY|#Q)S46yWGw$&6A zwksu!3k3L$K|wt^8-IwWk6|$WXLU8vL6F*WfX~VHL;z>a%CBvNIhwM&{H&X@l`qK# zI;4A=CC263dd7={YPTLDst}gbRZyY=1Zk4jYag3M2XWfmcEz|fqB1iUF0d+)LqL*u zbWYr~;(ftauk|rS${XzJO>4bEBRP-$6*sa!rAOQHlL2JQr%pt zDQht_NMST$R?a1;z+&|^SWS*$)UG8^?nT`ceMW&t!#_WP+nQNcPetvV;{2BXT{m#8 z((BnRDzCW~N_ky&wU2ZeZ*+Z1?t`U)^VOh3UPijUNvO_pHZskOo1pn!x4FlRvRSl5 z!H`pu(x^=NH9#`a@Gr}13*f#q$$}V-`}|OiXVr$(@v*8eoV-%IpBEf-9p5b)ltY_< zxk#h0OE3-DKM_cIV9X_I+ltz&+6jD|O0W41`+AaLr5E^l8vs&PUMC_q^uAIy)7+Xf z^+XO+3-+6^wh`pjMK0XiMi`oqi_HGUluwtrLblV7d?3-N=7r8>>y-VU;~zU>s;sf^*;!X#v8Y6Hr+2Rm;8JA-=PK?DAcHbA z7XV@T^+E%rxB_po(`8XAj^8MFii!aHB-Yi2s{4kMT@j@7{Wci$Vd^ue4DhsQ?$hH> zA|&1)DTIq#a~0NNqj7!kWj4xaifv(>4O89p60=|Mv4+;-)__U@37KWvuIBt`Tlo-~ zi=PNm39ea9Z26HZSL*Pi+qju2FRPUSeeBqGb9GOML}_-(Jn$`h4ZhTf4ZNUI^eWL} zDyiZ@FH+8yePx?;g5E<-_>OlR81;Uuls@N>E1?zuf1I6$(R64 zJc6p1C=ZjRY=z~NK;WYRS5`wn-Kno3c@T^LOHt&a<<|`2o*p>cWZ|(}crA+Z0HQO_f{0$rnZf1PGY<-W%TULDEe zf{Mf!gMMXgg(hae^rakbx-$Afdn;s^Sd7ju^H%U@?{j&?!Uxxd9d$S!6@s1f-8yok zBMwR$I+w`t@mO6Su5HKz;Cm1CZ#6-U)dPjy>pgR^lQqB(`$E+5Yc=AQ#o6*{yKr9c z4Cb|gl*uWfG>O@qNdY%j7BEL|$mryUCdm|XOwC)w4 zqz4-5wqt&XKv#x&YjwU?kNyqcOn*6=m!^ls{Ze-}$!25E$22?idJ)i{G)&v_)B)2-<@pn*ea_G5&|g+{V4laI0Y=lXVI#>nC2pQ22W{fV;U0+ zrP5)?MOz`Ozk7d-EV`4QL1)BYQ>>5$hP8knTQyIT^{8L_R^2U|>dOz9JWlbYEH`lD zT(6cks4DE>EC9`~104k~jOYGM>6dNc`6FNm>iZ|i`QJ(Y*+?~OL&X`8vGMMNdRO|T z*4WALisuuA{3ukenf;Nzktdia+}AF_AqhV`{5p>8`HyzPy;#jHs4V$1xl#fk%zAS zKU_6l`Hw@Mk~Wbikm!8O#GDhmVLd27#|a--^G!B)+@LOoDzc}mp!el98~jV1TP8E(&f%1 zvDxG}AGFTuCx2fSQlu|0uaWF}A@`v;czDIBlw*hZm7e*6m~EX%fU0^n`Ct1vJ+8dX z{AWf7e&6r^jc4cCV32!B5M?@GhkEUrL`Z?mt>kKA_yTW1ij71l8n{wmOF#VGGp!V{ zG-Ds!>zY5Af+#j`j@LOZz&HD?S8ReB#^g)N0BBb<@KwwXn#Bm6!g ze5yoLd*+}QSnm-(NVupKN|LEL;-)wQrqg+gI0mmv)T;^;|1J8fOJts~J-QeH{ljW+ zA)NIut1Utj$#UL-7*Hj5S7Ru}o6u=~#F({l*gx zX|D7dig%C9m~@CBgj<7DsqVrLibk==`~C7PuljN{dU;R~#svKe9!jID z!*0LG%{7)A z5h1Q(WY~qs+S1l(%r{p_a~cqP*I3;P^A_h~EHaV~aBp{X4gbQ8J3lEXkBGPeTRMwn ziIOkJFmuBoyrkq_>i8kH#Ya{(kM`BwcOBo*C!++p(8MSfrLRX-g_Ah+tP?POcON~~ z*CM{+PHjsLz8yn(G?i~Sp|hav_80Uda3&Z&9NyfiXA;xM*KiZ1vnAmQ>Gn=mf*0Jp zmM>WYoAkqG(vX!M;F00L>Pj%JHo6G*q7#eU#52hs$bHI<81hXXP;>k)`l zjXsD*!u}+rOOhExY{_XdB9&X(Sfl_mgDs>NE&xrMeeVRQi}HNA+f>hE6jEDx_K95j ziiL=O%I*7Nyd4dYQ71)opjG@}>hEqq>kDB;MDDgAOyLM(Dc#Va)qg^{4-)VD6Qc2j zs#X|maC%KrcFw8o3d~jT0hvVU#B?(%&QtSGj~r(?D-K5DNd{8C#6OdSMhctD9i?WR zK0VQr+TsygiF(8{x~UocJmc`7n}bl!sbb@W#>C|!yBdxJwN1(xeXyBOc!+63;Qf%M zzue;k@?D{#h{vm`!rDLod8P;b#IgHFJ#~U6QiVVH$%RHF=?|8Sy8?q?X-SMY(N54~ zEVdG|j!VCqj$kjZ8ZQVq_t){>})}BWV$IF*=YC2O8D&!Us*b<7+mMW42OjBc9FuLo0Q zHWB%@X(=9Ek5^soLiyG9!yYNbNd)Bkzne;X-B(fm#L?O5kCb@4TRuGCn_7E&N0oWQ*yV!t(YlFbogF!~Vk2yx_mD>p)~E;@LcYB$SWn zREs8S;Z8(aeR~o%EE26Iyr-ipCAr?_WG$HVR- z>E3uI%Y58u2AKAcL_qLf;TH8>O`C=0CcUf7Mq(II)jXeW`sbAV!Wx}pEZoD1XOuTs z4HLNEK|OGI9$|HN%)ei#(}~Q}Ku%@7&OGp1kK*AZs_hTa0}b^yn9ZekKqLx+XnBG- zXm2YE&JWEGy4$rPIMT464+ss|UZ>EhIc7{o&ML!ajFH^&z&cn^AF!lNznNFhuClLc zLehVQj6lYklUG#rw1Zi-8B%McKMr@Anf7d}yJVakn{q zylLCitUrQdn{g#N26JF>!!Xm90!v1{)NaNp%+TQrW@73o$ImsMFCU=%j7o!!JN0^R zQm>huhO6Zpg0mPkcblV>$T=`St*H-_xXA4U@(Y@=(aD}bPjMk*Dg`D}qd!CB_h+taii5OSVP12DQ?>5L%~<~r6)7^El3^-#UO@P^m`R`3vk?CbnnDTx1b zU~Bb^3oryzg<%Z*|BoTkq09G>Q#3hZ%$Ly_4T?~heHnW| z93tLOkTRM*2Q|P*ObX4BtM~H;cYv0ASu^Iplek&XIv>pE9n`g0?&p>Ib=x;|uzgML z?;sQ9f(MS>S9LR1#DK5{pKEe4&#YgT6YKOewrf@IRVGf`Y%gRfkvwfF(v-a{nYovC z?tT5TjTBD_fwO2nc_>y;KZZ<|Y_0aiLnZ3G;<|Sj#)4&YIFOymSIwe)(Ysw@a|$1L2~Kc5@Y;ZL21xT)Ol zyfL5mgbC-o>?+GUIxyl}yv?ZFMu6<929DTlHDyw`!}*tJ1}#33aYSwbQ4m{nxj)zW zT$twgm@+1tUYv;gs&LXS!uA4^GgXqh`wj~T-(B5DD6TTICymq?LuAB%U}D*0(J0Av zJ4CdODwFw4Pkw8d$r^%DnzDd!F8>*38@9X^j^+=J1Q3)&Y%)t>yh;{(B`PPDsi|QQ z!A9Nn5ms|@DWJ7pxm647%Ypqwu9-LIkiSQHN3ckRp zHFpXDf0$8%k`&;Y2%`*aXYvKAsZP#2v9^qYT@mu-*V;N|pyQ+o0UWXjkd(DiRwN?* z60Lf5&kqkH!=@kjIlM0zQxxytkZMpXjEkt$j9HJ^freMX(fjA7AZ~oW&g0G~HGGa5 zX6k)`3EQY-x;zIzBhv+!Op?N+=xqC-or_J&I+o`I4@ieB-BI&Keqo8exUim_#5Yyu zPk4T?SwhOXO0rPB7HFA5w2NRpR6!RJIYM1Q?7~xmd@{+=G)dS`DIx2Zm`v*-&QR7< z+3{{B`s8sm*f^{?PXacR@(76BB;6nN>3@Tuq-(|Rj)M7;yn;W@hNd+57N^^n%2Y$x z{4w5h(0LlHVHLeNWIM*SmFq5OVCW_{vk-PhF_5sI7po7G z%o2F+7aZ8fb_!awi?L@B-bfURD#vj~locsNo;3py_fd+foJyKR)yFrTw5>tV+R_^N zlkO-oWec1VpuhMYFL9mzMm)4*5XCKkm3?y3s=_$aycwMWwP}5RPQpGL=Es< z-b^kc%{(Onr44x&uu(regjV_hu6i~_I?Nqr|MW@DwOmp3J_quHgiTJj&I5ZRW8Y+= zRg(EGr6GwaLP$2ntJZ?!|3&;^rcb$1y43@z3+Ho#mmRXkb)Zt2{2M2F5W($mAxo2_ zAng`*mx8My{-i(Iy__!@LcFt2MDw1|=gEFCs=Q0ObK%3kU82~xw)_e*x&MH+DvRoY zpz9u`ot^r%+}^T$QCOrQ ztm1i=km3u!QD%1n|7Qwt9|UZ$TP-FdT7`3FZhW)rHggZnvIp*X(Y;>!G4_IIl&b&l z(j)wWs^ag%ba`y)KaJrV$h7|z^kC?OKdQ!4Q5u^Bo2$j{nwWrzja%;uX>ro?Nx{K~ zvlvT)0*A2ic1u33l~J)|u>)Ju5PMG42>AW#@W&QIhNj!ib?q-k1 z&7MC1Bq7Rac_#y6->tcf*a(OX452Ccx{|fsxEi~wM6%i&i@`i$pL&alnF+(R?$0Re6f7k3z$faQleMED2cmZTv%d39M=1336qd9#By=)PtOp$w`@C8qYM8; zOgGgggMM7OrRa;q752x`IcEX4%BOLt1eFi`3Z7E3`$$K&r4+(XsMQY;b~z(-F69@? zt%^z|$eSgUG`veM+zQRX0&;zz5T`O|=+z_W$-D&x9;{VG`$8`dQH?RNybz%S!*4YR zr7w|ALu+C?08G%hGrY=IxEr)m8m9wzpikO{x!A^O=3y>kmS7Eb++7Z+^M>BfIW)&< z?aP|=!_IA`f39=6roV`jD-MfGrR!qG8pmT}SYkKEyZ~~nJ$xdiS@CXQMLwB!K!T@I z^GJ?Lqv1R1cc*<5=fuXQZrbQj$T={pis1;UDU9N z18j4tWgs@{Z|9bL0f(?5y0q;dfn}FA+Gv1endaJ+1m9i#hSB}{9M_4z=9z5u0ahT0 zd8dttg5@$e;P9AZsjKS=jjunbSD4<&oQ)kA#i)W&n{URr3DfG-oZXwd5s1&?Hw(E>Qo3g1Ftt=U; zOCtGB-jBX`o2$9{u|8;q8cJchV^Jj$S3;3cZ_(z68ls}Tg0;_;44m{8kSqS_SGg7-PYa*hHpL~u$HKfNyxA+hu zmBmQGP)$lU;p`p<_h@6w69aH#v77T?0d8YlO)OkoSc|)E(P`Zo{`=P4XqTKu4c$$> zQsmjf15QlhW@}BpYxCB=ExO$sPhbLcq43c9BQq&}00~DGsMy=M;ULxGkRN z^l961iU3&kg#W|56K-Fu)^ZyyyC?mP%vpK4W9SO=f25yGHJaT25km7EhR`B@fq4Xz zT=J{mw;hDN-uu#ZL%11Zm;Mfsoj6d%de%|Y{Eh6@;s?$l0|KF8jq&v#v#*~M*n!gb z>EdEZ${ZC3IpzWEY<)ZNQrhyDRqt>v*{;7@MV1k9lIjD0Z# zq|fjt(zbn!CSMu4d4TL~{;$D0!aWo`pv8CemR3=Ve17F4T}B%&D8PVgYK3giswne= zEkbYeUR|Plx?B>l+Mw&-tsP8M&#eMz&Hh|lWo@O*)9o^JY*>Rj!EwK}qP-C1M#TVv zvFmSh`4S`K+W(`(obk*K8hQ|7kEOCTQD?Q4zD$8r{M{!emqG#T2$8t(uUAxaQjgxs z?HkICmmb{b`e?5=uwtX1ysV!n9=EEnk>r)F`Q_BiBM(X~-Rfk~1U%5n{?i$qD5V_# zKCbEe5(90|yk95I8o9tRh;A;gHDB<~lK5}dXB@^{?pdnVjHnal_u_&tf*wo_t3KOJ z#gH=O@N~hF8{PA#_Ga=Ce=G|7EV@UAx6_IQw`S&}Y1Z_JpAr;ij)l1(v z#T85XPJ{F(+lsLcAIUr%HZ@d>RQNF-4jfKIDUhuwg|u=l8;d3{w!#z+fzUT8To2qK zVi0=kqi)n&v=c7YkJ(oZoBbYUw{EP6xpiP-gL0O}F5Lcz?gyG;8Q$@w`^?))>lR=% zM*Q+^?);!Su@M7{t|sq>ksx{*HP#aRb6T?#_+~Tf#Ebl~aRJBt)|O-LEd(8aB+!5Z*%+4WYMAYA zn&3iOo$T#KJhkxFh?0poU)H+)GBJVa@m7hWR;B|0VBx4)+rDx+YzR#zSElw8eM&E6 zxThm5q)M&Np`tRo(U=0{8bKx_x}q0is;0+uo$AM+2nrfbaoI)p=vR3X&^RyKy;_9f zvSNN#vrsCaG9QL<#HG5ETOybAg1e+FXglY_S^kD!eY^ z%`f7S7WtG88|DFXVII$3A#lrEhrvcUS*CP?f1+$kP+z?q8fAb1L>bS`?>$}{ae_~a z!JwLV?yLsfYM?Ywq~O{;p!b@%)mh+w1q9VHj7jwh4w-}XM=N}LWhDZ{h`VY}i7{Zp zM~fo-O5U@%?YQ69)d`r)U$46Y!(w9YnL-=BTc}(>1BNLn1`AV0DFZtZWbp~gX=(b* zg(DOj{bjlJYr86)Ze$waH#yXWK%@Bt?4CPxm!xEhNU~zV9PMXsBd!l*F6EN8wQ(fC zV44skYf2*N3aSZWIp9F<6DJgN>veld;X-9Mu7C(8`BRu!-SzDzH#dc~h>-;?1g6!d zn6M5@OjCAwt%AiCy4WCJOdV;U;OV@$To6hM(^8x+8*KMOgKw$K0PPk`!z6iGX#4s0 zu(Scf-S_1?U`RM|9_+T@x<-eHhCml0cSrJ64ri`U(AZ+ZWb#+8HUa%urdE6dsY`0<6p5W9a!;>+OW^70>W%SqHWbVDatup-c*nEY2BtW**;7h=( z%D75TJQ z9Dta~&G0xFzM1TP3_Zb^CY?~^0M8E#cZM-lIHWO9QDlgL1u~g9(PAKu@F_9%dAlAD zx>1y=RLw)qMK>Zl8BrDQ4wRGKn_87E#4t-@td*e|9uHn#h#>v_ad2jV%zP5jco~1KjZh|>HlwvY3#Nx-@vx$TdsD{!dG2!+#+UB^jg%&2X> z0h86{buJ|bS%yDEiwm_l)xFP1iuZBWYc7*L3&3^ms9l^rrQ5}gtlIR=UnKs96hvh| ziGR~!NU%fj9^SmSQ4jnw@&w{b%e!NJTbi+vSBc#1-jOZcLdZO@*QLCtGZZqf_vt0l z8f5nys}8(SyoE&IrtwNLFEA%aPyC8nc;^;X&&n03sG{$h76SCJME%530Z$#B31UL& zix{M3?~DF%pG!wbL33OTQhj;6lPao#nIWZ~tj$+ZP`t^OuiqMv?luJ=GU!p1auTB# zC4UM&%p%VPvMZ`K0pHY4;Q~WWtWadlFT$y?^72gI7N%79zZz-lp<2h!MlHfRe@YZ0 z6-Gua!I<|8^C$dxX9d{c_PDkS+f8eJo4;HYmr0**5o~T99%Wm(V2`7znHQ3{WhKP# z>ZZU~sZ4m|*76yghMq+}{UJ;$R(vD!BB6oX=K6&hI~`%OA+=;32WHacoUnGC$pUJP z)r8fjd~jq&*8j(!FYUov%T^LGo&RQ<_)x}F{f$X7jNOdBFnO;U)hHbUhZ10V%;xA$ zAzh;e```94)(}4IBWcHb_IRezib&bqH6PT~^5LQritG}n@m;dRYjV`;Pa*$kQBm2~ zFDTdFyfsfre&->A*9?60hK6Fz^&@w|6pF+uf^-g$lhsVn3aoSh!W~6@;sa)c{JoBqpIDiDOt$6X`7V-J%Bdurd`92uv~CWioD{z$ zTRBRvF{;rl<_0~)V8_i#jp0yL6bT z5Ld%L6}1~`vwb%LOb>61O?d zGdIS=`xM=w7KDJyH|LjaA*XQ}D=jefi7g|T{9t5CCS^+R5?P~+*}dGiXUUCGa#m{P zS)x-p$Ggxq^%m=YVxtSjgxycyZK2Re2PKFJ@=YPhbQVoqa z=C9)uzNYzEIS&_R&ar)e85;O7I;C936Xp>2}y0mB5C)#S4i#LAhS&7G9*)rm)(djEA z%AJXN_2m00%!vDf55GrL$}3CQM}K8FTC?a2*WrtaS2Ek9g}V8?Qj#DLW>kUUNk8F? zE(<&7Nwi>EATz{Hf$x^ubC4^vhM`=|pvUtD4Jukemi0gz3Octq;k)BP`BLSW;uqAg z33GM902mLa3s}K;Tnq)+`^EiSX1-Kt(H2zu#h2Fuf=9bY>Yj^`2eQ%z6nX2m;Sg1+ z6Y6Dp(B)=b=X(%ed?kHOce5D+u|*sjQ6zHIssju+DtLhf%5%B3*!3kVFj)X*y=*w5 z!}~*pZL7-IbEtOOZU7n3xgMJ{<*}Lg|vbSr|9MjNdQDcnr6Rpqdf)W~S z^>t>VRWM{7Xhu+4lkvh6Xq8n_;8r@8hK~DRJ0D4$J>~L@Kh|v*#~4`}igKv4Ioibf z#me7ENYT=|6kRAgOtZ_48<9q9Eg>P9m~G5!j*%Tg!g3nM(y#3h{~o2T7QhAHH{u>H z6(I~WZ~g5*e%ERHc6nv#*^TzVZ1)v^1lMuQs)chS@yKG(jsZ3QPfru(DDlC11i*WB ztQ=Led;q!N6lb=@X<`fJwMK?-3EzY)s4$6JBuDx~B-ID^x~m)gV6BN?V25}}yTD`g zCx$chNn}i1l$y8?MdFfunugoA1?bmgMEZ1Ka)}d6E?-vn*N>O*e zW1u1YybN!e{ocNxE>P7nr0^T<`oGP|*!TwW7mAV?xWnbY!t{5!ar=bs@Vl8#yv$u9a4TsN0T%Npp(L0nX_^wY1#aI|UFQRim4;}8gKq>2oCO7U6oW^YUm~xl z{qyH@?C;lC+3)8Y7$gbV6!~Df1rLuiNU;V%E|op?&lFHywv+4C_@8`_BQ-fN$o6yx z#7xiO+diKP{Yaix7*NmmJ!5$Cxhw9r72xNI%oZzKMz9mUSNP`FLl)5+33dztsIns=vm#PlU}~ zJVmpx6mKnWHTqzGWI)K?s4G@=bjjf?;xEEJx}zZ2qr7RI9M4|kz-DsJB9^U3$y=;N z+)s}7rY=ez0pz!XXp$?K-y#p$Pj7NJR{9&eT20tn#%1`_PNl#PEy6gYY%?!Dv%Iq8tocd1G%LhS2ISTY-BmW`uVm_k@}+3wPE2=3 zY!_|_nU)*1L_3r%56zGlkATaxfZa9RouPCgFvS7X&3fKiAC04$5 zM_JE|F0;d527zTcc7=i&>?hZ3NjFqtq1v|2ZtFK3* z1Gc-`^~k;sP56Z5`_xoKa^)~rqqawn(=x(?2TvCuh@lI!?@K3O;GOKk->)uouB0nj zly$yT^%!E=;x+C!F5gJ_fHKSRgLngI2G@edb}A4m+jHh+B%gC1RaLeSWq@#6j*7@k z%5+C#KkiAxh7V>|2=1TtT8T`wmu_`oz^9U^IGG3m5`uStAe~}HlHEB?&%la4Fq--( z=-BuN4XaGl0!-J#7KtQ;QhcNvRDZ;DPlyT>1KAo#|1A5zGx7Ki-Ncyky)u~tj#j~h zU8dI|@`v`kx6-P0)wtC6t_0|d$vuFx36Sd}6y`?1LqkBC8Bkc$YwcC8D zOC#H&B@D)-4Z9j$8$t_)a>L476a=H!0p}NZ&{W>kc0J*JCO))rLWDM0cp@?;4#=4W z<4UGl8U_l8M^Rj;a&Qb{U-KRUP$0%!P%s}(S~>#B%0Hy>W(D&Z<*M6tQNg&B`YpDL zLfo386YG_Y@MVX|p+mI(cJ#=*8J2{dFOujYn()>1#EltQA-@&v0K{u?rK@$<<7#qBD^~)?zST9(-|q3o=4rQfnIf>c z;TVycHQ72D$9M8At^_W(HJ7Evmrh;2sWmH88f#9drXolzfhDXkiF>m+G(rodUjpdv z5}VHF5cy@c#dHSm$d$7|Fzg?W>yt5&S}($og{n+Z#Lzy-$zev8)L>S9k;Ei+`w0k0 zFG_Qej-9eNsFgl#5Lc0nRbn3@#{m_vaSJBA5Hmh`H)MsFLLtomQJTWwQN#c86g}vP z66eiWFNga|P;5=#Z)BWglSzrT4G=#QoticAz~}Ir=sD9evLk1A+q?}KcY3~5R%Gn9 zE(66i+VRJI3|cbmhTq$ib57$$_OfHdw}4qof(v1w)k7F~HIv>(qoUQKaqK?sdWnDO zaR05Yqh#J;>T$w1n2IyeUjqmuB*$!GByB%Lj(neFhoyN77Jg2^4!Cz#oTYs&U44NQ zEC|(uggE|CZ>KOH2JWj9!WrhzdxiWlTi>`2=yJN310}qzbbR4i_Xxq`EwKgXAGr?+ z&E`*9_RQ+Xk~Q_bKkvyawAW@(s(`t#T>_kU-@wP>zkUB{V?KP5l&+)-C8Hnn#)#U2 zth^tMQ`Y?}Tr+J0Xp%Sw>xF++i5FOZ$FzF?73JXS&a6KV2_^b~;|GaOzkb3(@fdgo z<7zJVF6F;to=9otJWCRDSl$eCCz_S|QH;BEF;h;O6WU4ei?q$b>95vVS*RqG*-Q8! zd7ya#2!xvi=h_A$K7}I;spZYn#3zhSb>v{R>BYCPI)rFIJ~kVgWKczK##nGh8p`&8 z0;m^Fk`1ni8og4$GO;Z!5}Yaerf^^93)NkvNuHitRlLqywC_LUd{FOL_5RHE(D6D8 z@;)5SB7TS*kD6(Asqh%6c7F_}{bxhRLuZ(7H`IbDVy4e4eC`xYEgJmBuUqPhsG2*g zeRdU4=#??ZU0oSy2lcQiUwKarE4m%h@`F%`3zin%d<5#8b(enEEbfAQzYB2%S=SM8 zjzMCPI67%RJ>HH33hMjnHt<}w-c-MSrU~@+13B>Tb`Vw(M<_8*iW1&dnZ>Tzz50 zt^%@pvL#up3d_bQqMUn61zICj$eMEIJCUNB5*!~(g+iTk`A|L*#8I^2DhT}f$XZi* z%+VxF!S?46o#xKW#{~F#)GrE`GOsvymw3pjn#yJFD+dm-syyxkh4%^31LaSOYr2Ed zY6a#_Ss^COjY^RrYvp=_?M{_T7MMRRQN?FgSjodO|B;=4ZO4j0SXMR4!Knx0#^H~9 zd}vPI8OWSLWpp#OTlYtiQ9)Kzs*a@}+fbyJdg_KQ{oQ0EZbT^iuIR!zmR2s`76g9!xT!eA*~(vf zWJgAY|yZE}Hu+j1Y)GPyEEgq&t*eyg*}^-tZj?z;tW zzE9C70nB_)M^(;|b8r8R{0vO0{LY{AN=A~2gpW;>H`?P74P#)-K#%AT`JstqL`8JP zqH{9{qFJ!(dwZuSOcQDZ6%^1uUhLsN<&y?$U{D;8z+CEnSn=(;LkooWq`ge-h+D3r z3iby5Lu3Am10jni#_yx4I>C!&VkL#DFaIKzw_JkWAx;gA*?*ULm2Bqyv3!KcbG%S5 zhXYp6>VNGQefME&Z(GykgT0H>j!{=V%;X8Vb04%vUh)t=^qhtQ-#&F5o3#%y#=8Kt ziW=n&oIaCbT49C~WUBq5Zja2(V43n9l!1X0CdntMr{G0tZZpiI z6%d((29*H2#*R)m8zZv!P1hu7YpO0+jn+=0Y1oZ~vW1Z_zd@_dT&7VT^?6z#`aKH8 z*FUDr_M3L#?4AoFBQ`vDFvmt9LVs(35lm;DKJgFHOxQ3(yAG$@$NY_`~8eVCDLW zX!y79o&2446D^$>eFe0qql%H>b7hIN!Bc$P@~b(N$36HQk4ZP~!5M@VJ2tYy;TGci z-X9L6>RD$k>PO`)(Y2|)T#_`4#j8&%Ys8D&yUT_&HK1H68jH@{*G4NKo$9EUXg5{^ zeNVRhFoI~bR`b4C%pk#2pSueyZlEo|VFC;J4pq3gBW_T@Hn{d)v!{>vf6!eD#4D-O zcF#>G+N|@i$^f905+I2psfpwxap2qRu&FLZ_KhA(4#)UF*7PrcKKT33dsMZ(Rq{7R zpE5;gR}77B<(!L zVCWS|lPQ9~9U~VJ>ZenKrNN#87YLcAa<76v3u(%@a;Y(KATn2pn--E(z?p5Nzgo3Z zr%Y+s_vcK&cD6O$=d#%x)%Q6vL`VXKX#%b0{JRI9f9`Du5+UnnO>~ftc~PB;VD(ngsIv#OKgb#7R+(eX4Y-2)+pRAdob}!>5#1;v)mk&=^%P;}ihe52}A4uRA0|daBeCLJ;Ic zihuERo!}^7&fNr-1Axn_skO(nyT_W7*#A3^AGgl!yxyOlR+eSD=ZOQdz5b^H>ob~* zTQ+1DpVH)Ywfi9hr029ra{cojU)$wul2PZ8Rkwl|1;Z@yBVjhJfE(W7QBF~z_FB0E zNT(8rV=(_n{E{%5$_N`|sdOr2LVc;Eoy%EqQ^BaFwMY4fwLw^t6!*OlMK>TFTS5fw zX-uWuDp$%V=i`F7IW-W6=a5aDZ-cF(Lwa4oiaDdE+DKfR;SFj0hZx;7nzWn* z4M`Y2IM@Mav43l|{#YDj5fE#^%2wkNjI^u+y}?wzTySsQbEAaK3md-$tS1rZU&Fa* z!s$O+n<&a{Ese!Q&!7Qa>$WjNTp_vwY2&5kLP>-@gr5U0$kwv{P1opQH)IMj!_G{E&0Lf??fl0Jdp zdYZ|R%7pRZGFJ*bnjomYgpovMf!z|QMim(Ru3nn+*|}=FkQ`xuVJxQ-9tG|UW}d>x zx!}pfx$Zh|mnvS%+5gcuUZ4YT!7mm0_mI9L=X{V$!T5;T|Xl6l_&Prro&bW&=*5B(&wa)Y#hW* zr#rZR44~Flg7g-a&ChRm?7OntXU}*HA{}xejzEQ_2Rjb>M6mw9RDeO;r^nl>1VRl$ z0~g3w*9bH>^_q|{LsVN>P)@{FSO4$@g32x+u)WX#ePBP^oCtm)W4wvK%gi>lHbJzU zT%D$Lq)%$gV^Oh^paYwT1J!~s`)Nraus2ZT0-g~GAR0l9-Jlq>bOatc>a-{Ue+zRb zUv@5W`cNA~jSXyv!w`EyeHW$xTZ3$Se{$H6O@CB!7a`A}vApKeIOti4F z58F%tdKg%+(`9o)#Kc*QY-Bb3kyjBikZk$3**N7#IbF2WSR=xx@KY;te-ZG{aRqDP0{Wchli&V4o20 zv6H_lx9CDm{i&%hwg+42_ty|daaOt!5i-Og^b&8w?}5dFv>Tbb8e?lZa8K+k`Q92X zVkaDdAutFq_VvMS3+pu5I-;V+7hr{DL)JZUtirD=o?`L{M{h!?A+17~pzq(<+7PYx z<@q9sM8AfHD+1A;kGBwGvCKegqmBu<<99sXHhQ;sPnlhso*6B**_@Rhq0C`19G2zE z>n1d$V_bX>Bhldr^sDxBFN$LD(~Lyr>77_{`t>=bZ}$X43V2ler)F0lVbcLeiCmeE9x%KosUrX7u>wTv|=^Qx;T9?6sv2gd3n`Dw!xC(KnR3nyeF zI0f0X_W<((uE<)wFCf)LrU`Ev3Ag8O_NH&g15TrIwfq;)9%PHeqPl|)DiOMI;2fWD zZuHqlG54?c8t1|3W~4~eC5!iOGjjivF3rcTJ8?gRf9ADVPn9(1i4fB(Triu{@0jy5 z4sBn4x>b6%^R~^X5NL&O>QuvKQCj>FgPv%W+w64khDwkmX7XV`E<01|!9E;muU`bU zy*)%6#z|%Nc>QTfm6oBPsdyUp59v~qoR(}}XJaiGA}Y*(FVk{@n69uZrj|h^M?8|n z4=mI}2@8~Sb1A}#qs)!%Ky5%6d@>&4P9~?M)yw*jy0QcvUA{7GaS2h|mY^A=nv#QlC22ClWz9nBFLX9V?Z&`?8O>&=P z{0Fb=0$#Zv{u*ZxHR+#UoQ+De5SfizoQsMK0*gc%s^=61J)UCxc1c!7uFMWcSWT2O zO(P^kQZ5+xQ)?t=xQIq@$je}?aE09fpMiZgUe!N;AcA(#T?^ox!yWP$3YzTyQIx~z41q`=di;3Z=svz+b(k6^1(Lj@Mp zvxw+u!-15o-twfD;EE;4 zZ6g1x{21te)xmy5jv=(jdB9bww(V$Vko0^)O7(?pP zR8Zi`8Yvc^Nk>*?ArG)qLF4S;70b|J1!vX*8Zm&RpY@w4%|q321!w4Xx0#p<)+g!v zV*h4G_r6{=pgUGrc$=JCpY>}RYWcnV?Tvp`JGi*`LMBRh;}__x zv)h}HeT`)RIY7eVoW>S4RAdRr#|U?jowU^9Hq>5Yu)2W^P9z|}fBXVHgJ6pF|A%0l z)xeZw;y>$}<+e~0HuRQV^tG#`C>JsWLXMpD_{?Am#l=50gt3Xm_eR_3hcm1;6vD|W)k|-e6 zpo7xlL2)N38!9>o%604(O3yj%zA7f0qbA0Q^2UuxI{w-gR8@X|Wo6P9-QuH$dTD~0 zSVb00Y5#Kayu01uv{ui+gw`zB&h%&49k+LFmh>okGXs}$H`z7MASlAb>iL<8;LJVj zEWZYLksDPTQJcQ^O8B2ftL|M+DK_)Dr-hsMp`I$cvkGCg4|(+B(kvDCPs*uAB^=!P z51#tdc7_cv<{(^z$bVU0@UfT5g{#>*?9qJ7&+wLF5y|SQEcAl;J88@&M zQ-URi+0L1SXJ1#cZ<(Z4wE<7xqRNaTQPanAn~-uT49bT8!`YsPD4${R12_o8+Hj($~Y3ywJhV-pvs?RR_c|j z!StA~8s{q>jdepqpF&(LrPrFx!mHUIAKr>S_zzZ!0p3SJ*r3QVO`~;yhp`?723{qp{NepKmE+U(Wl!D((x zJ(Ap@QQ|AOmbT8{HQUhCLgSQ)2^+NHkNYEHHCD%zK-VqXfXTg0;}kGNL#^vQiRoe2 zfE8KI+BgwAgcODERq_EW?R52VbqrDrL59AB#fgihZNvI2<>%<#`RFGIUEg8cvfzy9 z+NfwEQET7Ol80(T|IwYAOatFO!7(##DpkQ)S!rek(Wjw1m>ooP$9}*E*_?-8!$c)} zmb@Tc6bLlwtu&*7yT@!5s9fHsKt^NQQ>z9Q-8LAOZD}l4mKoz=gepO zEN;RUM?u1O^v_8*7iTmSl6?;p=u1q)yLk7YS-u7kIOZ$}6}rYrIGT|wO@cxWcvq3lV9WW9t}ZKD*Yz{09Xwl7S~V->OY@yu6lV(X<_`VTuo|aU8QGsm%`HQO}$eddy#dYhJqEFv!1)3G_zdki>jYy<3!st7RxODIA6oZ%`g^HDvChfa@{$r{jyFhz29pz-eWP^}d zw66F56tb#v_cUSPVFt6@318t?WrK=sMpTc#I1=@v{Ckj3FzvysvTp8tUNvxlu&$Hb zPLFIi@5xL$K@^dh4M@ITo5iM02MyKcT_$Uw^Rg%vSKE7zYly>vwieMm&@EacHIA^0 zT$yTmRk8U+my`u=SkzOEb3+1X-+VV3YjFgiF?YP+7FsHrvOwg!(ET;bfAkX%wUe5C zQ272!A_ zhBtb!jaY9Sx~W~0-I#S&)MJq&LqiuX<^+|Ns4KLdk!%xEjK6(Q{CV%8K9IVs z(G9Ro)q2Ohg0};l3%sX11&_TAe}L=hy^q|@h9f4hq}*fgtzlDsBQy=!b$q8+x+n~S ze`w_-+#{LIZv$CRHAln|zzi!El(;DJ3Xv`x-gQt?01A?T$~ijU7PsQPn0s(Yg>6Wn z8w$Iqw#uAN+6os7F!iFFT8Z>ii8wSXeG~*lqmOVYr9RzSVW9-9*wgGn#MvwpfcVMm zRHvZkHv~9e9t-<82D#z|5)z^){}Qf5*bOXNkNX{%X@zN-z+=UTr!7`?G9yg)Db_wk z`qyFfnx>vg=jZvq9|?lKHlW>+M?1Vy^1=j`g|?HdnUuc$=2M?_t2o_(z^6)&aVh$gw$)y$vEWlw^a&TiJwn3!`G-@0CLV@Qc zn9sTxur`o#Wp(pcXwZh_uQRqQ@0OPrLTip0s!N^6b2MK;Bog~(q8^b!!gvT~#IlBG zaOReFjihOBOwM5zH7*$1WU3L2HqDpu6-) z*9@A70otL_k0(i;pg&r|_a>X=|D?-?GP69@<$Swd{yooN92SlY#HsSKLLC#ZsQ-|> z*_v&5dPW+kHBO{?)wDK8VmuBbR?4Da=F0ZN)_h%5oDBM!4?2uwQrlu)lY;M_jWDI> zJyH?Wld*S??o^zBN2wvG_ZCaLt94TC42Adv^neITwJj~!m{%m#$akRFwXuVew8ug= z(WTbCiN5bc(O4{+UQ`aOm%SCl+v?LH z1ub~aOknf)>)9EJu!F$lLI_+M98>ciS}2kYGQLWhaCno!W`Wx0Jq5+8+)-<Vw;CSK}WakkBIcno1P(inE5LOdj7!rFbx2 z@S152s_91ou2Ii2OzZ;)=gT!&(n!?$YDH^iAGjVxh3^z4G)Pcc^L7a`_2j6Su$pk} z3KxgZZI*pdUON9*r>_JJ+{~@x3Dc6R*g9b!oWwRe^Y({B>d5~o8J>qk$K_l@Fq*R1 zM@omx$BvmY-8?tipg9Cp%Fi#(iy}2FDT(h~1%g%cjbwjm_dP==^Gw%6iAU870UH-= zeq$Jii;o};q#mU^@m%G|Bh>DBKGD2`FauG~ITFtb(k#&KBoKtLVp8(W`TET<4y+cc;NeoK6;K&LJZ$Y|nYt z)ZcV4xDR0Jzd3hB+^;3Q#f=L@A;G~eR4OuT>QUf*s0oxWPW~t8WBYN+0e#7E*yMu0 zKk8&&se~OY{fd1vb6kSHo<{sRUN|Zs*{L8#Bf*OboI1mr~=e3E@BzLG81}xSzrD(&iSFm)ow})E`ea$HW_*g}N8EFe=-8 zHrLpToSBkj15eZ+1TIB1Rg#%^xJAxcB0O&87_fsvLUkN84=z~-lo#s5+Y2v5msIF> z(NtB$NW>_Y>) zPcnUdQE4#lPtdugBHc#@t*l}o|9gy(k+ax|)9QiT$}z)b%1lrSh4-)HXIE1lPC^$g z6o4rSD@a8{xvd|!Evx!!8$5k>*ES%q)4*QGAO;MnYO-gokxBebvK3)r`ZH{ll34FX zf}8|WAt(s6snjmnjFZsVPct10eg_gjWIdvfqn1Su{F_x@Jfc@VQ9x_nZV ze3lf^)sq4Yo%|-C(m|?q=z?!Y9q7-L<29*v9@~;%GD-B+S)5MyiP|H7Mh^V19B<57 zr9%Y2RjYkAqoo6X-!p7&&{L}KRKa4P);ed0<8~KCzJFE7i|8Dv=BBd02M|(#PLhq%tVVBjHe0a#<)G_mhzaJWhciSepkpH)t#=x*!p$pebcnvE#A(;&ARC z&GljGdI+>0{^w0Hp#8K`p-X4FUXbTj>;?n2=Ej(zLG-WQ;%D!w1((HuGSEZ90(#6$ z-RU0CPp$JyEMB(|cXW;Ae-vzj00?XcAMEb6hZcEB(Pd z{KOC4TRt0dai-%REm7iOJ)mI1YeA2cgDIo7r^gYG9JLu{M8^eKgD7bXwq@m$9I^KK z>e_@Rj-tDpRnxpeR*%kZbU^X~rXnJ4AP!556{Q65;Cm+uIOCZF&|75E1d?G_bi5vz z0ZT7NRvha|EoQ8RmPq}f@b$pkdh!cbhOA6#0+$o-2=*A^T(cNGaKLt6(6~f0C3Rw= zfOw3=DuldI)b2z`<-|z8z$d|XCG}ZrV6LS?{=){5cbB}6O_*Ny`o9GaSdP_o_yKeE<9rOn=oRm7Y ztxNP*JukW=HZ)RV_hiRM>p`st`#uPCl2{LO;!`!+u4Ft%iLcICHFb+n?!Ug#^e+*k z{?7ds4Kf!1`>g_STdrk;yY8eq{gK`8?!jTFB*X0 zq+m&m<0D^L{VEUWOt05A$0Z@HK~yJ|6+*nTcTSh|JXFjXV`68QTF_bh&duRGw#iAv z|K9nDhn(L|jGg7Z4GeCR{pyhNfPMg)1_Fn!%JfFNwNmaFu<>Eb;boi)`{q0AIvOHD z3z?*j0bYDg8mg<)iTFz8xT1L%#guqr6+vKrC0~ouWb^hXvYp2Q$!+# zyKC$bLh=l6tGQabiEDM|K zWQX^i?G*(fY0oYA`|^QN2*((K-|eJuvj_SB)n&O_f@g0K{6+?neHm5)|XU&0lu7+6nfM$RcSLR0DL z<)~Yb#Pq+4AY!eh>S|83AT7#}-@U6_!!vwSAN4N4zZv17T4VDQO>XZ`I+Pf`dE39j zEVDLQt05hjU~t`)Q5gr;XbvjWOfVQ67QC7*Rr!fc@`~3C{UGaQ2%dPJz z^)4d`&oOUw64JuQ8KrI@31{3vX}%TK>wCImu4UL~>~72*1PJ?lG#y_aQ5-OG(+o&p zJyNdbctmZuKnS;bsr;aZ|1#EEF;3!TtFVN&bUvnMe4-B{BCB$K>qV(5wA0KdToT(9 zXmbxXzn>Hm>F)$8V?j#UyQoMC2*N-K>kq{zhze-JF#Od1NdCYd}nTM=7efC;6g)lQ^KiSq7 z`0$4ATraS*PlIeqkNkjr6>i;ptg)dkOkr#w|03s(<9;MyBTE~ zw7Xi*LvSV-qwP(nne}3A;g`ZY`JU7A_2hiD%(^ zIHoI!@Xe6Tx|(pQ7$m zPCMzvFn*=S;F&{=$3$=GqBTEXJsAM1EE9G7!rir+1CV z{Zwm9PSht2Vcwl0aS+`>C{}1dD5dL|Gyb%f(VZcyIvXqW5-U zat4dLRu7D4FH%1{+!c9MiELpb%xgh+<;0Lt!-pasiS=7S*EAwLy(y|x?OKo*B)WP= zUsN+zek}u8%e#8cyN&m@H~<)Gp={qmNllwi)`e6btry*94ty|%f*e|b2vt#A22@f$ zi*9m~(gj`Q=ni5X?6H4B1=Z7F)ZC;O`N;Q$?DEXPJfSlBXSpv^yfA%{67UrrT{u(WG_^05D>P2HL3p>~M!l=q^p;lndX1 z&Hf{KEGw?}bxB7gMhOsNIXh7C`uAVte5Jr8o*+%gYm>!FYht)NCZ#LTp9722 z8pN=p$MiMj9pI`%t7H%>qzOXqy0^dmrvG;364p?fCTlv==6ya6o0ZqUwto9OB%~&o zh=KH0r1$8D6<(i&-2`Ss*mlCB{YzL02Bu(KKXriD#3}g;9!=#Y_O5!t1@rN2?(J3! zQD(lG?3}`v;_V3?s2Hjoo*-hefM`A_A5TyYL9Z7?c^1kS=@VuO1ZY9x9mfD3W}|E^ zQj80H14wf_sf6V*5)bGeSWVCyx6gIeEXp$%m7Flgf9c+?8FBzB_1=>|^+e_P$Lkth zTM;k`^+{%M8rA0f=2<-#Y_$yE9-K(g-V)ZxNXT<-{OkwL0_C$9xm8VM2lJ{t@o^$C zyL2p{duW}2Nis;ARP%H@NsI3O<4NGXlMS(c5B5|ZE^QHx^3`mp>JxEb@-+5*ZD8RvQ$dC7ZHwL1LI%})o zRgUb5;>yGU16`qnAw;`tHe**$REUAT_*3^+?l6S|5r+Td*2M5U&;2;q%g~ks^2hoZ z$Q$N&JYlI6+q7IQ?$_wV3~3Bi;+adtiOB9q4i?v>cqQ7?sH}-*XAMyy4w3t{t24_! z#}5M{QE>yHJgGIyK&QUv!%;)nnk2V=`zDR08f)j5$L`y1Nzc!3P*bKlDgGd!(KeYnR<7UJ->#}SFxrp~*Xv6aTpp1gW z_g%x99!V!@HL#EAv*Zcb8grgjLHgj7o(^T^TjCNq%7zTC?j%_Kg$a7CRNmSKbA1th zkwo)LVa|&Gc9JebQqN;Q#2g z>DfZfs^hII7w^+l#ZEB`6t{E1Z^H&b8W97QXw6PrHGeAX(nhlE&I5Fel}TosF6 zH`F4N*=OOXHR6@nOe|%|A+Pz}JuD6k%xkT)ZPGqvj)HJO)~c7QIC$h@d|x7?9`bDd zJgK!;&6W|+i_dKa&wSb)<56Oz^# z_oM5c@YQLPdD^!w;sM>7!+Sdyh~?>AEXG76bJx4K*GPYb24(iLr-v! z=YZY)r|J{gU9OWPD;~%6fxBO@x#TrD^qNVvz(*Lv%)TZzL@i|`qY2(=JGk6Zm@YV9 z_pyZC>f+_>mNBuDz+1$JN>NxX>PM^n({}N^Qm2$`bRL8UA6yu@1~>5gyGRCyl=-qTC9bzv*@UBHmKzU(SqD!W9C1GMt2Bns0q+k35T3z zj#I9tD_JAT>Bq#ixym5+%wqkuW@d(&vRdn`|0491oNdX@^Nl8d20(F(K3qQL5oD2h zzGi^Z_AMw&Y>k{-9?=!B-}_guN~_)y>9|2X!~e3uhOh=(ucRoGKqt|j6rjTxW%b&*R^&34w0qCk1WyJ4@yY4wYWwk##N zJdP8j4^nawONnCv1yt1yUy)gaWUTj`qewAIF6#LB4)EDc24E3Na&ME9h43I%i#PEp zk}V&hY6%N4z7Q_;PhYpyjKF1Z>@MPr$!ttm_WDswFvIDB~hvx6hTPfkLNG^{YMa0kOJ#} z4M3<%g50Y^HDaM1TCl*AbvkH@+$OpjNJ>9ChOQ4-6D{a$~j#sJVdI&hv=D4+;-SXW99|1m@e zY$JKCHI>E4CJ(b01RdTMUAS>}i3`@)ouS{$wH$`S6^*JTg1>79`y2HUsuT`qf4xQ_ zk8QnU<`e~@?pE&RH~GLX$>5IL_x8(!dCcSXFr8L0K+;epwuu&(W!Q}xrSwPqOmhc9 zoR5DHw3ag-;{OaYHM}(Ykmo5M^SbdFV|XFfn@6 zyqGO=UR+OpQk<0_DWnVcvVF|MjFhkm^lw>Xktzm&2?0EFgF>NP4?^^GJS2?1k#pbi z>LICsq7SD#3khu;Rl zH4oUZsruY8cG0azfaG-G+DmtfajTk+*K3in+j!E3_hB2{G*>cF?$iIWY-)LsoF8lF zLm&lDW`odH;UQ!6)|QdWQ9KifmnMkXeAErg-@<*(EDk6mAz!{-VpwdaMXn#LHB;Lx zrg7vEURl1?AS%SoOdH@h?*a^8S{wNuGGo`K4;`4*IuG{D{MNLG#dg>}au4@fE5B z{^>tMFH_6vTm+8hL+ilVze>Tp`4QDK+(C~1Uh|BAM@9jjsVpthkblm6S$L|umQo7y z7#|Bk!POEJ8sSc?_$pTZW;7w+A8G=H(m235T&F+GD{pD%rwTUlsdrf{M2m9C!gMl7 zb{QT?5aveTf}5>QKp@xC^<2Cql+kFfDaFkjhD(ScZtDgVwH4JvDkQ%0WN!4F zVEEMiOTZ3j4H+hfrN7}8@F!TPI_)Q0b59vSST^?kU^fYLJh^t7GX0o&Q?u$im?8PH zm*fDp?PtVxj~-3PF7#B{3D?V@ksexLQ@lPkX{O5a&OwB6?(=ojdT};l;|Q)m1>ONP zl3#JD2(v@Y=PyEjoF4v~K$%!E*^OP=bre6YMJI(veL)VCAnp;+9?bw&w^`;`t1PBO z6pa5#d*%0&)p#1<7T6>R9&pYYgokV8@O;M*AYTJ$3M=|*(h7i?6xsF$*l~Nf-Cmi)Xjk5bw%qtzY;?0alwlx z)yvto=;_9J|2T+;a`JIXL{$%*lg||xL}Dt%3V>;mZc8vuKQFaqo@EC%o4Q|t*}o>TW-SAQa}j)I;KGjum5VQ2RJEUVZU9S}%*9qqeUgZYB>dr(`{^)& z$D)BjNkL9RUy7R$;@sKayPOIPKnTBvp_G)&o)~$2dwB zl}+?UR`+8c3w`(0zGF!kguL+P|fpr&0YhIc_rKp5p+}qNL&9ZXzblP1s_{JM1K8we5`3#fv zKmy?H<)E&S1BIwB;&T2MeJiFp5P(crs@NiZFTV^xNcz4&Ofr^frK<}bGn>!mPAfrL zAtRx?)7H`by;b~@lFLhSIg9IZ-S>AxQZJblZb8l+S1bwA80;H~py~b|LD~;?0yylN zFt=J%aJ=aH2GD@}C(_sefMuN{{jDar+zC(nQqAN+Xv*EZDq`!VGI6j7wx2$9{;<@Y zo@`K-ir&`g-Yll@pJxD23XJ8#H_Y%;>vHmkckY1bvY``FaORJ27m#4ftg>?N*|o!H zSKlqmS~dAD`|oadT_HD1Hk&^KWyyrG5}DC!0C6|RSAs-;;ejM@menV^HuojQ9DEzw zqiR06X?XWhM&fkS{O?#}QytgPifYraxx2bUzl&=G(y{2#azETF0j4jUePyAan@w;g z5lph-0S&Ck<#As&HMzUP-}4?CdgLtMWL=gL>Rc3apz*w^ZZL{R@JpLa z#jw5=G8^6uIcjZAJ84X`A6D?8v5YBPhg9-gQ3D`wkT_-s%-7zQK!WbIhbo5bW(l`S z{!WsK2i`TrZjmMZ82Z_dr>3WCGP=_okhzL%pFg!0fr0MVRlz}G{pn0y*Kpm&N-IKl z=XC7?fDL?ej_}j4AiKzd2HjR<%bePwsgk^mWdqG!F zM`Ce~S*r1e;JB+0e@>{Q;xbsU&l14+luBVX+%2_{`44@O)5imfu3RFFU@-J?Q2_N_ z={IbyWdB7qOGgOG+I#8m%O}fzJf_k(RCL39_;I&K>EJ^HJ3&{&+M&y2u`vx2MLM9Z zYsV&HP|uWFFpc(+NuJe&4h-W*2!EkecpIoJyb@1-Qya?r2{quH73%grvLK!;fp4U> zYXoi4kY+~QOL2ZnKi1)>z^6rphNlNfKi+_GpC(c9=&B+xXgruzPJTI1n| z4fOh^rfjy$`21O{*|5zOq&IVJaLIJ@AIcY5_PxG>AxdA*^ z>l+S-=|Wh8YrJyEMlwPdY8jxj@f?<%5ebXIp6P!Wj>_sJ8_p6}9W=gRU@X|6VRP2_ zuN5YQ*X+Q)exazkE6gBgZt6&RBkB}3g$h$r>l|vk9rkVBIMq=t|S_mxx z5$$jTU{ty?EDl5;jqWZvtH9KV5$^{&N4ahcBAWAw0sFWuQlLUiv!3-!40sAVDXvPu zvZKHaI0s3b+I&cXx>F4ec#N!@Js+yUGE~Y`;qOL*VbF*KQ?N9`Bbt!obDRxEVdcO= zhe|s-`K!K6x-WeQo4^ycfC+_{WNl^57(xKwc1>r$1bSb7I$UoZ5?j8~$mIz| zO|I?Ocg1hELkZ&U$y#>B>)nr=38SSu!HAy$R}upq zVAxl>#{Al=0=}z>`3PgZLJ{}B(?u(#G?5s&vw5@?p#d8Cbdd;@vh%Xa3OY|hiWc{t zzbA5g|I@in^^Rz@kt6TxU47We+6Obq97=lfa%8hLE>!Hq+3xDv{)-$TlTwv@E&f&o z-B&mAR2<@Lz^ZX)-E%`1K6cw+v}R(*bO@0j)l8|-G&Ab3EDDI)_sWs>U!HRI82K5U zg!oM1>qRN5@}~V{`3wFD9Kzli-46m5WpFdpGG}|lyAfbd!%Zn8euP+2Lw+SsJ=EYJ zdHv2=N%+xI$}MK><$uT&2Emp<@?obN`Cga)Vpj#sZzfBoKr?b6(;h3bVCPoahtsrL za|Fr4XyX`k*+z6R^z^I53cO}cBVUqy3W43sdG514z>$H_c{$Q)UEIN3VYyz1GIMay zsC~82{Pea}pC5|s^sq^?8FZ@VrYseI^N6nzaB zZJbojWRs3Nq^bMaLqR(2Qr@OTX;%DCuPR7p)c^;);8iBEn8z+B_C{U+L zUu;mm+*l=EeX6r8ZLRAda17-1JxzII~hjA-PT@e7{EbaQ;E|S`#KQL4U7a#&#So&Y(;D-?RPgH*bs{T z2fcpRrfY!SJ}juQILxaMX^&Vv633ju3hO;y@nyyd%S#C)r&b*uOxFgz;&O1Ve(9>0 zZS2cc3tdGzB|TCPNH65jUWJFYr*JQv8Htreb^!h-|M+uRx|otqb{dc!yc@1Wwqu4& zJc^G#1C>xP*bjeiw&}hu$yMib)_2^zXH+pqFh=2|`16oYXj)R@=iAx+_BJZP+ckn| z|M}`u|IHyRCVAG3bmyLh8U*$2i5B(O@rm)XTSr36k}h!eKKvkuaO^M^%!p(YSn&-P zki^>u_2V=#5S*lHO6F{UNe3e#*73_q(Y3c@luQcFkn&?OPnK+5KB^EP*0#R-KZCre z2srFGHR8WDS3e$X#Oqylm&K#G z28K@{t9{OWcv;0CbAk44w9F92P2+*Dyf;E9Ur`>a$AKWji8b+bI_Lx>?~8EZbl->7 zJTfwU1J~MZizST_qrxZLqx|1+q(QCP&Jslwp_UfdREeH=ek2i3f* zs}-)=@g@>Z)@(JwZYNEsaZw(ws5K@A7z5a@o{I-C5c@|30?Z1%S3?yFdbKbMraY+0 z^=RSy(ctGqY_vqS(JL@s7l}a35RaFN^Yl_x#EwSgBnv8CguzazT2rXb#y_H}I*(E9 zOr|tyj2N3XNkBBC~79VZJZLKc%d=KGD+NJ3#bTlebF zZ)e#9a_v;%t3ROJOBv?l{$FKeOsQN_HnU|YKII2c?d&hf|3@eG{|gjxg$F!%OS6}r}XIgDDr z>jG^tFp|9D2O$=gaApAD1jVT22yF;yHR7>@12@Y51~-7!8pSdEny`vXSn~i*r2d}Z zV8=ZyQnfkoq=-2;r6!7_<}uFmp;U9{X*lnqt5Q%JMa(Ijw)Eb@{(2_&dTs}{*gtn* zHLhxq*0?wAb6Hf`42KSZ?`g->j{tO663?M_=tcFKPvTvQiLs07oC+QQVLN8MwbuWm z|5Cy=fdvRF`BK_+(RLHMC`_@jf?G~`IU@O%kq1xt@+Bp)KH3Ld0ekvBm69F!Lh4NQx>3Oz6H3O zBg)FS-Mp4)HA7=Cj;~Xg;&$kX04Wi0)s($>|MrMVJ(<~l->5T^qQEjja|qN`T^N(f zelz1y$G0S6Y4oc$<0257;Jrv?Fr5DDKYt=;%!gWWu+bTU9J29q($+uk<1Z!iiy=Sf!rm9O|Pg8`v-PUYA`%}J2t8K zu7LyT8Qjaljs`~YLx-uih3t|I z-FQ`*`y6J44OuY&yxE((`~0#tJT#9=wsf2_Z)t2kXnySLSZej6y98+4jPL}y_xDiH zV7f(f4=gX2Sj?in{$BY+1B;nfuutL8rJvFKl|)McB*09O!L^y^UoX#HPh@UXQ4BR- zsCy@%eX)?j-B9ldZ|x;(^>4wK>eWg0Kw!hW4T2S=_x_`&=7qXpTH)veAxbM89b}xj}f1$a{fdaBkxK(v~qXFDH=l z#O=Mc4v~G(>^$ku@&~L`M4BW)%PNL27`kOyK>%65JpqbQ<zu$YznpLI!WUH6902TI4~WW#HUNjMHBhA<4Lk!d8*X7;89tI_r@< z4Qe0O#@AMj({>!4?LD@Vac*$6GU*`hHvU$Un5W{8N6qb#gmp)(d_2uH}g!s**{S5VX>0VXB{Pl~{LmlX2Qz60ut zCCixSy=VV2{fd1N;j)pnptd|Lvu-tEhP*cw_&W`RgK2iKs*g{~x>Wu`$hw-!b0F_v8y~pIT1Sw)|M7=TWXXpx*( zJ6dALDLzTZBPRWx(6CR`vZ<&{W>ivjYrkW5NjsymkB6PKj|V)CuHg=vhLBiuinFP! z<|o&1ly?%`ao^9n-G%-rs?E&kU)0z|Zy=~%K#@DwS(3PYD~mY2{(G)m?nj#-xAU!a zso|E$vM~M(HlhObJ23r``d`)<8q3lqyJx-}nWaxxK(+1Gg#Bv($mbXupZ7b_%o6LJ zVepM)2$NyNKHJ(AvDPevD%jGYW=_f0zkaqN`ZZqMz%c^27e=0E(`t`1g~R?fyl)ta z??>_SZWU~?N=p-j)f@SuY0bw;&Nhza)initf5sIlE@Y;Wo#ma7=O*lR8CX~H8G9ss z8PjrUs-leJJvh1WTj@KhmhUY5^%JJ4SB$AT!SF3t1_?9D7D97t?QMb5!o32=0#$4pXN|7uz+jPLzj^|MV*<0Y#$<*%LSk zMl4pB*X|@k(ID+O-cl1d2Gf_vNQ-g`#maRo1fK2`=h|7qRC;n%H2{;hxq$&ju0w$| z*R*>4{Fo~#z|4>V2LG~g^B5UK`VR8ey5ziU3Z-8aMGzP=rX z-V(}!#pOr%zVEhq)jVkmH9ph$uUn33|FZXy!f+y&99&ir>YsB}$>k1=GvoqK3d$Yek}3U%h54;)O&>o^z>ab$B|Cu6L<+iDM+t^v53^uS5P>oWbfV-Let)O{+y*Ywj{OicnaAu(-83MZ(h zI)6fIe%Ef*LYJ*ot|mO*Kd=2AZPV+7t!>dtg&Oynq|iwF_Ws7|VRzzIhru>PwBy&= zZ9W_Haz6g0NBBP)ZbS8F{*acNQr@fkMSYX%!$9F*&8<7>PBz6j^k&{m$ST94Ix6we z=m7^e%0jAyiY}N2%h(7p1b8aAV0p-hj3 zf}ru?9*qn42Yj;-$Xcn)$j~lYaYalp@DSkk4Gj^rgFtoexg-SRy0g;&S8j&( zu)eT^a_mPB$I|AphVlR-zt^$sEXBoE(v zv?+gQDmZ!YREm^n;tR0UvZUnuJLczELA~u_&QKahl9G*prUiPi&PbfFWa{9hcmKhH znS1+mQ~E)gEVR4QCZT|67pjjGQnp>-XLWlDKXoiu1>X5xCG9 zuga&i%Ee-tOI+UMIb1)bE|AjfT*M-(`{eEz}_~{>Fm9Bg(&A4u`{`1hfa*pGbf&hivCFJs|yp6d{X{60LQl1d5 zknnUb#$ExL1J#IG{TqN*3Ir$F1W~ZJdS!X2;%$Gjx;H?eyRQ{SBVQuWENpsMc5k>D z{0MolZgIeidb$^mg3IZZ#6vgGSnce09wPAYe4XoL zFnh9lhTHFwdD)yC8upkb7@~tk2-F>f)F^EqwI8dO$qgTaG#H~GV_S&1n`F1;dj?ztePM+~S0*Cty}# za$VoFqz|wmf}3*+5h5*RqW>w187NOr-DC<#HE=MWK}`&Mrpsf4(Run`$(wEo5{Jzm zIo3c35B+(_%Xg1@QbNG8$e=3!ykHZ&K}yDp2(X`ZhoN;sOFH-WggK>%B`r^LPB15u z>XUF>wd=4D+7GI;Kebh4Wv;dO3gn-L0&ioA3u}UfJZj%)Odjc6(3#~7{A2shEo0Sv zihUF!y>VW7KSY(~Y*>_pL1j{uQ0&tx7Kqz%x#YIL#XLwiVlsKY9oxxyH$Y_|Vnwvt zB=0lv1xfEV7Z(rQWwhK^!^VPF2=X9TTqO=hb*E3BqyYDMxeD)3P~*3fNO0a`#~O3aZ~RmH+&-%Dnh0Gav*O8t3aG(Iut>$)29ddPaQ9 ziepOf8_+bvyNS;hILqM9)eHSjyw18PXaFiPQs%FLJQ4{n5e=5d2SV1QF2SXOrM|Og zdN}Z2*#8Okt7~2CE1&e{%$sp?(a$Lm=Hn+ELC7KBRVSu%w?&}|W-kaP@lfFGo$?6t zNmfwcx^p^{^{ZsIQ1trFjd=^LbMlNHUCeV(<%PETYkWt}^OT=x3 z`)U5p`?NlL&xog&QdZEPv@`h#(kMn=#Oxx*9(y#I3|j;l;>rmTP({qLkR?%Q$slZ* zF56oNk+NyOJOxnuAu~^I7#Y?7&YiV?)YXqcCLf_pG}D*}UA0!H1Y>r6uI}o;X^sD( zVul%esmDZ3mU;eHOa1iHV8Fg!$}#lP`z+w&9jM66@P zoRg^&8}ZB*X5Us2hzxeCL(6sePXs2FOl?)jz4(+5$|)<&&IKOot^xszU}|au6y>Mi zo}ZMGK`ihZr^3Pf5%U1y{Cbzb;en7p>K=diu-Hs3+=Kcji}LR~Iz-&1snsN3vE3a% z19m%-4YY)$TkoHVo$vq8!YDhP(kOL4+!T3y461DM1)V1W6&YYiT73j3ErOCh3u4z= z`*Qo;L;Cb@7SfN8A>4sTdgwXT-&7CbzGcZtn6dwjQZZ`HUV|4wlg%S`80ms>6}Q;l z4Ofeh=JZ#={XGq8uF=*4KDmOjf`CY*6e)mJ9j`w4el}lsOml2C(tI|`FYF#abnd0+ zea?aL)xoo`kSxYqfj5Picsx%kRq6&XcXO9Hbbo75$tx-M<#LFT=cQkBjI9kLolb6_QB7J8+B7TZJii=<47kn95_Yabs`0A zfnEIT4h1GffuGI~$=#I^1V=!m2Rl-d;E~(iJfG8{xB2VVZDfe)^-h?Md(-T|BH;2A z@*tw4vki3`yWUDc1Vatk&>eHgXO39qODIi`FRL0#{Cv?TK1vX3UsXEyV-)GFw3Y8Y zT*H0jw-wh5Xz(Mb)Q%_iRS~?v|2`}vS+}>f3(}dT)#4;GA-I-E7?icLP+kNih8JQU z$@n5_(Co#$koQ&3KTLf0Q5lt_fjA7MSR(Tf1qDREek#3Rc~%J3XzGQb>kHx3{W>_( zT1gk0SdUWm^m`vzsK6XXIHu%%%!ro|D_&vsbA5RmQ}L{{KfRr{!dKOVO<>kVR-ra1 z^>oH5*U4jEe3wSvRzKK|bt#AE(Ij{#+!vS0@Q#(d<^JP3b#PLtF_(Ed!c%H<;&%9j z<_(3L{Bj5?rH(?fe2t4JOZCfUfJU>2-#DiT$m)d-Zxi5GnZ~&7oUo~h*Tt!E{fZ&6 z?8s$!a>jRQ)C)&Vd6Um7H1Qh_Zw=AA=hwAwR{_+`R=)7r;*JiuJ=^w|ISW4GvZIp= zbmeLx1SwiR2b>X3{sC^59*^MuBqV+WFJ<)NA2wD)I&ACLAQN##YUsxLx+ZUZnqqb| zeeFka(GFV#Io81CrP%dz`SijnR3&HMgQLy;9!7@-7j1Zs40{L$8`)hw13t3p zNwREjmv#@w6xe*gt%|$6Dt>52&8H?7cN>W~*eYp5#HtPU(Pi2}b$8A8(m0&kffpw) zx-O-)z6I#rU#YFWvJMMrwvE#A-gYu3*#;d#CXDyWOyOCAZ0eS9Ik*k;XPsV@nRoIE zn%eg6cvLr=D9;|t!_rVh{^=tZYP%DG(e8E*GdrzhcawdY!P2%W9=GQrX?KR(?u|ZX$ zU1&=S(Q{fWfi)=nWC+*9pD=eloq!c*nuO#u>Wueuo-?!wGrib?Lw&^`4ttD<@CuaHBO{_|785GbdRx^q_yO>Mo}fz^=C0zk9y>`;Qq`|%=e$kKc5 z3qyVjV4G>4SSG`tYtS+4w+i!`n)PzeDaaWJO=s1ik7y3=Srqt&zzAAa{%W_Zc#U^C zUaboPGz3 zm={T0My$yF9Iufu3^rr$Y12pacER^R1DKx6VP!@|92@-;Ht89^D_K$K1VrP)OJ;a! zW}_PADy{g%54S$(tKj6>!nk2u?`ut8xZDP%&Inr{^eIgWKC@u-V?1zO0-RM|UeTNF zAazusj;_vHvMuDpn|*T5d0w8TL6g;K#q*!^muX~g`CGqO_B%e-laz_f zz$Jb7K%TP5b)8M{U!^@bXX=d`U|#;HCb{jv>B#J{cMtNacPh=OaJSlENwWc!$gFW{ z&`D=11pHMv2shawH_kz?d^6q6;F2deV|VI?1es1@i;w6+XWeXv`z1EB2$-&$>V7tTZ6Gg*U=t_r@!QcXqu^jIrW^{vqJ7e z7sJQ((c023R?l}1-Ez<6tNYfXYy+luCHN|g`fo*fS%i|&09ePkl}*S=t>7MHM*#bi ze?IYLa7SdjHe=%n%iCJfa)bR9k)i{E1eiq+e`E;Ee z<Dd9ks+S4=vP#QU(BW9@F$~$?*#Y@HC_s_BO)ZFE zF~`XruOdVt1qR&*U@3h`Fr76WpEtcSvLU8ViP+|aM9&ivPhU`R0XhF}pa=i(raL)V z7p{}ChRo$zTJnNo#*Gs%Ymz9w(ZKe};ntXxWz;I$H?h-$@~Wi(`3UABI54(Jjh!5% z_uD*gbqJu^>A(S0324TATTO^@r!TWm7)tw9De_hwOcEj-RMKN-`srJAJ2>{Bg<~8+ zYHe{Hu{kJ+mYbYVo>xxwr}P)b%0h&L%A_cA2y|lM@N>n6Y<8W~rnp^m8v^2Ki&@rc zQ|S|kL6zy3Uk75PA(wt$!Ys$H3frDfL`&8^z$7?ON0_7h+Wf8#E1OdfYq2lY*J#PB zx&MDu)-Q;>UTPvq5176m?>@|;a%&d8=wA*tqG;e{*?ioLYG&|i{40ehDjNKfWIZ@r z!3=0cl!aJ=nfxH#Vy^8qd;%7m0E$EcfB?#Ul>=R-?BNVhG+|ZlwGscrs`9*}smE&; zt5$neRF#Mo6>2P(*L)^ruZ__KSF&T#BKLiFRBVR>9}X+7rlhsjl{C;|PW#L50m1h+ zl%`aakPbzhm5G*!GLR=o#g_1Xe`%TDd;2SUI1p>m8vF9iEsIAX%93O#(Ni7mr+uV| ztI+G?-E1bwp)Wk^YC&ikETYffDQUm#-KEnOu+p3_>u^vYJR%xf zRe5#~AJ8Xy49_|9>&s(1tB1{eRzlvAcc^RM|5cB zGAa{#vt9lqm(gWaV6%w(S;;AI@kPD9O#x0`Uzt+)UpUXGU1?N@azV<(W5H5bW{cX3 zVbQC7js8)M_Rt|s3&rYm%^{OYk>x+mH9J4RtE3}#(Tu0Q6|0Wd4Th}42LChiL2qeT zNzrr9UQQlH68bO=OR@XL<_*n_$}}ii?S)k_?z+FEZ=8MWOB-|QPPt-Ttm9MPCx;{)zO>c{779uVmI8xQDorzTA0QyZWA07`kbNQ0@!H-EN?Ezef#V;88Qcj2U#jlB zTKdLKJ^udl+rxJ;bhMPU39+>kM=no0ID_^4>C8pyTZkdLQ^oewW5qWep+YX4nounM z+x9UwU!Cn^LLl8IJ(3@m6*Wcv7Rl&@a5-DGjJp4J&0Ef9oM4 zuMol3FsLuFCBNM6=`}!Upr9v(E*QZ!B*m7Rg+IIf^#Y=yk~|hjpTz)td#^FNXbxD2 z^bonG;6^IAjmM6yeC*P6lKvaeb9oC+%q?8!fGr^$m;5TpoCgqOi}&>$RJLq$98l95 zDr3vK)0N_;!^%bdUK_h>O|$p?s`+!cbWJvX%&H#qAZVow1LMB#f&+~ZruJ-e!ku)w zR~Og%h4mgi_{V_n&G7U_{0FtfU(y6>ko9)9`Ew$s2`|63lbV$Um8$uSan{D!a!~eI zcL_(AAwuvlTs-VxXWw4Z?GLLZ5xe*_9=(6YQW^DAC`NUY&cX}d{iX4+q6?R`cC?Bs zf>k3a!qYO8FYxAfEaYl`*Y1S-y0}ZO6EwZ35_&u+Ky+Q25gO@qF(^GfWVckHQ4Q^v zlva93jyB1zU&eVwPY2x-Qj7dMb3|xlQ4N)E50tw2Kx9!vNn^pi^ErQRZ$<0UGej*A zv}nuAjD*G1V;v)fFimXy$)t?ZLTN7-hVU2Ava0=J%e4KvDfop&gq^PVoR4JHxVEWe z`8kGYDXcPwglw=0(%tgxp*sB$H&kaSVkKheYD-?;n(&u%W@#!RzLkc``4{O+BZD4{ zH%E~JKcBc@EZu^=D#Pb6kC7{+BLM@li@nkv7WZm~sN_^{oJXY(zLZw_7-_ze>G&i~ zWkP`;g;KZ4N#3PQj}2cEXlOOgDI#1|KE2NJD(rsYDGG@5Uh602Qtom$y8nWgsaWv88U}fqKUG!NWLyGi3*Q(B_&)&=mJH{1JR@FaB&D6M)52|;zTfNVKGHM zyGJu5B@^rSBxV&%^9L{g+&2$#g~(Q?Dk6uAt~D_!mhgf5EWbo)X_|Naz$-!)XV$&Y z@wq^c(wZAAWO!@ZHzux3?l!N4VdRq{WUuaRX_49pttCWMY75fbu9e2fJ3sl~y4a64XiR+^q)OQo(RhSj4J2J@B43U6W_Z}qB zR(L7W1Lwrj3Cix9U|*sAs)b8vHKaT5DY!|6?z=g_#+jGKhHNMK8X0bUu602T2p;gX z!=BqfhLoL<2|wJq{8>T8TZxxRN*V@egV=rvQQ?Nzh`x$8NV9``SKW^oXG(o&tGNa6 z!`y*}J+%^Hpvy;>=i_zrm8_-Paua;Nd?vV7SSVoG}sYKwj6PB`yu+zSA zIJY&as7N=X5e{KCY_DwcKh{;VrQoj^YV~-ve8)&6Z0a6=QncuDM$)|;p5|LVoNR1s zMGQK(XFQH~cfU}!FmB-}4Jw61_`C5GiK@aU^^T#_2fFA3&nFzF#A9$k=gJ-hx3}ED z2TTni5?})3hGpj*LWbSjeAa*nr}6W5D{Dbs_vmILW30_s{Hd2~S{~(n{joxSncZNoIYu_!!f=CA z(ZgxTkPa&}vJAO;xNCgE^R7W8xRhVr&f1mQNrATbsgARG_*MDOj3k--YZVVUtk6D* zox(?m>4^C@XL+>R;C+f{$Xw5Bp{fKP_)siy97>H!2-Z|?FT%7jy zlaM3~o(qW_%gB~;7p_KOX>Pu3@uZ|ssVYa;faG%0KN{VF+!AIGCKZ5IO}+xI;UtPd zQpjD6VuikZHQk8Q_4k|cT263CFQK5J^3Ro_3?38eg z-wRq&fw7y~EYgL$kFc3!B)$XLl8q_zL7dj_@3LGXkpCx5vypP2Lds^vX17p2gKsV4 zdn&|Qlahej8r|>xmdk3`O2uwAO5_j~vl6t~o;OIA%jG&xSEfcU(+0R<92Yvctw2y$ z5ZTb_8{-&^#QF%0f;=K38<%9Ji+pe^px8`g&%8-^%aRY_U=mJ}4X>mh;3}nQ#-Wj1 z-MFs$#km+UfiiBFL@L@?&7KWc;NxF=1lY)E^`fi{De!*(GW$~+!sD)`CwxvSqapIramj-U%6&nU#-XSKi}Neq7G_d#oQ*&RDcw@(4lAYv6BpBAvaFbM?! z4<%YR>88f-=? zMP?W)YtpzN8vn{AY5lrOTbwvGOfaG(J-gKNXC$SQ#`Utar36#9ObzK$VNzhbzpizLemuoX+|94Au*IOB%V2|dilZ& zEo)VyHnL^%7YN=Jg9kPeRF4ZIsD8Cq9G)rH)SJQflq2(!zq-ivcs^%H6g$-Ek9fgL znpp^{Q1qR|!z{d3EE6zw`|U`pknCg_wbiwM!GDAD+pgaAwJ8I>fU#Yd(|V-P;LZfv zs)8BG0=FFDX4yW5ZMD%gV~$J4SV8%>y7LB+x1#&CUsLno!S<16$CEk=a#k$_3C5%TNpc{p-L!%H+Nga)4}qG6DumntZ?CiIGhro#GY%cGm7akZ=rUS zNYA`@B7$nLxk+)`-iwe4f=ziB=+D?t!w3g~Uz&2x3gjut-IZrpp%m=TFDcK?vo%zA zXIAW$Xzst9pLBQ<)i8r7)i#z_pp6`v83eB-<#B_Euyi=xivKx!{WOo9XQ;?;6J7FK zBGZmzQCOS&s)=PzHpHjznE9{GHH;R#a8J!~D)bYxJ)@FwMdg}By~Q1ZU^U zo$J#6)_o=U<79VMi4s?U)j+!{%&atyhy7T?y^=`Sf5bUzP8?8^@2-K9P?c^*eDx

_Rjh{@Gy1FZ70DZe@OW0$mb$S=@}O8^LvBvev&Duz_$i64D92ZJ{xD z(wkY_%V)I|%{MVDrWaT%B>XC#k2pAbfZB^x9m$!;ADDU{G9w(dZd21?=Xe=x)h~tK z(PwL$p$UgxiC&2zHu99g{cKLzYtpeBNH>~$$x{8|Z3h|hrD@y?QjfET0~**vAZX7B z%+5FVmVX0cvd(JzB2?D=gk1GiGB$S|6>2Ox0W|+xe?P02kG&lSxks_gz~2`*R0qHt zxuPkiC37-OUQuAPC*`)=R)LiRe#*ubk4V(4aY5XihF#c@kW}40^QgP!RcR*Q(T;U0 zC!fvluDXF@t$9 z8jtWh>Cy5X?91rI9JR}i0nxICLo=0des!s#=gZmj)8XRjMj;?O=|~(ulUFh86`ZH0 z%eA+sB)(=$l6>fnKb)!8t#fD@8Pv5`g4}03?5qathMQ&oyTg!3+fvM=_1`STTH`S7 ztv5i7sxnWM9u!$f9n-IX=g(`WaOapJOF#k)DG3Tw_tfjVb+j-XXX?_mK>k-OJVcF+ z0(kItkCLmj$-po5-lqu^@#Qq@hWgLUg&drw;c}kAtYiZqNF=`?8Y^Jm#K;S3AI&_)YY zg;_kbebB<^l_VcicJYBqVQMZrKav!D;4^=;g_3v-3+KIh2r+#}JNn&_p75#Br+g|m zu_JLbpkw=`t~_S^1PkPukT!Y)DCde0S%5 zA~Cg{71IbL+h>?-{6$oSDVj&6VB$tLMHW=nv0OMs_(LdIfyq}8+B^I{;tYLIZwEMsj* zc*?<9l;X#U7jyb^G`G{7PS~s%fF-}abqbmVUR2AvtIB_t_a=;j;3K7mwcjz&FXLvG zgVF>;iYQr0+z~k0U&1k}s2cxQ@q`#C=mf5qq!+|Bb@ey(Cq8~Mq|4MpSps8we4VFZ z68GE^;0LUh^KnDvFyKs4DjD^8Sz5((`cxRSvHMG#_~fKxCBua4E}{7NdnIap6gUR! zuAilVnu@kYmETek)G*8uk4j!vCSW~Z3j~zS${lNiQG<>6GfI&Fr1eBwt)NPBujWb( z9-kO%wBLncDm&p!s>2uWQJ=20%BpPHq4lG09Llpd+9&GEw>Gj7+Mfq_s%))en@MZ_ zACrP}$;kF-R8V)ic*lb7y_aUWB1sK;9}iCD0*j^_5&Wh%DqLo-tfim7CYYNgL`Vtd zcDV@gH_wL2->CD5FTpbvm09G17=6SV0SE!@0;sHibS&2>C2nXLIE^4t zk2s41Hm*=LC}n;XDu67m&9kXA>~W8Guh1v~?=%c&E@@Q{qD`2wz<0VBQ4wb;>n6_GnXJ z!0oUVp`?i;G)XnmcuS9bjaed}t#U_O-tq|upp9Qm!_k8myg81gQ>x=J1CtcASMc9d z9eGV58jnA22SLm&lvPep{jB5fr%*dQ+A<~X*#S3>vm?b`5{PZpLH$4ab-2rd5P>)w z5G^cgVxfG|b=ZsyFX)&57_$IGZ{f^!I41n%pHRX ztITg~RFPtUtmYrhT?H%Uti0A6i|>`7^Zt%aGI!_#k3_A+K*O16fkzd+JC6&SI>gA)WP<)!ohR`h_DGn3?-#BMmh3gGUHiCthe zerdwTC~qs5`?Fhu=$bY}*B_f3&=lm<4K>Z~h)_3NhzX?@P2s%gd5@_WxI?tpGR-F4 zcqv(}DdXVh&lUs5ingK&nr@JL44ojh#3(;R2B}4IC#P0F2mcebuv-^5^wUJY}jG_bd!|m{^GhA-X zy>sK~(1R)}Xfp9>Ptc3#p?zBqX~HwV!BiZj%`DmLfuJrF zZrtIJHWZzxi)$OKObLq`hxBIl`(lz4&$5>A$%_)1@fNOJCnTu-vrNL~Khnkw@?}on z@dmh=#5y&)?HE4#15u4dXcBw2tYeu+?r)3B!3y~!@CD%mO10o+amZwT4LRqQ+caY? z8YhKPV~#}oVaj>sk(q-n;3fpELniWmR<1Q_`|QRi5HThsialQO?-j!;G}6^rt(`$O=|lNU@|RsGdFq zyt89I)%ULK3~owuw(Vx>!Ft51Atz$*JsnYtW9H(D?Rra)!=I6~k9cLA-3oe8HZw3g zwBKjF{c-$2NvZ+gXlHXVESN8ho-NKwalCJk9l$pSFbtyv`_a%2%iNR(e}m;kN6>Kw zlp}ltfJUVd2+`a7ozw*ZUS>`CGMiiedSGLBnlUuxnu0AWx8MYihV!x(hEO-1fahZ0 zciQy)w?dt)%Mt$!Z%!5rSp)@-h-5eBZ0=-Od0^Bpw~$%;f;%8CE4mf?_gfu-ii(fp zIg&K|I%m$dpqo~BmQ6ChoP(YjW*|bccw$1`-CG^-NDo6Egw>gbB1s#%W*fMtK*bf*PUp= zZe4OEf#^l8Z1~%oa51^?Pb1d@$cIBwdR6{!EkL~f-{v7pO~wL9=Xxsdk>9+Sk#AYV zM|UnoMI%RD_)tNFb&BUr`|DT$&qB%q1;_dk`)-hZQ=l0mB#(&~K)wyUhe zMVwPbUPVz={PAl7B>k02K!Dt)loc!;g`fwG`0|wupiWv_DGAK;PLAs6Cb+(`Z+35_ zdZ|(nBiPh;(&^2kDCq59N*MJ@k{_OqZDAnmW>Z*8<0M*qF0F6Kzh zW+Hv`4(oI!T#ybX&KK$1Fu5g}mPR^wqjoKxLI#Q+Vn(FU9pX$pv`oO!_XS(z)Nyk$ z{Fo|Luy~SLizSy8^7&VbeAL88FAzI+-e0lb+^`kZO43xVUNZDr8ja|nN=^ja-O^X( zBukS~@6@_Kcl-)meQu|Q<%rR&bViyvwwOJxiB9T`+{d{L*QN$dC@WDb+b~Lz96*WW zx^mU+7G}8bf!R^`8~>||Qn>RGv*iR@uwbJ#5^A7zTp_7i=+oDVAK;s}9(}%ns#aRq zEq)AOvS=o4s*B7KKqczQl>0lIr#jx*{%cG8Kfm2ko1w}t?K9XtlB6B(vPaNzYL+t( z-3r;ghTA1m4m>ff1-T>>0N=uVJp-HeZIjvGbNC#X;&(-@82fi$rOklwPy)BV((cp6-fWeUBB<&_4tl;yvWF}uso8BrxlM>Qss+v1Zp zM}6H+)$8439K0=c+tm7COHoBK4*~geo7lYWs(mj0znw*{;sN8oSlqz4=tLGf*s41d z%KKl9vnqpTNv>1^PS|MfAsV~%_uuhRdt#`v+)LC1(gjJ~q;=+Gg6AbwU@V`CdJ*aJ za{h_ougVO$^~}!)?~l9hQy${`nCJzoPJTF6B-L~rl^PCWl7JRPcrUTxgCr{!Tm@1W z>FAzaV~=;li6VAGG5ra^QE*o+QIX|gKX?BZ{H7V5f<_SxcNr@68MHm7)Qbm8#-kpL z_2@0<%%M0}W_BIjWOjqeyY6E3~2S9|9og#`o zCpiV(_aLpp11E=$!6U8ZSr+Hse82uk{O8Vfb(ZYk4w8GyN8Hta(sJiO0v z496_IE^idKS;ghSsXteL8c zuYxo83cp_c@{#c2T~4JIZnQaznKEn07QuuN!gN&p0&ztAQu@L?jrWTl%w9ugDJhfZ z_MfPuHObzvzD?hZVOnbzh%;qJn9}%h37-JAo*_3X3$%1=4sJ~pMQj_WOsB@fHg29{ zS~hkB27ldjBpKMZylhf}XKU5Vf#28U-4ru%&uf3LW+#epxJ9mv8fDWKTm@y&`v>Eg zsgx&dto-g9HAB`rK^%s_PxE8+x=r6|+RwG0X+J#-fO!HmN}Bz)>I-2qXDw=L%g?6n zYLgKFxNawiV)smY;S=FUua+b`MvU~n6YXW;@-{7`ZC<96`(zHiP~0g`kdEPhUPlO< z9JkH}fKtGy@fdoxwththP#NhUP}sooC38)<;OTy9^~iu zh^%#*m#7uCEzc@hWexzJj;WL*96;o`YtQggf0)sya@XS`{a-yl)*-Zn3>zH)Est^{ zEi8;wM&(n=W@lcrVsEcAfx-57l0MsXXp_n~_!v;{HaBfc0UroUB8=pz3Cz1}QxJPJ0|e(h@GV-#Sc3U36EWWmvRRIV9x;_B>% zBFEeINDg&F1ovX*sYYeYrKB3NlzV!Nnt)<57l6aYR1Qw#Ms%pI&CtOagkiKD7)^lj za6rDIqd3eV94~T(atfghquiqOWQ06JZTm$L`9Rzyg@8eXrv@&0zYM337wV$KZ`j73 ztK3Czs@m!1gz#UAkeM@^&jaSp84Rs2t%0}~|7-uq6sGhyRouG?JUr(ql_OkOk}j3# zJBxuW{aA`0-|7Hlu-`sidI>9lw_Yi1PG-J{vXa(6*ML_Z~^N z=p%0he4oTqv18l^yVh5QO?NXPzjyxrG*SZRqhq@~+^b-8ggn^-1+~X5bp6XXtJA83#|LOSbKIgt=N8xXed^&gAbxK1+ zIXALs7INE3_Y*t`lkdSQng7Sz*?`jid^u1d+#Rl){M27ou4>sep)1x?km!sta}T4Q zp)Yo*a!p=X%Ab$l@cC*~v0pg@dL{;ObZ@dHig$g;q>G!_Tr<5P2ZRo`t1Sj;|!cCeEo9OITnUG(LC<>CV3!&15h9<{~ z0i*~iGJQRzbexc5gCErHnDrF@IqSbbq{(nkfdd)u_22gZb;~Y+LB-npXKL`H(^_D! zawk5mH$FY)g-oHa>8r)liv$g1f1R`eDC_uKT*YQ_&+z}{<)f*v-XxwWp^RZuje2J!jr`=z<=cm zLam8pZk4~49VAEi)$Dv9m}i_{Zm)EeWlXl<)3;m4cIJl}^~bO+;ES(qJTY#B$c9n> zDJmc8)GZp11hl|vlfuR4n2g8&zqpQDDO;w8#{!5^DQ4L7XgJiSy`o$jw-eW7?Pwv0 zD_OdggxbzwJ5dBa!rkl)YrZv6V<|w(rDEhKH5DIxi{;QR-i$q<(!NnWW$l!Ui~!mW zcughmjyzR&>sSVT(fo6*b_#*M+E6g_{a7UmOB)^w(3`xuF($lBdj;2A6r=F9dJGSTU z9$eO_*&p}O3NMFa^!bd`d;+h2w#WR*O*IURJQJPf*Dgzu%!u3kXgbjq2Nq@#n`WOs zH?9%7U&lHcNxT#xb==ImT#;VaU(1)5L!`F>BM|;ptnddh8~FMANxr z>Nl7bLGht-hs--_C!2++d$uL{)Pz1}63!&aYj)HCS4nL`w1VGvxz`H{5eeHO#Pn5b1zhJ%zXF|n6On{9r z5UJ7!jHp1y;s`>2nXScUAN|tBd3T#&eI+ev6qKd#3KX{azB)=h#zihCO3@w92=0?S zwTkZD^E0M3o!GQ!#h3|r%(Lqc%_aC3oJDuX20%oR>}uKd1=NTaN9!qtGIo2U<7F^V znwch%V6eF5jWwQ{6J>(3OY!X=x3s_m<{c}l9s!aI%QSa@l)_FsbJ#A}l`{opqM0dr z(X;JZjZJE8X)9WxI>3RJ@xrH02ap7raOxU5CbjL7y;pz{2J*B8X?njWp}pG)<+Ck@ zLCjrfH=dZKN+60~RIX2R&>|R(E0N2)gB}Ev$is;>{o3nNQ=i;3@Zgyl5$jdcJYUKw zQs-;Yt?TWMXo8W2foO1eVIB+#I)dEWCT1L?fSDtTMc23xmw<3dc&SYA?92twYHAvw z_uhEMLcYDABppB9`;x-F)?6iYJuA3iXWMWd=%3BBf{>mnl%=B7(j=$Kzu}9k^U{2# z$mXx_X zK5-jg-v8G6Z{!fL6a}gUa9+JwpFEvUr&?uK0tH0im7Sts2Fv}Cj(^UffRww4@}}p5 z`8baWj^wGr$Aq0F2~vwPsyp7cf}d@~-x2q68sq>`K>@lU>I&NOyJoIYE3j=H=t~|# zXgclYSrbABRIV-+lh^;PNeMwxYdf4lLk;ciZ@B3V%-#*Ek?)BwEtJp$D^Y)in|lbz zw&H>!saJ9Gt_b>U*vfc9m?Ql-OKj7h#-p;qj7p=;pH}C>2G_;H*_c1XEvP$a)SOPpIQu=w$cfUFx+h+j|b%ku=qZPv&#(J$Za*NVU5{mJOY~ zXqe?$Q5HoNtbjqTMcd>mL=EI6$I}M)m=)p0n=}rGxR4tpga#zAfW8Bul@K0s-Vf9j zd!Y3~!*3Ajc0}W;x9|4CfZ_}-t>C#u%4cu3#lVdv?ojJd#)pStI(3ynM<)F>_D1yS zLdNemm$M2T$lnJfu?+`9XMKSQSl#x|@kc_vJfqj>bNO5UEY0T8=|^oDn`&ce^h)1p ztEso;jT}T$41S^hoz($nd13267$3IJj8^Uy&`6vp*QvEC5VAdCKZYKM6h z(?bBhaX_ld8f4>^G%xB55kVpNr)8UU;vR2a;Ale1(-}4Bhz|v$v2*HEc|arph9J8o zScz-i*3dS)GcZ|8Fp{k0m6Rf@!4Nf^p&$`mPgh)=xH{aIrSl8*mgnz~asg6sTJYI^ zSp|&IMMu9D6{5-A=U+>dU*`FEyN~&KpI+A=3-68ob<~OyD5d#s6g*OZSH_mEXD7iN zw$>bUjBm$rKGk#bJ^~eI7`R(up89^e0O{FLkz;=MtH8$YX5D6pdWyxu2t{Jv;rlgZ zGyt9*CEsbbXk@X^H@!gT8rv0iN=*T~^@cN#)^o zS9*o4losP?1r)V2RAgGdqXdv#9Qc~MCuq}#Tt%aWb|Jl zHUV9q#4KkVNR$??s1sc77>HryRBNK>fAAH<&b(WZC3_vypA#DaT|?-hcUp&ei`8lO z-)5qO3}&nqWxsU5(s*h*oS0$+L6x#2S;nx%BEb5p$dq%DTVxw_zRRJ3vB4&xlvM4wRlfPh^{I4^};D{kL8cBQ^MBNW{=Y!L4R-Ya-+5qVn!C~ zCZ5`16AKsj;q1UT{y;HnI4Vn}j{BKl)=Itmbt^&CGhH?QE&Lj+0<-XZ7Swl(%jf+J2>Qxc@nUefsLw#u9`IiWc6Prsv>ycDSQ& z`?Qb4y^z={1nokRn}k3u0hHUjSS9VF-Kq@EB@)dMztC6dQFNz8Y*^<_L&nevlP%!m zu6vJDpn#$8%k};^O);We(@JIVpiDm;? zP8^o6D~(NW_HxD(#}v*P3=5+H5`2yjxMM+Ax&CfG+93Oq2z_QToln~o^tQO_?omG`shGfq&18Y7h=b9FN z;vp|z;)Z|tA~q12$R|Ugx%9NS;iDaZoPm<>A1G8&^J1KOB-C2mI8UWl-A$oV^V6N7 zlU}}?(JE5$yQM!mlze?bVKx*cU#ssj^ABvr^rs?& zE0!*Csf-d8&V5;H^2#i|h5I9`%ZZ8FC`o?&kSdxzZ6sH^*)ZS`1hIdL&&VfZ*1hWQ zkZ;2Lc>Tm%MGQfTQ(L@ZGKPN{w~GT%?aGdepyR?0f#r(m@oEbir?%~MBQ&jB*!LHW zr3Lcj@4=%>-}ry_)F;X zy1Rys=3|4BBL!G4Vcj^bjTwFVd_KsZuIg8V^0HsW`JA&O5d(hhEya|&(G3{-f?1_F{M3X z2ca`by9S8Zq1_HgjdB1jQKL0(wjaOcLTGPd`tuU08olVG@ofj^aEC;df>xs3~eJb6+vvjkvhnPA}tsiJoG~@BLt|SgECps5{tS)CvD#j3wTL ze>KTmE9ge#9KCl@F;zXZHS^r1Rny}n`9b3Fz4iZrhh)j;X(@)Um@_kCoO>3#{tKs) zrF((AP>A;D{BzbfLkXqE)=en2s#8*oECyt3A#3MnN~O%9GVs}Wxx?E*?hp}y1OszO z#y((eg74y}=-1lWwKPJ=9H*p?h%UUA3j9DefZt&00|E?D_k97!=|WbbOgrWb{bZ(MKOmzYHKg3>mdV0{XY8KbwZ^(eE97vw~cbNCGTY5C8WWbiz0!jk1Tf>q$^*GjvWW%k&d0 z`a2Fim_9SvRr+9^|WY z_-_K*YdjP#$=k3_IknFPuAE~pY9(QvK_XV@3*1V>;FbdUW= z+Rf?y^>0JXr3Ioccw7ItZ!Y~lOYhI%23IKbE<3fJJiTM4c#hS$fllzh6lKT&pAIEz zdSh7R=c$4g$%Y`5aa*68!^JYNY%7dZXEv0vM>GAOe1CojQ6GN430L!~ca-xW8zUs+Z%{#cB*C5S5 zkgAI+LhY-;Q-jC2KcTtw^swL`uID8bB8OnPk&menqi9|!Awi=8 z2!hZnW^Fu1$0G@be^U`YgHj4gR9 zu!CTXQ=NB)9%aW@F)7)pIWcTi_U0(j09l6G=aS-qoU;CEhV!5pV1%()r=YXKS%7r zjmb9nQB0~p<7y$*=BCe#*$_u&{W3^4j}+|*fKVr@)gNiNrIIAwQrNvul-+H?_yysZK911Vjnbkjtx9l!a-TZ4?&go=*orU>+i6U!Dw6P(9& zsi##0k=E(dZ^IY z+H>0&+F%>Rw@2UP;<#*uSnd6?G~@SvR_@=VyRpoFfk5fsKZ3*!6q`GM6(nw?&iW{)e~J6XgXk)7 z`_9*W0~I9 zw_gVV-?8OY^@nNFdU3oCON*HI_6h;JpBojncHqEET?o3mb3Zm(Dc5|$hXZy0CLylA zW^kgJ5j9D8dpiD<_c!2aRyp@SaXEB#G9UXohX|XvM3n;}(_U zrLHemU`r8@s^>_`$KEbh5RStNeP;2)_buJ}Ub4%XO{z|j!IWSpGlHfnx&<;b3NS~o ztZ04jB?-?_^adytva}zsH{5WDO}YFnVI>nEGDvOfMg?X>q3q7-QK`E4-jy35;URTP zC4W2?_u{_m$}4x07Bb>=AyPjGxS(6^z7buPd;j{n=$ahfDHW*Vwu5cxNz7 zY?8$u75Le78&nJs8?_M=*0jJ=11wAKtoer*Q8l<4+!kS5=~_dSLXT*@wo(9Nqf%~N zj_FVJY1mKoT#0@hx!ik_iYxrMt-JqWF2LOTFL)|YGMh~Oo~wXdeaLIGEeifaq7V>y zyo{iR35<&<^NPvq%e4+x8Lr@=B67v80TOApQn=kVB_XbJ2EpJXAmNVWnazgE^^*>3 zxVjihHto{IBo{@nu*Xq_ zp|NVx>PX^h11jIB4q~Dn;-?^2y>sjDhRM|Wmj3#)#=m+NqC<05adp zJO9^Dpl7BDnt}c7G;__66^lMCZ+*=5AQcCwFQr>6Pq;4>Y*Ki=l9<|Q8CXnqFY-@;vPX zhfGMvV|gUA62DbDGQUzz9>E{-{pPqL4_8?DM?b?`$$76M6XI^(&i-20ilU=7=#&nK$Y#X<`L07I{}PvMB6oyz;49|)Xg zBg#vNv_Ra`(;8&sn?vd#kT5R9b;VM}d=52M^&e0x_9&BY-Vnw~D|fMN&iyykjS=mL z9?ED8PB?!Lt8a}Qebjx}sazylee_$lwcFuiVOTN5=T$;!R zdmgNqXBRS*+R=+xt&S!GfqY2Og9Ey3QRyXu(z$=wGe37JMM0?-Jz~bv`_UxF?hwFa z!$!s{=$y!zBX_B_62w#9ydbi~65GNHV{mFgF=a@g{JhpbRTvj#HCW>_tgp(lQNhe$ zIFyeQxXg^i66)1C(?(SnCwd0~0(7S5$fwYD$X-`a#ToIHqf!u~9?h`@WaVkuUi@+I z;r6qq_xW-CyIU)I(sF#qbBXuj3(W;j3=r+i+O~li<|_tf@5TMq#%3UfDo+JT@l;A~ z9nGy6>ugxobv|N9tLh(r1x0RkDqfdc-ddSL!D6e&0Zpvd+{tky(KF&p9|;5>4MIiF ze4y?~{fi%}P)Kc#GArsC;e2#T3J2D5wQ9 z!rBu2z73A_^+;NdiqcSgz`Wkun)aZQjTyXJ+`s!1k3k8#*$a_++maBh^0jugeSiek z?3f8(V+~jUiU)T3=5F7=bLGk95=2<}F0tk;^$nD%Q4IkDt9kkEeh^E`AiDt>))LXI zmgx@OzkY!BSjp_K_br&bE3xr3lsS&P6B9v?^G;4{Dyr&mT=+uwy#2jzVjIi3IoxVT zfv^8tet@~Z`W1fB!?J*xy}2-rwL@!qF|S4U-64-uvGy%}mSakjm^Xh&0!t5Z5=!kWnw87s*`A?enJvGHL zzC+LraZVw>F`08(gheg@i$W_DhEdC)n5k%u+gLqwo%t<>c4EtuDM*qy`|BOr!w?@b zXzt6mip$I3H!k|yCq%bz{;H(rur1bbimFSNs!Ziv+VaH&_JH#Dl z{j3WvNn+|3JoQVyy1GIF4HNMd|1L*H(I;fLH7GH)-X8fTYy>BH1Rah031=aAC&`Nvm+CavQ8JKD*O5Uw z?!1?!^7>lZu zvqw-b97(H2IDbC#@wl@@svmZ=XaCQ9OR3>vlTALB+gA1_U6oAwUj{2&GcEY~Xo~G9 zDsGjAS#j@%M_}wVd8wE!ZXhN)A?#TdWzD&f8E$lmI}iY?ibW$Jlmh~Hx6hn$7z|rL zVmpt?_DqjpW(9`@kkklv*Q2&KsDlNvNa-ZR`+1?xtSJ*ta^J0?ue?W+4l!&Old8r`=ZGtXyL1#8gV)ja0~GM9gn0%?`7zqcG988E{e4n$P7zY@xvq z;@XC^QBY#sQ9siE-hVh+|1BXMS-IWbgA=eN^}7*AO0R(xpgCJG7c0M717NnhhM!PH z6$`pT^gRV)&6|wRlUy@w>Pyfakv_kqoqQ~ZoI;-im;)P_W>1eP62-Obf%vjsL{G3W zgPx)R_{uK|tqU?X{ofXp&6X@jd%gkg80Q5rxCgv|Wp@Zs_FWzCj;l2p? z)B$c`m;pIUlQ}pvSR}#q0|gbF@Gu}G)P8faUsBLgoN)s=_K^O!}djV zPP>NFf2$eeV`qW37|3{z_=8{jE=iXwG`n^#lkDk#O@2}glDus?G@D*wZ|X(oTr_LT zz%gNDovnYE%KkmA_aXL7Dj^4eC8Fvkg~PFQ1b@*S8>N1hMgDK5G~bjTe*4e;DeF40 z{I=DAi#Kuma2YVfZ=hSQTXj*GiJtKFd9NG?wqDOPa1RT-3Z_8E_~h^Ax0G&}bs}?I z%FO!-FP#2K57TA-)bN|@jMt3+OBg=$oj>)1)*U?~c@M4^VlxNBte6LKo7pB@8lCYq zlKD6n`0gh8Wc*%>fX>@w_ue2GTqgD-)|rlVcRd#m>M>enG8=e!WP4%$y`;B^dMI%Ion$QO#K|wn zKKgLZA)BZWY8Krn&Q8>9j7NhLi|ibB+)aTc2-x}FW*y@5=iEL#YnUZfi0ImX7Ug}d ziZ%f7XvO6G>El%EOws=b8eCq~vHyMiTQowIi2)>zFzo(k_~NS7YM?^q8eb z5v{E1x*#+IWsK~$qbv54;mEBtFpmy9_G89a!|0=h_#}=Yxi);@5o9rHYND;vl)DpK zwCU~%-2Sqys6zs}g&$VSwUsi=e&7J!`ah9z-XR(P$(KWw*bTyp-pn*e^ff`aR#MIe zv(MD7ddunUH`aEbcLe*lK_xih(Y4+o;AGf?6MIXz$r1ulR#NF4Nl1gxnR8%DOnr?* z`39uB4z}H2$6htdpuuKJ<4URQq*~Y3>ZKs2!yCY;(eVfct3VVr^4$-`+Owvy2R0X7 z>6RmwM%1TqWD{~ugWzRAL9e!30HUi2f2GyJ*}!NjMBGC+fw+iFg&VPhvR0#!52kQG zz3JLOoAsVk?O%j&(o7t-ht|70?Bz8ZESvG=_znk{%vd;AblVOH*;eQXV?C5g+*$lR z!K60B=)OzWM`<&-axhsaPVvDdqom^!&oTD+t}zC7l4OUDu%8|DR&&K&yMPTDKUR$7 z){2^9CQgbWeR4F1wth+6{U?>WCEfH`D-l1@*ApGE?BZ2ka_Tn8*kQo##Gf^ObJOijDpmrclJ4_3QzcDZ3OAm+ z^s*CoyOXJf@)iAY7XXRpd#T(I*~dhsdp|E8ZKwVW4ud{8C#Oz@JcRz0NQDV?VjZMp zRPBk?C}L6=@9 zNK=Ie$45yu*lMd!b3fDGhbgSQH43zJ!lw(dlaeVrKB(RjNp;#5CsHqyBi8p2{vMN; z2A%Iu9Na!06PSqFQ-_HyDHx%Eu7ZTBzly=Xtg)vyg1X zq?sFqDR>JBcLnq#d0dh6;N)+DGftu|qGfrlm^L(Wm)ALoUV@)Y;_6X_VhlO<+{S=N z&zO^BefeYb^%yF)1h+)QV8G8kh^V%KqnRr38jW@!9n26=SPA*sWnjax!N5&oQX)k% zyb+TXwk3~cpiGF#gW+7e`x>j;H9%&-FWmK#2u#PgNd@5HVJqIpY6JyMpXpg5R%3Ua z;~qBOhf3?ZLOmO$(8WXtzBe~;5G?|m_EPgyZBX0WR{;x~)tQ-Tn-F$L>L@1$Fk?I4 z1~4}$bX*_`{T;@)2#86IsQ9s%*ndyoc}9eOkjW>?o?A9MrDuIjI4jxxTu=GblbQElvg z#+@Jmzt_CWG<@YBl5#I^qaWx^ex-#w?Z+ik<9CoB+P6r3z92}Sv;|#3#YoV}gTDCK zYYir5F7Im-SZiMni%wUvYduZP%bJ_oO@Hba27k@37}`DXFfO~o9naqP?%LKpbDBSjK)tTD7WM@my3H7XO0$QPYZ?4Us6|V4=mx;OhWF1bImQb=GR+(U z>`T>dJ7ut+~gDV-htMa(9 zlC{MJKGGWe{UN5Zy@~FeJdoM((&)n>xeg4Nyk4OViT)2fMe5;h23h}k^nUb$z-!r4 zFqrL)Z#@qCLT0N$s7mj1q*R$twq->5**t4mHn8J-N`-)IcW*RKo>ct|C33@BwmYpW z)hSgmt77C8?e7-vL)G0qWQ-HM%}x7HhC6c}#OPGC%t^XWfz9YJl1o?7d<5GW7^@7U~xG{8WZ61%FNTd zYtUq>4#0_{#uQfMM3#U_B{e)M>ZD}gEjeB=C$Yutpn|3f!d&Ocsb)4sM!F~7KUWSsNGimvEi zXwT07KgG5E69^HV8V?2tO?>&(Am4)dhWztqpcI+qNALoB7Rt}L4`>Ko9cAt#R_hU4 z%JHYIP_ofCW$AwQ>10AlfIt`HLjc<0dK|Of+4nQ+v$*v@8_jW-F!`KKtbUH!Hj+8D zRu50VSh%{wy?L47HTNRW&&m5n&;j;CJ3 zHpbDsnzOpwEaae2bnlo*6v;SEsYnyl2w?rsUh>Vy>#vA1FmD+F?1!#xW22{g%~PlH z@}EP?3O|g}RgI^W&s(l!BigjRGBlNn1LtnxA%9ZDwMdt0V0Ahg)39KggJG>ZOJ%B_cSmnKNU+8>nps{Z#JTMR z^T!D@+JR%HUEx$~1Q#p0FTGXUp=kiky81S%M_PRJA5)Z-FZe1;sLXS#{UrcBK*GPW zPS#?OjE@53+#-1dG@DdhRLYx*_yy6ho{ysoQ>bqnF7k1BD9)+dOk0Egs{ffU0~E60 zU#evlAJQ?Ea6F4uj)(2L43USbzDe5{dmSdH-vIw}a4rz9M(Tgc`Uw*PtUsUvrf0Y8 z7;}*&peWnqPgy;+@zw_Trd;-0(Xg!x1#voi?hfJP2%p;D zSyxX5T2Y!{{e>aX3OfoFVJMgij~+7>vtRSOi6RWIkxhtUeTA)?eNp&<3Y)f{E6tlmWzh4mwA=nX;y7v3OCC(;gyK>@ZwyuM047M zr`(G*KEc(97dz|EHk|K3vU1)}7Ho{270!JP!!PQqP~QUJB+T@uCAx(TVwyR}TG5)( zr$t}FMD?kS*u2xobqxl_OC-kSa`)AT$~?dv7^y(Ud*w{#w*gnd&trpFV@J=V)Ak)K zzZd2Tdo8InBm5r*F-LnbG>kkIo2>mf=A)jc-=;TV{e`$LXLEmG5{qK6IMAxZtvjg% zX5G7-v6bPR3UYuFs;CSPp-wM`ku#P+)#Olk@2}F*`#>g|n%$ z6qS}q`6}n0IzHGE_q;=lH8Dg8eXUNc0L|v1-O(89r{PL_IC66-Mx(POBW)(DhTLaT z{ML#{~)DaK$&(PS}0h`Wz_y5Gv?m7zvl)m@c0k82=*aT{qHn z@qq}6RlqLhk$GNX)*D)RpoOpC*fW~yb zhFJ^}-18f+V|30Qtng)^tACaVGP25?`<-TEcKK-tZqr8I-&6(-C4t#mMeF6j_J$AX zCw$yeD7Dai2f?^NbIYis)Vu_b&(GB(|&qw|}Ty301rR4A-v*nz9TYEhRV zX)r!ir%yzjj(&9!jwo%XGBzMW1S3IMHU|A?%BXk#e zLcU->32H-*KqYy#ySs8wtxu|=)Uw8XP)uuZR zu^5pGOJGGpx?TGHt z1*<3fUxUq2&^v%i&cEsYM$%vEjEP9dW!);I+El_fe%JqiTkyj`L_l(5BgUFY^GlIr zCj9fDxdse~yTFrkWA>a4;`Z*~QT?t>A-QXP9yFj$MAGlU`^0-EAVkvE`SWMNzpB-o*(}xZLM`k$wZRzeY)63jZ)Ong9oBgPPAbrY zr=1;v&h>95hSJwo6=g_F@%bTl(S#z-O^t)vj8Im{JH@uoJ`GUiooux#T39Ic3I+2H zK#sPw-w_)$fyE99ru;?}0(g|WW1T)FEXW&N?__rj1VG_Mh4=@*6lLlBy5yXvkya`? zjx(-S1f4a!tz-_Fji+wxLyz56h%{YQ4?;~Hlg^fB_%p}KG!ZDW?GFGzgzix$ZhI|v>lnD2tthr^ zUfvK)DIIw{E*$X4v+fys5aHtm9%JbM*Zza&RR3j~C!>aPT(UY*9NT5Bi4B-}$}6K!7N)bg%tu=jmM%GXB*ppluG};{_ec$O zuTgbKzD;w9TKv~h)03#Y!=`Iv!NYq<@mJ)u&R-a=++mrjeo5A~EMmBfN|eFE6C>Pw zNW!Yb*}w@AZZ!uKcYf=K00l7Yvc}$SLJKOk%CX#OR~xNTs3IP!Hdk2QO4@S}qf$(5xYRM8KG=trE z0-p#u#vm;S0bTJ&-iWP93HKTdrzw%;{Kekal0W4Pk?JJ-0-6&#VF8_foe}uG;03!A z@Bn9!Z-D16{NU<}oh%bqOn4kb;-+E&M)@%oP6#Y)+i&T-(l_<8eXvH7ptta1MT*ny5CZWx5|7c&3pJBR7>Wgk@xE&Wt9`*thOS6 zamLJBg!paDYa5bm=Ztj@VC4o6myb<8$K`XBpzbS z3Fv%U2-L>e(N$&`ENYp<4jy~A)V&TLB83So&;NO!lfLZjW4D*P>(+2~sZY0>U|Ue% zg+^(hnug=z6Dy1lJFBS9qp)~#K>N`qa>0=$dnw+}ne&c^Ie`SNI}vKy0Nv?9!Pw0C zS*)9}WN*0ipCI062^-%LrIc2ycDlvdY=-8fb6Kh5Xt}^p8&x5m>W$1@?ug+Se9e#l z7`+qfmBfzIlKwr~Z>7ATcUm1`|9f}D1|`L(b~aV#!0<+X%ICr8h-Lq$ww!|a>(D3Q?RBx78B=tufORq1A}-@`+YM}s5@R9_S)Q?nu!QiLyIi~*iBVLx_6 z9LjktKu(}G5#S>ar+E4KDlC{>sV!!?heOr8WaUyX9o!xCvlwg9JBy=7Wn#?AUjVy! zoi)^XMKi~!DVCU|BP=6-S{(_r&#Y9WMgX?}LJo_jHypK;jrHwDuM7j$`41ReNP{GZgQ7d@ZRL8&e+m zm>a&x0QJ9l=Z^B*Sq(<3L(t@)>nUoB!I`Gaj^*BG-$@B#jZ2{%I|1UAWe}y2&`33w z&*V|kf0Ie88oCHGR5aHB$)E=V$BJd5gka68qDG8o*}>;n#T~%2#saIO}?#;2mws;)l-dqC6&bN+o&i#4M z8t=hSNKkNd(OsNPMQgHwziDw~BNM*-v}Bj>enaykY&_hJJ7^0m^|<2j$`m0})4r9DQV=1Fx%oGNi2T*p&-q5WKS$NcooT-d*-MUovpfDX1OX^fWCDlSqs}?KMIEORFG#m2?8- zadv)LHM7@4AJpaohPqEv*~5K*J+|1A2Z@>A`yRO{JV2*rfKn%}V0nr)(!QqoOnh{!-KCcSz$1R>#_$?e*DOc6;GLZRDk z?Hf1039L2RfcACNGE}t~=y@f?mFRTOZLBmO>eMdLcV3W>5>dN6-{$m5j1QWQso#05Q-yI>zgO?2k!X=!di&ENiG`zF=$H3I>nQM zs5!b-&B5A9!c6p&0MB8hyNqNrkQ8klt#y~#9s4I|Lj>GT-wq6Z9Etuhx0?rEnFu29 zZcU5UC*~v?D6k@>X%~V<Z7Gol)6&VbOfU(~<;2*6#>PD{_7AmbVPlBaxY~&+ zhiPsm^K4{Obr*+K6hb9`=M9M)cP7ND%#lasRIVBg z1exnr*tBiy>@RG^j&|Xor$PqF!vpTAn;!fT^)D+FxSxk%o5wf~SnniY`cSrPW(xEO-3=G313~%TY#bTHb|Fh{WQxU zr~xGe=Mxf#W+#?5x{|%xlo9Wcy}X|JW3#5gyGH1SKP~wYIwPohGeJHsUEaXbBg#Rb zxo~YU^NEL>a@iG4i&5QHp|ogHWq}e#>Lj!@%%IzSmf4PEVGw*O08N5nRHSe{oTUrW z2yv*Cv9vH@S)X!YRxP9SogDm0ojE7VRI<)Iwsz%?rRNCL$1J8O$UY(z26bo+Yqg_j z6c_%u%qCl%3(P*(Y~bu(9v--wzLB-2wSy?aHD%M@-Ek=s!R~k>Gz)h+NSG!=!p;Ne zb@+6-7;gYN5aQ%8vP|5R0n|!pw1reD82Nu=bG5 zYb?x*Dj|3ypmB_Q!4D^LK;)h^^9sOzf90FolSv4}Yq#p^)LNF8Jm1FxIiI7--D2}- z$F4WQHFL6EndGh~RbFbYZyJ?Ru{+naO+AQI0lq8}7b#Ek?OGqH@Mpbzt>su!)Y1MP z8`jQz!=kBjn`-6xIU=fmE}~O)@R=?)hJz4e*Q}#brXzqxZ2r+Ek;V{rO z!o4uKh4a!Zkb3abfaUSRSUvYVy#E7D_pL9c{&U`_VAqLC&pq?2V)~s%tD*_o zqcThPPE$-(eZ}3>U6Z(&KGPLtQg~X@A%tBhuS9(q_}yH?ZpZ}%Fwlbd01rJ}Vt%I8 zd!MmHw+$kJ;YurcemPBwn*Edv_ahLQ($b5V<(;s<&jtv9GHLyRU$bTrW9u*-&0AaS z49YM!pn`dIhr#+=I7{Q|MoBi3lJLnDrR<&|wx6_Z_U~LTeWbG``x8Lnpdd;*;y(4@ zXkihW`yS{U;1`^VwcT6@btWHhRCU7~Hv=JIx%s;u$4FpvM0A`P= z>@np>Oq;iErRSb-^a3h8q5}jlo4y%OIHhad06*Op|xRkb5GxV#3?Ho3dryB#xNMsgUOKC^0*U8Ux(!F2=d}iqql0bMP z3tOPt_vD(boH6IBty;rH0BqAuli#*z5kD%tnvLrZwW*G!ESZ#zA*n%Y5iSBD*ulK; zDu=E$sd!vNxVK|12{Ep3{5g9V!_MRSQE@t{zbH+uYm(}zYJweFelYC zDJ_GjxgGct2~ph+W|i}ls)IUjihMdLg1dmBH;j4oN~q))a(C{;swLBpF0Z+=Jf_uh zmj@#_uAU+Yg>d@+IOdk0ED;nIn)+IM1u;G#zfFg#x|Ge^>+C65PD2vt`2kSKQF>t# z>FvVSF4OH)a`zhyjI?FyA~7QC%~NLar8Mb*bj!7CMR93ugy_bG$=wX3FcJtt5Npk4 zZ2g?xcRVr)@0lkKN^%2@wP>Jc_rk8Y&OvZa-4n|{1y1z5h?p-zPG3IDEYmNzlDpWI z$ginHi|{Xj)aM2n_ooVTJ}}t;0Z@J#lIZPrE!!gJr_eKW5mag8@FH2-;Qc&hrubUdyU@*l~AJ`j@*BWAvYc-r)Ma# z$Rk=Eltvpqa))yW;yXrBzFVnsx%fqG42ggZdizX2e?2Mx@3QP8!Y0p*E-1gnXh+#e zmGNhOI!NL}T*#GMvhyOzbCI=pmK&ONU$SeAW{i%(;ojC{G2wd>(uI#wXzYL{JK7_^CF&6vxh;1%B5!H#NyOi=W0V{{TV%8wu*tumni| z{IzFPIXxq23w@XKWgw#XGnUcx$GUF-l{WS>(T(2j9{OO8UQBSiQ+dgn-#k;~HHX9I zjt&~o_*W}4QB8eA7d~$e%7(JW3G*+(Uk;jHeVzCJ2}b2GkztdyFU5Ze3ssaCB^jHk z4rp;08%rCbb&yt;UNdp>25AQb%Zz!Or5D)PcgM<=SQ6~rLCF#pn#AxYdXDQEc_(`= zRhCy7zEzBWmym!!U0U`B*0jaw4piQFBg#3DLbi((A_j4H)%T4BoxlD#k-B+>Fh?cu zqHlDSW`98wibcHB^cRpk;H*M^w)=;S9te*OS1iupQsLZv&ZFX zl^4VG%YT-^sP1YHA6+0QljZXhMpH+hn8x)fX}N~aBT=NyvbJf2fJQLE1GQyZ>++ z=w+7aP#Awqvf`B{_BRQPje7#He=@ajBG!Wog(U#RRX_TA$*+gO91)gr7}(pZhF1y} zBQikKuNPJ0=K*COhuXD9XBafhD0jmWVr+|w5qetD-?I~IDbDx z{|J@bDhI6UM0rvN^YH_JaZ}iZ+i>1q)tVTe%s;@uNrG?*&M5>68G+e>B5_ELc?cY| z$bMi$O5@dQ30whgAfD2%fVZLwTP6rHbG*j=2C6Pqpj)Xtg|YQmTNx4UN@U> z@401CLL8@r2@FX(l?Ig8$3XS*X+it=SG67t^VzX3STnw{Jz>Vm0p;3YkB9e~wUV@q zDzDTYoR>L+nMwy#b$#A)2EmWC-V#IdVy@@x{<7s`HMj1n@CmqK@FUD+lst;T16_;XCJa0?$%z%3z9a#AO!HhfO*9F7YsoKwl9B9^U zD+VxMSUKwYnW_X31+TF8GGLA5(LgfRqw>01d03Kl@H)=2?q)vYzD-k|yW2(Z3G3B^ zIUok9L^bPeo7tq=OP$_5CZa9Rjy}A!j5@zod`M8W#lD1IV}f6YcS@)BW(PuQu+JH< zY!-!hh&!dcLefm%Q9HyA^~G>kK=$p@H$D^$G1`=eYuStyL8-thVbfCJwhDu5bsHYh ze|9V~TsRVo|{zR1Gu^`=+>^c~8TtjiAhcmWDUhfSf&%(C6Z` z0J?_h>xSxtc!3}(C<0B`8(vRA{1ZM*e`HlPK@D`pYJ4|>LA_@=*@OCjjNzXn4dfj_ z=5CZ-?05HGw4nq0pbonDC{R2&NB8Y5 z3Stl>u%T%JGkL$zwaXVERRVBCTdW{8>IE%mQRiP9%}g^*1R?zfXM$juA9?gB;HVhu z^@dpHpS39u=r`*L^u`GC-c6QBVm4zCKV$1egvj-D83R!Fe9{IWZkwVvuxNNOwgvjh z%^gg=Gq>}TIDKCLgW}7zx zjSW68#TROaeMqFtRUmtJ2hT(=h>FbeU8X)?+Tz~Qe}A`-Q)Fv-LQ-kQ)~cWR8NOu@ znMtoUNgIkif7_xOwbnFI$jAoD_PBPaokOnhQRSLKqJ!-qjp!W86;3xl*ao2C_yzq! z^Lmy zR2VUN@`KN`M?mG8)|nEsVLcCC$d#jC!_{kUpz<&4X3%J75QStX*tlo_Hl?dR;X`GC zEx8Ye{-ILojeqEm{-7F?2Z&dm*Iu8hO zbYwMC#rE1ZM7rYo9>UKl0XAmC%0TzTx@WBR7tEuUEeKx<>Ry-J$oW|$Zp8}%xf&cYT5sW|-*v^Cx89`p_N3glmI&S|4zr#0b$x!8k$KdoFqb;LeBi~0B(P<-SOD1$ zm!_m@=nAZ?pE~0znnOX7ZVtp_!x*;V?>*=Xu%9j&pqQ96_=au8j6o*1@*UK2IqP`_ zuT!ctfK&Jz^ivu77K=IRV}CfrW*yOxf2(ZENnPem%aT#ZYIIuYrF90aq-V;fBNV97w3T)n)3FBB2Qvj z*1|Kr5$6Xw{&Wra+1tGZ^z^Yo$+P%sdzc7p&P*u3jCW|X@pP`>76)rP)-0hOM5YO*Y|o z^5Y6r8dsfSUJd}rrXKS{<{%Afj*uNqtS_G&w=nEnnRstI=in&0m&I!G7s3&&8sf@V zNo2^!W3Z;nhYPtDMLmhSn5eh6-JI@FdsfDpcwrq#WHtwtZrR7 zsYK5HIi~F1Y2NzCKtwbt6&a_#)?57_d%1}56wgA%r>72UZicdaBaZg2-aOYPUfwa3 z!5L*$19Q6EX_cIvj#=1IVV{rmDML$Yb+b#I%tq2~07*~qtbkR(48Issb#^o6 z*@VH?aggMVI((eO^`Ibrq7HR@C3=1yG}xlzc;medB+2_CC$8zy0ZTd2!ol3E&$q_-s*mSfe!$=n2kVlm@(08RL_n66D4 zIOCxwQir}QlSR?1R>t+bwdS1R8#h7-=W(^9XZc9f#1JJ@oCExAUSeKtR=ju-3T+#D z++wv@h81!D5i^u4rpIX2XxdxVw>WGZ^anZbA94z_5)&nc)A*mYKv?HqpP;11P^^O6_neP{4VZW3_pUe_vM$2FLZZl} z`EUjQdyTnh!}fFl&7E-iVl?Fi=wDNtX#s}09cX}wQBn=)D52eAEAvxys+ik;bVTbV z=ibCA6cKyI?-b+&(DV_?+}!3rn#tl0XE1nWlv<%A){rk86Grv5`E*u3)f)-31ipy? zz2LeN1<{zNlL^I^MzvZ6tR7|q@Txt+RHMWz4Ws0e*3d+zH!!8F!pK-EEEs5wn@^e0 zRYCNGJZaiIZ9}t#6(8GJ3vn|fyCFjv7VCrF<+o^_x!LwEuHA?%7}vvci@vXo{mn0q zJ}aak5uE@}>hP*9^PT+>d#o&GbOYtgaG(3PS{B0vVSJ2p%$#a3?yiN&QIQj*34%>x z2_z*oAA*Rx-4((f(rfQWLbY&cxsecu3X8T{at# zI%+&2Q1A-rMkGbSUUsATaJXVk4w8pTYWYTyWd46sB!0&}us0gW)-wxVr7!~yg*|)0 zp%}A_{>naa*pfy`U{u+A_rsYlwRy}kKz%(6#%~1K@!e$g#9$NzTsoxM+^vtoL^qaW z0Qa%Le2fycI_$s}*d*z|#QL#?TjOFRp>>ji1X&PJOHoliIl672Wi9+89Gz(*=N0<8 zcE3|%uni4eRRFwL0qr+axuy+qtL#F*J5v3w>1|~P^Vu?H!Dbp5bA|!09nsLwvFcPK z-||g;$Nv6(9V{ERr+S`{IyzTZ( z|HE~LRNeNE~8SQx{m zj)#~t%z)Q$2Wm=}?^g4j`R{M2aerY49i34IhDtS_t1M=XVPd`QY<7HS;NfnNbg`x; z4FMnNv@n`}H__^snh&0hQq-0(So!E2PRV@DHER=_umaHm~^sfzGt&as86`RxZQHi&V(RKzSzy7)pDHKh{sw zW*#4!6dDSc$JQl-H;P@dh&gC`A5IGG5gK=!%eH-7HmnB+p9Rm5k3UPr`9hGiLMEXs zX2!UffQq}DLF7b?URE>Xy3a9=DA&c&J7`A`uG+)BAm^;&;oy2pgR!e}^u*^40zg@umNSsFMD?#Ws;E>@2PDti`aciVbSnDSEJn z46oXCgeAW24gE~@Ek@}Vxt%>rk2>i|wlbL~;!XcAF4bvLRv-$$ViYv{zm@3zv7bXQ z0t23?;%H>uH~hH|g^V^u+kA_cP{Vbh&-B7Z*rAN8jXK`vp3)vIi{vrm5sk5^&%KI+#;`_S5|1o;NLqkw3Muzwiy((CR>Flr>oaYMsU z%!O$6%0x6nsxD6g8zWEY2Lht{Bv)`w8h8Vu-BVD41+fpyo-SAfV#usxGV3|3x@XM1nOKO#U=0hw`fosm1m9m5Y4N>8m&jrnNgpH2Jr@M>y;v2d zH#$Fem@+_$a_~V5t%$nQuG~ACH;JVQ<-79uU8U{lIeYCZkk)L|`e~=i34;}l*yDi% zPA%A$J4+amtY0GLol6O?@ZT1q@hsUjif)B^yvGpHUy4(lj=YQ&vx=|_bU-R!MsXYq z?g*|ICLYhfJ)mAX+c|4Wf>Q$Yq7_`W+aNHaeao8nh-tOR=FOg@uO|*+LCubFgAvYN zY_FtHfwuBC1-mv*N*f8E${P}}0l>e0KY?JM{Z@fgnJa%DvA@)};e2uV0CHatt6&42 z6Y;u8lN=op1VHxQJMU~qvklKvy+wZ4j5N^8g-agM#r<0v7>Xz37Ca>q^6{ZSQ)nkF zfes)NlB*Q=ZL;a%xSy1XB;FA5})#NxNi1VWSZBYk^M#> zY=|YVB7TKKC)^`=SDxu^K!N5209z-%YjBj_Lrb}F6!&h7wBni>2MNz`!f!@oDz_TQ~2 z^w$}%@~6~sywjrzTpC3%EmNf#FR)#%1SsYfK6RhWcErM<`~Tfcql>Ktb0+ZbNYy1G zka!{e#v>HG?Gq_>7p9X5Zl^-s5uOF3w@8GA_)hIT+x%$K?CfbPU^vm4MEPLTTAt)4 zof7zJQ{HxXr)aRW+%tQMbD*VPkAV(R1`}&m7LgzIYiQ<+Y1#^$v2>3dv%gYVsZIvALuq#hri2x25i;IPRd6|5s`Wn6J1?K)jH&)O_@4WnPRkXp!JH{ z1$FVIp`FKCP^D4EBAKK^QtYE)Emb=w8oL1-kmB&pop$9a) znaa#Uar^9C9{G#jLuG^(QVL#@AlN2LmvP?GA1=|dwkc|DK>#2<1NcLGSBFmVj&IZS zY-}m^nd8$P(&*RYv zm^--{@|#_dnLRLPRWwj|JJN8m(veR3n0=G2f3bP+yK;jBxx2WH>1@#Cp6k4 zBv2FB0!S3s$tWATW~j)Td+m~2ct&|z(eichnA4w3a#8K&&V#Js$SZ$$YH;0vh+?KFNEfo`N~(Hv80)vTdmd_?Sla?I#&U1uL{^cpB2UgL3uuKuABx)#EG(Tns9(j%nuKOG=fT zOkN2j!_Z7144TfBQ)+uu3Vw5^mFIkCodvumI-x_EdhP_zlma#;vw?IX?jD}vg4E#3 z^6b){_&=Y-Tj>0~ld8in&hj#;BlF<~u6>8;=itG7be!LYZCr{`MV&)QhedV!Kvk=n zQt>ig-iuODpSXJE96(RUu_=(un3MPrfasO2*5j7F-u$QuxtLsWY9FoKnHgr>XQEbXL%i3ORjA_Nt`P;tP zFhUm3Kx2mxD1EM}j1-ySPZ5}Y=@gtU;_V<6e6{q+7BG!`VMX*K_1l4uYeBE6_))&Z zU5wgZ2V#82(XNqR1*pcw{I?P=e}(V8D^^!Btv#1pCePF7NKTs-n0K^3@je_Ou$ba$ z?${|1lhw&_k0`z4*;Mm#wuR{{+?G;PTwzp}O7%bPQ^RA)XB6K${zi(X>;??#xPnQw z?UeGYcGZV@6;GiwkdAu-_X4m7rF?6`G=$WuzcPXM?H^&+Za|>iOtrT*I)@2@)mq3O z=69y5&pdl0Mp%`9gt|%v3pU$W`J^i()QY^aw*;(Y4u~b1Y3GM<3#LQqvb#=95E(>G z5=>YsN#X(0Wh3tC$_t?=0*%i%2E1K0y6l&g%>H}H91V$1;fYr)Dce3TCWmM=Mpv= z5)l@+txG6`d)P1yg}8R!qj-$Be7u)4QU-%8dYk8tVNvp1oc=J&K%pf*^y)p|M z(#fOI}o^~ zt&YF^jD_)bT<1-!=OMF2hdTwxLG+n}C_rm4H!;$)-9tM+>`+*JAjYz(JR&&i7BT_E zu%CSrk%A1^HvFXQ2C~A=o1{~5ciqGMG;i5l{5IWV83y}2^FM+pZ2{xU);08Dk(7%oMCYkEp z``=s4@jaV_i(BZ##y$#F>~r^UvB>)P)^aRujlrX`n&*IR38r=iaru>+sV_@>tz-cK zk>rOR;YRgJmd04w;HfWw9@gom>;77{)97~6QO0OA$?bM2eq*r--y=ssFK|XpyEe## z=~y6Z1hS+YP2i=XS;_5VC0{=z7+ERfdA&7I?txkV)DB|PQZRv{=AOgJdJtDOC$~Id zIEiqe#ou@ZrGes#liGZ*zimPZ8$+G>CWpg>Y_}ybPypByz`$%Ff^GRP??CAIu1%gD zO4^_ecQ%XduWl+ms5a#PH^QS4UT9dTqZ#wTGwL}>{!xdvF=}B)=dniKTKAI%r*f$- zo-WCM;j)Ib$^Sd|ukVpZ!umoAPP-5d>ZB1=sZ-v>0p7I{TX~TV2V+~)@ zg-#5b4IEA1KbjUVG(*Gi@fH@+pDuXVJY%4K0*+`f-Sgj=9z2npN8#|6SlC2k#|Y}CB3U%JLuYk608T)$zkyi%$A#v-!pzCZBW~8dN@3LXo;PZ-i;-F3KCFjSrup@d z(tNs0H!~ZEUcGof?L$CM7Fj90Czyx+VpfwO3d+GDnX@vxT6sXL>HzrZkPTVAZhv$E zP-i-hBpqzX)|1L{mF%o|=^r=^qUAD>qOb222G&xf(v%OqhJk_-n>xe`--=(xJG2v< z>+LNDMx(yF;o*~^t48zC+0M56(ABoy4DFB@Y#v6iHmC6^zM7!V?bffjiJOC{pp7Q4 zk4R?xA{xNY_>fnAC12zWXws@#2`_CwfQ{h#C9vRy=@U6UAMMeUo3+Aa+U$BCFX9S9 z3B7rJ%eYDcD{`+hg>oAh45REh4lp4>_%6qeTuj;`NsOoaiFPhUkZkL4cx`U(5^TA- zjpy@ChQwG&Ri=ioIRhd3r`=J2d2L&zSP%VIvxDXhCG1t)3U9o9{gf8nV4o^WY=Q$z zM7xCC%a@K==fQcY^HX>q@jl&@ByF+MnY^LCeck`4UDCq3tzc_FU3;0*>P2RNY)A6z zl(^{VphgAZPe3Cy-;rak$>%a4nw1{ST43Ql;PDncZi|*9;Hn)O-tER?wML70aheo} zd0}X4&w$vRs{66P^En45R)D&l_2-qDtdQ#G;mHj^l!I8(!z<1nt}3Sb$B9JC;+}Lf zs&M5fI#F~};`@9@b|T+KrU4i4h(ks{8YT>_^f6WP=gBp1d<QR}MWw+O{&MsIGUQR++fd_SPAMKI5b0hpD=;US|B@pF zjVNd+(+}*s`TIm1s*5<4XCC!J$?OH|l;s?XD(^dVMu|_=Z=mILt|X0tuAMwSJwa5D z*}|CggzGSB24@j1uvKs--x*(l={adS)(NCQA|G78)u!rcnGNc2?fyEtBa5pD{`=_~ zh=3DCoXRfRO2}OmQinF1hl+MxF(gXM_0!YA?A{(onbpga_sT7#W?rPv#uXqCvEq)o zM5n`46ov@5iBi>a#bQl@mLtz@QaX}TNTQ{kq|7o!THoTn&M3&Sw-0JKC=_N@daE^7 z(8uMWiiG#YsoN?==`=0!?JKFCNgE>&>ka`%Z+cJ(U&FQ@FB(3HGOAjt?;}OrwSHfR zcivE|zn)^K;PA*w@lLPgP>TM^Xx$kd##H4v3U4;#h3Koq2JZ(c&gz{mB9|C`S&5P{ z#fMO+BO+KwCme}i?35j{$YCA|fYa%}Ww~ZDR^HMR?&`$Jzf8BJ9KgTNq*x!A9VJdt z*}jP~+j^!sslV-IYm&r`&0`p4M3v7Ma*ro@gWBWg*~(Y{qZPll*usqH+l<^)YRFe^ zB*Q!(Gu>#tdZWCln&|wOrM_AFcg-TkJ(VHL_l?1K#^46B+w4>stpX+B586zn@<%_( zpphXt>2xZZ!B>VnGAB&JEl|CB1e`?;eg+*r!EXkC)N#{XW^|`Bb!4c0z$4nQZ4$nN znCE3UO*zBYGy7O%{NC5Up4-fNHLTwg2)qhaf?vaQ#j@Lp+?-(g0vx(qeh;w^twZ7A zz8(ez4>^E6eZG%4B}QKAM>b_lJZ#pgMyjxt9sg%+aGmTuJxnjzE3mzcYRaq(Q=!_} z!91$WP=!IEr|Ez9s3@^t)_2LZt}~}C7T^=;)cHRyEu45tI$B_k_v;HbvAbE~USwe9);%iW8v{U%-Y(E~3TtC3Q!P2*Q|^7l ziaEvF{4su_8xb9fj%M@#7t?qfl&#O*R?e^XG~~8N;MyBDPlhJJW$cBFss5IA4dd&Y zra!X~1BE2=wasaLx}sc)ZAJ9RPic1N8iZ`1H0n8G`@!#J`+pT-BY(^ zv=%ti{Q=(Sx*aoHdz+v8=Z%6Pc%HKL7B`4Tof<6uYOLNq#Hj6LM%@JmVDFih@PsEg zSmnS|eFx*EF|~^4P?WnV`B)Q?TU2-Uk+^jQJ#an;m3=q89VtyS2NNq)aGWvm%`GSi zLy#nlg0Kj22$y~uyn@&<3KQuf@Qo{xY^5-60ru*DscDCLarBNzZ0P8Vpknic=~b~SQYB! z-*OJd)3iNc?lLOQ+^x_w=CsewT1ua<0kbOYMxd>#VvD5rOU^PiDIR*-bok}kQf99` z8vjDT%&{^y5JWU;7Q$PaH9yiR#dbU-$19Sq;Nk>qJD1x1NkeTl^~1rF_%9{zKG^cW zv$b&n;0F=a@zYdUlXot6+*j9|3gX@=1c9M}Z(Tk9s8W6hYgIv4SMYHG5zS_eZbx7`^O;02Mz?nyO! z8Z9*1qD6iUWSF)tN2+XdW>o$O_Oz7p(Of82 z=}#enmN$GQbPxH(^~UIryZhv?BdkmyHGQ;7-jM7TFqIp5_ILh(5W3Py+RC15V=p8) z`R*V%TKX- z3QR&v1DGo6%h(TX84Dt5i>f=wL1ux&s$^|M-MQk#M{VC>;PWOxBQNwWmfPbD015$&or81 z293#vKyB_=ass=~Giv0^MkU%WjmeJw&%6Av=a%AjbFuY+xRo#^X7gp%!HA#@AH+ji4{j#@<8Z#kbY~ua$bn-X>W&uo7$G zJgEt`6|iEhsS!_x-p1%MMtJLBfoqSffWM@~w_iIi_~Zr8zoQgy7QAduG1qws&zxAJ z3mP#?+RG6&vGu$A07h+aUP^@--?h*KE?ohYPFh)+B&519fw;@WOy}$wi+OtfZ`$nPAJoP7U zaJ8v)+@N;1I#U?kfL=qjHRKK^Ckm_RO)iNb!~f)e11w)9$8b|8Ovt&hfe?D4W#kKG zjy*4yprw0H3F(~>2KN}PEq}O=2&XLCg1%hV9k$||qWl<)jrW1{#vaS%bEb3#AoHoq zfB{v0z-k{_Td`JM*eccaSLjG=`<|1h4ihVA#cLNsuvi3TJw{ijJ(;+nNEbwBDh))3 zpJUgOR(q?{YQ0au!_w~2J<%90YV|v3pbGO5NySU=&j9@*kD#2HGA~&9mzWbuh)~Q} z9w!1ceeCv#I&`%(ZEsR7AOdhAC*OMiFg9iypi#qhng-=RY;+A3qPFGDRZZ$;kGrze zm2;%cxyXWGN$EDpvFXcFuBUort966}OE>oib@v=H8Mcecd_xuJ>{p2$;-G-VwgM^r z+TawEw6jDm7ccEQIBt*NJ;rzGr*_MjEeK)H8zn#c9htFOJX4lV2@&>N2{GZVu&;aU z`KV~OlUMf_cZVz604T;ttpCj>N{V)xDjhdWa8LG9<9c|MTMJOMNCVAy&|QgbcCVdh z!*y?JE#kLWQ4kI9pc-^2I+qzwJc@=riQ>aS zXc6b+Sh?};21rfA$97;sl#dO$Q$~0Omy|a2KJ(pMM&X@5o_GMB=gXeRFo#M~k=5d( zWtg(bZ2L}BTAx=eN_OOzh}CKiY<%x{DtsoRCH6CdMs1M|}nLUk!LKrv?AzIuCpaSU;)_nw^d3ziWN|I!|0svggI66W++^S*)<# zz=5X=crqh)g%R)Lh;M(X34080G_q%2))B4OJMz0`Tizo4RVJZ{fG)W6Jop~EnH(fD zwB{EpoPgzDf`!IE4j09Wp&QhDcjQNILeZh`Fc0yyu0VTjPcyyFHv0QqocU2?MEYe zH#p-Jm~T*Qji=_QIm}}S>yM26gQ_%j8Nl?`B^Z>Qp?=6~8Fs*puTkZEikKIGkifR> zT#qwWy3W3Xhh0%FWQ3-jNhe#9;ODG2JtAHu=gKc#FQC=S>8ylX8FCyf3emT7B#IB< z2iQqXBO9!^(L&VU_)UePH!wyxh*cfxH&l#6u{b*<`9u?fD!qYDNhJ@D}LKs z6uoyh=r#vRNvk{DV~lP z)V~&U`55oXuWaJnq*$EwZA!?rj}`*AWz#Y{gZ}f!x@h#3r1mpcL%yzqspJg{BdWX= zQy5LOHRFzk{^XclVP=*Z_y&)_bEa(sQ%98#ZEOJ?KYN4Z!a%r}CZ090cJAcI z*s3CfmfnkZixXNFytIM zWz3)2IPgqp`sMQC&NRXm{UP?^GrjNqNfq2UJ0!X~fHh#gP!~8p;+BK~L2R-M#{bT< zH=;%-GmZpAihN`ayzO*PKv?vQ_}P-F3mANpmCC0+9j$19+1r75P&Y}uWWrKhaDECV ze#XDje+5-~T0WlRi}jT&*tEFDU6HuQeBpKSLu+%lu@Lg79;>g(z&oqH_ew*Y$~^#E z0{Eg&SAnqJ9?@XFYz^kkQMShbQa4Zh?&3pSVRr3+ayTZG{wN0fVx}RRQ(znLR<62h zQYR|a?Gciq;;Y>SI5@8Ba?5O`Ds#pBur`C%=GtpGa$b$E5no%0SRpp{eL_gw&Z?B~ z!^JEJDmFDGmBbMV>Uz8`#tK_chU>yOaY&3~c{}8~6htv7Po1oL=Zu2Key;_Ig{bu zxNN$amAA;UD$RjY!?h}k)?yxXP2T$dd+iY(L_U)ou6$hWQgvPm^Oep=h8uqu2@=c* z$`%pvp*eVoToEP5IbWA_ys0WBUEPxnjC2Pc*`L8UoWI~gt+MB_go3nIzC1#(&McI- z=6J{i23Qq7-1eGS!{db($b`C&yp*Rz1S!PW>|?}7SRw)lAVfJ*r8E8+OtR-@$-(;`69mx9X;Gb;u(0f~5+sCIpYOC8P^R?*qmvJJui#9j)3DfH z!+4a{Zb(>qld)o8>Y=)NhHi)Hm*9LJwqulbU!0X?0Mrx?Oo!*qp0VN+8?lOms;V^2 zvi5%xuzCL;1jw5FL5RC3LhD6Gi_2F7&E=Ye>I$_CxG*!;-e#y*`F2kak5g7xkS;(;Rx%zENaE3i38^*W>_38;@n;u~pg}MkJsxxNKr~maZ{`fi5h?-kJRi*$; zR}Imm4CjiK*ks3(QG}*JEc~$hnVQWkVmiu074ljlC8Uv~d_rl#XXEwMl2pC3SLGSX z8=M(=oxh3vs&dWC#k}1Nd@(|>!gl40n|zWJAY9y({GpIECy1ZrmtVu9gUXBetTr=8 z#vm^QEfc{!2X64H}H$DZt2m&e8a1f`5eQcd4AB zG~cPL>}^!#56jzzya7a!JIIAj9prQw#yKwE@{c-y;~rH-%YNR?rX24e_XjbQnmq*9 zUS%L^O)(yCi9kgkH^F`f)uuQ~@j0$?CSb6&$J3gxR}$$oD2uPyVkB7N&7z)kBP~+L z3FWo*!PBD|?~L<>Dte#FVA4ZENp>I@^L}ru1xxl1rYy0`s$W= zZu~Vh?1c6mBw)>!At9$SkUddy6QrAdlscW4_Gs7$LR5OYnw5jBxU^{FG27xYi+xvO z9bti?HhLuhawJTrmOG__x{iq+8;*h71OuaP^=9tEn`MXwzxCrI zb2x~Z@nmSTam$0yQLX@`+538JF58855w}ZXpycc zgHLt6AYUN5!gYmoBl9*hnVe)y(Ota;M!iY!hQP}kz3iA z2k$g9k7pevVC&Q5F=ME!QPR0f7UcTHNAs?={(W6TD5gEnaU*Sx*L0+Y zpOS_=9#Pcb=GDYgJeF0ttYcg5S_6c+Lo5$%yS2*jPd2nwq}ha|6k zXBg0Y>yaORovv4Us=28Md{kd39iz7#K_ zUawpp2WS~u(^Gxu6KmrFNe$ALR<37?Ct;vqAS|?9-@_zOsk}X0^Def!aqt8~giV0y zrQNe0URE+1)Z-9WHK_6Bmcb|Q%pq|Q(FcCBtCeJiugMkWm|n5H-kCW3jj~##L|b$* zF$a_NhIqw-Cj6BjGuZxcLMo>^v9e>MNb<_!n6*VNZyU6UDMn#q$>?XZW<6j zY@n;lwDuUf5!BRh#H$2M=jl`B+2`vaqAbM5!{>9^(}b`Rlso;|GP>h8!MRQ9K0Pr` zpyzX)PA1Xc<|fV87uP5(1nE`PaIdSu2fW16iQFPt84lQs-9~@pt)+0+7*R0Sye38G z>dwdV%CVeR9uQwdjXmg9p(1FP=mVUKV}aStOl;$5$u;hj6D120VZH8e$LO^IdY;f) zM#dQ%!tpJtQz_3Q8cmc6P-OKxQdO*_Ar(j26pVjOd27K#3i3kIu$38^-5rjEjDA^Z zlZLMGXEjxPTR0I`>}6X$$A(v;-R(oc zf2)ZZ=%)3075>#vQ{H$&cK3=@=r{fDf*{r6GPyEm$N${$KnEyQ7FLAm7bO>t5bvMu zGlOlOhl04NYs=*X`-f2l8f0WqG^1fkZLz&tGUsyqNh5g5I(DcNTmffDHV* zZH|(Y0K%od-c<>mgQaW=wZv22ya&n;L+Vf^?om7Yde1S6862W5a(RKqxaQ&5J`cdI zb3iZ^s^fCQHo-y>#Xt3FcF zUN22u?l=ms>tci}OfY+qnLuv|D>lsp>wJx+z1Fb&C(mo$;gq}~#>rJA)S+)4qJc3Y zw{@PU0VV-#5|ILjKwOa@3{?jbr%2uHw*EK;yx}f8iBFhiB9qz)p9GL*fzehcizb=A zlL+zqfLp4>mWY$K0j~CGs&7r+FUKUm>A367vIjS-@`Reo4A03$ zR0inMVqs0|3ph?gS%o^}qa_u>wR>JK=D}Smw^z7+VNt_@Q$>nyOo@alYswY>m;4`! zM7_;kGHYLWd*9uiFCp?2KwnzbAtyZxpP#UftDb0<0{u@r1l48crzqAAe9}DZ~Dm*_=w#aLjTAtfWJd?p79Ac4lc1e=L*bUhJwP<%ppT6LD zAm^k#KA}v<>(emP@MX^!JoqKTne^=M-S6{jC;+PccI+8v)_JA@ZXh~;)X)XA>eSv5 z21H746)$3%s_U<{wMMciE_5aak?R%j)cwaBWhDV5(nJLq9C0>S#5evTDZnq%PU}Ot z`A&z|l6R<2rEXkJI_VZ-Fj2cQ*bRmtzi1CW?~4t^rj&u{Z-wjUsW6FAN&h)u7(3;2%(lX8_Kh4>^sYYc*{zdBztL8Db zxj|EXRm1xbMmKjK74TonkLtz1xW=(M214vO>;};{JK>G3!p@cp@T=aOJPGev&1a`> z4#)0MZID0?-?0K>yraQ9?(up33tZ2C+T_RhDBU7TZ3nm@{y1 z{f~QAuzx5f#44Wkr@CQvq_HJn<(z)Bssy1kT8)Su#5hD_^KHA$0r2`_Y(f$ zrJ1T#d2+-Q2oy^D_hx}^?ST?swg><>`P|=4%lgLi!WS1(IeVZ!CCNzGrW=df_;jpm z7VM@<9)4U=T+EY!IEO`HnS*eaU zxezcWKQH_q;>NiDL9;bKLG(wwcE)!P`2V=lG(fCF%g-NIsv4)^N@>>xr=9;3Ly_YN z9I~>42BSPRg`UvQ9Jvz-eLWWs_%C6Xegfcl2WgCvzLt_o1E(=xZ2ncU7wAl6NEqHv zTF%nTgH0PMAI^pM+;ogW##%a2B6)D2;3+C|=NkVP{Kd56N0xpj;x(*Q2Od5;zgpMmW5+ip4MaRQ=2EvT0GE;mR zqLO|`K##79WKn0~!NbxN9b*iD1Ta1BSVZI$WBio`KEaLC%U!{a`Pb#0m+y+IP%)zc zIM7VMF(a%g8i|8jGfQh}zP1&9{qmK>zU%H;0V>YQfZF&P0VDUJPxXUd7TFT1PRm&% zPe9kduXgZIF(*2U9h54JAI>v**s2e%l(4lKURJbFZrrpf{XFQ`O?4)rIHgxP=w^iRhj#ge2g2trJ!g!+CfX8U}B z>Rf%@hVk_T@A6O*azY{_bbsgV+0J+ngE!EDmrAU{z$V5Egt0l#o_rWm*N-!=q^0KyW;`m=D z>UPsWXq0A(^`Gtx<*v56heANfgRHbH>~yzP7YiOm8i$=y&bL@EMaO;f(-AK8*uc2M zF-2%V=!!ESng*yCQ?hfRSFDd#>yD)S)^>h@Vk{R)w9FM|%c49f@N*8DG!|_`VjzhW zu8Un^RH1@NbGa)>)Z-yHUQNHya-<{MeAz{JiXlWE4#r_)?Q&8>8v)HQbeU7+u#zKMUQ_+`J<5-D^Z%CKYcddajwc@ViwvNoP^Ha zlOo=)=aC8M@D2xY-$>1hcNsj^?~dR}-^L1{Xo@i{2lAHdsCiQwoFmy1kKVATmO1h1`Vw&R4$pr7V8=8wd0< z6Eb<+k^I0I<{q+Voe0v2qOrd>;Xj_W7xyokPdw^fNLENS7wKA=r!FN=mZm*C_}u5^ zm`3*y7EiEyNCvx_TCFlkk~y;e0UBP+_YGwn^*ysdCnrO3$v)~XSSnn;=hO4W@*qm1AR6vFi(rdu4{7Ua6IC(NuCX0Rot%jXI zWhf}4rsM}HI=g}G7gSL-#)zC_escmS6H7C|XuPhBS=59bL55oP6i^e0%E-9z^(aGsuN4W3q`Pj{WA} z0f37q<9-*yP9~z^m4Q0lD)ex^NI)6i=mko_i>nzLZMK zjb&h4x9Y@HE(nf&L!Kad=X(o`5C|BA){A3K?)U4e``3lb3vj` zj=4ncDlQ71h4F5aazap5;l>ydlJ~y_*tWbY)!@^cWW?RDvqsqabL#B|mKL7&#^}DT z054kfAGIiab#`cUqE`-V`YpaR@yRQLSm!E-+efa)!gx^aAm1=J-Gr%Y0I_?!Y16*# zJ(+GfLUoF4e5KFH&k+=}uW|r8Slue&M5j>|1sfPi2ars>nTTZe6bqTagvkan@a!3l zO1RrHv|h;!B=D`=^fEj4XedghTesB!HTYHoqlTc08&kDdbBy^b*vp9LetBpUU40|O z?40zKm%p;v-#F-^dH3ixfLT9SFZcN}bKTaSAQ~yF!FLpKJl>G$>f3k}qlrWDLPJ02 zXEHry+@yJrfu*pN50>?U%tyf~IdFRON%aXsP*&FJ#5JX&ioU?({!F5S39E97mV5zl zveja@XIVDSRxK35X-QH}d__y|&3Vn{rqI3+9vI5!jb*VH$1KPyTj&T873!%&dvF8{ z$jWCJ7!nr3)A9<(0jZZ^_NPRevuE4~V*&y$Sb(XOppJ&N_7oEe>hW#am^TvJXB!ia z(fTi#Q#{vJRYEUhS=G00sBFSO5w)SfTt$bGu^djR_HtKHj>Y_BSyFoBxj$oMm9rsZZ6iSN}3hmV#>u zY;;usTxe+3o7CSuEx8NzEQd8Jz`)7Zp>{BWM%W~7CjxO-Tto6y*6P=1eXMqo@g{Ds zhXn>mSG{K)*9Xl(0!eI);o|^!z9@tiM6nHRK>n+K_G|z8;m4g;V)1CYb~KMvAW8M2 zR8q=9?N6KE&-?c75-CHE`Tg{Yzpha7k4B=GJ1zT!m|?EEHYG5N+|vk-e)^HDODSy( zfe**X#9T;dr-Soq$PGH1M!DfJtUMB;u5`GO?PIz?xK~&o9U3i|VCdn57Ul3BHCQpj z3`uSiEUXm5-d|$nH(MQXi^DzGuRRLyfION@3O^2ykdJdN|BjA__(oFgeRlKzuU=w@ z7M!LMITOQTOVS~tL;6fzbzx*%Bh7Y(f!3xa;laiPUSrRq<_`w1ny1tDdf!? z&kFCM6p#+>8W3ZkRuKhPlsXar;Kwr=XV=ioc2ZrQ5a-sa6X=blU}l&m5oQl9P3$O> z7dmg5Z~!Z2vq@<@I|I1Dn;e$e(cx{6Mb0A6NMVH#8$T;_NMUGWyLJ~@p%F44eWnCi7A8TFI9_|(-k z?jQJZfez;B^DKa<6*V5(2SGWC86R+&zCBzY_Hu=D>a}6JcdGBlEbShq{mI^`g1Q+5 z7x$rATz!q_9EpG70@JWYY|q~C3jjln*5>!fgCKW{pA_mVveH5QmV6BbxmuuuP~Hy4 zrYThtjxP#a&90JmgvpA5CLqr;PfRAB_yB z$j+m`O~ppRV=^v7RC|s#Od8aF+d3iZ`zoPCGf+!`{1dK1E*Q^I{szrOXI$bnmd={UBfK&8}g z4C?VxSvNbvvR@G2BKLRbX0Vr$U&0uT7eLW%-fr-0A5NPUgPU+6E0{*VrGl(utk+WP zEb`>wD!+cB(wz3+lH2SHp>;)>@f}z~pJ++cT zDBP3mtDAMMe7~C|0kOzCN4EVDZ%e9g-yapi^M^{W_d#S@8KA^ZSm+txgha<>4DtWV zbF!=@DB;ut7CamzI{Yhs%cHutc!$1~1}C@{a^xhYUFTktsh0f#9k_gjJmbk$XwBJq zmryzWmXlDf-p!4mI5E1)A^#cbM3qgtuHs_Sf?y1}5I~x*n-|UVChRy97}N675vIdD zJLsTEx=sh|M0Fg=FKA=}9TYWy*r-$9L}hX}C}CfrSn3zEi6!^Thvq}Y!}HPg9~kM; z1=)o-@Lnc0@^X?iFY4WUWUL){K~{r(gM(SVpMj779|YLgj@j!H7M6iwmgsvndnTJh z9uC4;-;cDBbS@rkAaLhAIpe5eW-?=aiMFk2I4mLM0?d<&WpQN!T`F41pN(t7aDo>AV!!Z|TB^ zIWLDExE2Ty?i?>ieWP0+A6=Euq`L^hN2^9WyS_SPfA++RwicfQ_RF~MwAdDX|a=gQMb6=LT6EJoU*;!-5H`K6aGTVHtWt6 zLFYBjs6|#-pGMCS=gdG<XWn|?-TzlC$t98lk*E$i<%p7T|nic#pJ zGA-@Mnf8+TVsxjC&!q{oL%A4mSx?e`e$F0!=&83U4~B}YB0-q4!$><|%X=NeUKv|4 zR}u+9RQLgK0t1R}j$0%1)Dyo^y7?_^xwDYaqjvl6g%^t~1)~NEs@=cT%;c6Ce^K^+ zp)3>}A(<#T4mKO{*FGtfrUUooZyQ#~`z=orE5|zQUdV_W*kvIE4&s$ zCgX+I9kta~i@+~`0m!V7!z~c<5iks?O%vW_Z8T_Itv`BJIv=^#dynWsDi*ds@=p|w zjwy&}8xVkiM>eX0^{AJ`%fj!fpWK#DAFnxaRgXNsCXq%sS*Ovpht`2{7lQ>robxkF z2?nug`$He^n*PI1P9@sPIC{&N6v3}4HZ@~(n9mPH^y6%$em5yhz@Vl@y zFIY)dK7lc|!z}JAg>t;BxDo0q8yJVw@Q@_W;;$;s{7sgB#{!5jz zc}lqUuFSf_T^O>C*lR-@FX1+_r6Qomz$T7JcMKHW+}?4R&fQ^!*&{-Kg~$ehKB5mE zKF>4nLu$wFKaprMiP`PnMKch))$biV9ws488U~nPaevN5PUAoN|IOl(f-Zw;oW@*k zw(Ka}d)xB@I`^%cdULV|aCV)d5zmS0uWHg2>spx_7ah*Pe^4fb2iJZxCv=1uGKMlV zDCk8YwZ=^U3|+dkd&eQM$)h0VuI>)-J4Dv1SBM{W$U_H_aiz=zH~|x;>KI6m35_?4 zZ#6bi#xTmB;;#%Q6yv|@4it!&%=W>Lt?w@O_hk9oB z9N(Znp!TyQ?rtIJ!*k@>#`gBCCAYO?f6RzJnBniK(gP4nqr5yM{6RJ_Ey@=)))%5H zNbS?t7*9p%SpzkofOQv0)#?X&Y(IJ|0t$b%7wYu(we*3yX+(i*|FT1_JvV`oKWcC_ zEe4&awYbL_I$v3N3t}UrTSj{qf*FVC-wC%+en8`KEeYOfE^IYiM6S05xPG+cGzA~h zALV%}75I+=$H*S$5`zewdN0Pw6%P*&sZ$miTXa}#tRZrLp{~3%cBY%Y4--{TT8o~u z^PY=gzO)H(VerfO*=Z=O0&UXRuPqp{&i#J}EfV(TtnqwHn4EsEh zoHvkmabmoHKpJ$o8)31DP4|t|M(-axtmr{vj_NB`A|*F)Q_YW8`mF%P44zlsPzQ~G zzam{qy=u$+Z_!qd)ijFc>7W1x64=4_SEp10Xy!L+P-ay0Mx*5SfpYw>_-AtEl>Pkl{Gw^GE!xi?o>JW$D?9A%RZ} z*Rh1TX=r4lA0>oe_dm)~|JuntUW-@LnjN>Ukfg(SX#Idc{aguyUBXD%gzJj_zAzGb zR9}B?ONt)L&F!}7ZHgbx$pt0>H7)4WVn8dP(5-U!vD2;2Y(#W!IZm=c67|HCC>lY<3j zJ^LM02#Qbx#Kdm;7K6Jd@wYLOWOlspL}KY)6_niR^Y|c>O%bBV-h<|KWBwC$4|&l& zb+CSAty)2gvwn?`?De2VkW5nSm&TZV8F!$W zg%KuqCi$%6fzN#+$N)WC?xpx`{zv5RV9d}n_gn3~g2|{sxJNXfVzOsqusSD|;UadJ z4>hm+O~;awey=+^HeOu6Ljq=6FnEGeAeh#n>6&3w3v`9GnQ5P!J1vlt9YQy|xX zd(~z9jt# zbH2kbpnHW|8&yu8IDlc-=$q__0BU3#)nybK}1H zrg%t4*R?s=1Z{bkF4j8b$pO#+F4BwFAMv`>4xgQ?zbxT(_ME`3b1PWOZANVox6a4! zG%OL5JQvwMt;tNY&p(uMoy=BY?8ro$HEDxD3>E{k=j6gn=k z|5zQUroi?W+QH7R2&uxO!K=3D5Lb%Mzyn-UTmoIsTxG^bJYo)`{Nk<2gZ&<+zaK1j~kqVKMg zW_{kd-Cz|{^4X9*IE^p9Q(fl+<8|V56FxvW-3ssfleQ&E#zV7LxjuP zmibE1kKxzE1@(6NM|uYuce`V=I)yt8GEWp00$ZHC!V-`Vdz2?%a3k1VRK&_^X`a!u zDs>tMoFMjgB25V}BtJXl%S&1VE$F`O@Z*v4Y`6j~Yq6MgeXLD2uFvoGY@rk(dTR>^XwQ8=Wxt2Q=!b1%v0vi zmZ1!lvHO13`s^WmzrX*z_jOW53HFf@PeYah-Z&7`6mp|*Q%9&PI6|rg9uH{cpRUGwk_sw!c#%&y%kvhLp)SJJe zo+mHTY}@=bIyosL;jhif;>RQFc2xSi{KgeK>n%L8u<6oH4=c7CzBgiE{yN7$?o=Or zs>X>C$F~?o{EG*hikxPCXtVX#mlo%auiqN8ZOhG>wU(Gzyqj%d*EhP&qelh#*9!BrQTN;Ln0>%x z<^9aCoId9+{c^s;Z$tB+F1-=_vi0MaqyAB-?^XM9{+jZjSI^~f8TG2oAM~f+rn`Ip zcwiyKHyavIRI~cD)5Uw+ulfDaqf6E|d#4P!aevLptmz*wS>-I6-Dc5_nH5%7d-d<9 z^=q0o|MzOfhxsKln;h63;Z;HCV=>259sO$DhDFwsg7VMTD>$~eS8&d?9IH(=+V^`2t8>0sU6~VA-naUMuV*y9uUJLcneUnsxa#DKPJvgP zp13=C+^xJg*D>gIxL?mU!><>^j0` z$%e|RMK1Ds8=l{)`CG7S%hN3@e5&7AvtrK8)olWOJfC!pTj1?s|9h3-d;M&Gd22Pq z^RCS}v1i7LNzL;M+d3#JneJHNz9Mznl-V|geNy`${cXyaHn#OgEOzVp^ZotZVv{Vq zx=i?E{17vF^C~arD~c@N26fGCeXjQ&&!?{ww0ZwlY#(nCeZQK2euEkfcTD}Wd6VA` zw;7pS!*9UwiWNrOc$jgaOHoF{ZIz$bjf>c(8FYTdz!xXZB~*O<*VUGLMoj28)%eP9xr27ZDjmk~-4pweEJ+yT%$A2yi+BCr>ZozWj(XwsHua-1Ad#8DJ zm9RA#BYxdc)ZyW}-){=JsWNYmE?w&XL44b!Ys`;L_Qxjef+2@k{uA#-sX=gMwANRbdY1LxeCI17> z*F3QeNVj-y^QwI2hJe(XH}-Dc-halL9+9)OX5M$42CH0ZH~Q)9(w?WYo{usUvVSgB z3!#wKG=e&BA7cew7>GMBX7i&I0Sj)9*z{+=_rGu)T zeiQGz{TFdpUNetm{|{C#4lc59GxGJ(t0TsnuBdu&dh4{GVk__JvDNE&+@9C)OYCKl;zm2Fq>kTsW}3OToM=754}JbSX7zLk+7={p*+9d7EK!;>49T z%dTv=yyQ#Isv!e6TehpzK4-?dwTsdws*BRanOBykANNqL{M0JH*xm8@tt-2lDXOiq zav0&azT5}@d#(D|hweN)H8J#5hh>d^US=_I!-K^OoV4YuSIrxJb--_mzbqI0{r*x& zP3J*&Eth{-yC?ru?ilOA#o9-i~UE_larc=e%wZcjoAh%0m`6*_bR^uBZ~w zEPh$hVyB;;Tyjm?5nZjJ&4mWD#I>z#Oe@`8?IQTNpIrY>QOC2MvoBr`e6(+r*5{bl ziolwC5}!}599U~g)`b@1KX$a9Q0wN4gxuay^P3){pC$! ztbgAg^Wb`PafLM5}vl z@E`LrVeqaBwV$;*li2Xg+zzvTbFX7N?ZPvw-`lP8%dC3O`d+JX3&O?+S&kmM`NjIP zea86D2x_sp#k4LqOV2M$I?-r+odo|{n}r$)|8%td_4$x^ixsE$)c-pEtorYQHKvbO zT&p$bb8b7C`&?_kBU-PHHy0M3^|8L~EIQYUZ(S|^r#f|-?ELiC`NeL2*Ux5XHniKc zb4TyUK5fH8_uV(`ZL#e5_pU#c$`c8vlIe z+5VK?t$zB=Z+RWx%GcyO!m3@FdTsAl#|E|!GB+u{{AuIAy@h4fd9Pmws*fE1^~w8D zw%up=*HwfL*;#Sfh_vPHnywglwav39x&4-mD(N#*8QsfNoz%s&#f+Xl3xZcwE%Yka z!nvY+#IfNYYi+pfY=0pB>#wfQ51Q;!OkcmK=WP4Cdt>bb>>u=to)PBxx!ob+70;vB5v_mGWNp8S2<_N9Ru7{-#yWST~$LvU}f?zlJaQbIFM9RUG1bxAckq zyghZ-+!Hlow}d~LdwI*=&@%yzw%TS}WjZbkyuDE!)}YtL*e54fZa_Ld;R&Zp>DUU-RQp6yji>|BG)QYOxuk!U zj_#JNIv?%aQy9MV_R~66W9l_N`Tkdx^Um#aKXqxfyu54X?ztB>Jgu)uK~p z?APyYnUmsXd7;&ypkZ4Ue%bV;#Zj?}LqM2awD|&g<=I717cyTQPfl>I?eI&-xP`f~ zUX84O`8ww><+Tn&Q*Z7JE%a%f<*)hDZGMkIKE6ALw_oEKZF+vjq=I@k&xYSxH+P)v z{28s^pSkePJ$zKiwU&XqA9#e%_6nKSYL(b`swNfpRTP69$dIME&H0u-PFhBJ49-mZ1JsV zpL^t!S7?;2_D&5u%ZBxAE`M0MW2uE%&A}J8=fp0l*5$LKWEAp|Fg~N z&fGSaTD4j{w6JuE!z68=nU(uB?a`s`?b_oi-67S}!>{3F9^IDBeePU!iy{f>aed~ z!rzfYCgcrSl=-C5-Unkhb`R>;%r&Ohpu6iw_8W2IMbpM#x|}+)z4_>@q-JO5w-TQZ z*RC4ABl&8z``di$q*g0PZTaidCGv!3>;CyQud>ZQGqx8$+8yYn$efcr=hL?0>rcKK=Y)taY0TdmyG=i)tC zPKOZzJA&`8Dn6L|C^f-sq?6+IzO%OLr(de#GxdwMf>)nw7H{r8oL;TKx8opptLf96 z<|f~+cxuAMAs4IrMcG;Gi;gX5G`)&X)8spSGL9EyeCoe8GQ9q+>fzhA#?;ChGN(^$ zGus}rfDf;NpN<+8f*;P_(`?%5O_z5M&KsJgrT z?$%@eOnw+R`ANHNPSqS;<-Piy>vJ~RYkkKy<)flsylX#w(%KqJo-TwXAg5{A_ zmOC!4>pv`ZaJXvpUuXTTmE-?v_^jWM&B;SImL@kUvD$bzdg&i+#o?!W*IRvDArv!nH^!RBsreHvDGy8qaHY0@(v|2MI{d`utP)U^6+abl6h*v(O;Eu1!)&Rw7A zbvi^GS);4p)YdsM$)`5P&#yA;ZWFI&Cl@r@6QMdC7h37xUswMV*QJ3xw{hFM-J4Xo z-E92R&dc+kKDjzEx5ka@f7iV@>!ib)u_IgTYH%{O$DhaV0GaiO{b=vDU%6dnIK{eIZmAnSDJ~}A%-@vz=Ha+qR9?i_Y84>A%I*>Z#vBiw-r952)ATQ^YUI z`jv}1G`*}zT&Zok_5F@RN4{>|J!IOrfbjNJkX@v+p$@zcTC&w;jYnGiCbq9*KL4|zuyFj^@Rmi^<8NP#YFu@q zcWy%Ik_Q0~8qQO_{kU#_<5ZuN1v5W>{&&No`I8Fgy;?ua-*k`Z@^a7Ix{5i&y`4^~ zlg|jZs!hu~mzLJPjeVpxdbV|xINbMQy9@DkE>?Q`7IV$k*1Yi=axsA_gxu6(EIZuX0PyB!T)f3E%2FTL;e1;d*^>*>Fx`5^xh`9o`u z`m0i}+Ac50EYb!9{*N3x~AV96G1%nmD*dkloi?9lQGne|E5%)W-E|%%68R zs${anylo4IjXfT8qo8>0$7NkU7LU2K{&=cI)k-~_R2BZ(Fyi6|&uf9Fe}3fY`RnYV z9S6Ma_#yxJhQ{hYqUV_oufF212A)>sf2#5Fdi`!WD_p-i{64aptdeYA=7M97e_mGG zQ&Dx`>mCtLx%6mfN&6QV&wsX(8<-RlEruzkZ?L?o+^PY(9 zcbj^~XP+J1p!VG75BxTKu-#U1*`HVZrj-7>yu~j|j^H;pFP5MA%j9XZ7u0;vIc>s& z7oQX7m9&-zPc&QB#rxpv8&yWWuU%o;aHmr>f9jF^@87*cPG)WiFr7O2%;&prPpH$% z@9P);&}MY(&Hn4!Kk8TTsN=#R#dAk{4>m3$rcj?&MaQ zG;d^!qsiB-A7{s;?^H!qI^j2^wP$#xwf{QLJ!hI6YG+lL>)Gti@ivPa+)BN4dR^{| z@o#+P#Z-=jB_E|iC+J-m{>_mX706hED!xh0WHW9YT}Bca@Kx zx%z6DCcx?1x^-_xb}cF2!O<;pfAe9c1N`g~KHZa@czmtC-P&W_+uq1qxqr0DQ@>B= zxBNSzvP&PA)IZ03J#yYAS%4>+$r(%R+ZuNuAuYdHr*%TlD*r;xjVgl?!F zQ%9WP)8$k2pwM>XrggZYwytISxzEMSlWqGRJJw=T;?@fulRNa@F|3o~M0DIl?TlnU zpR+DDfv#81dTdzQOuot9^B=iMOsiEFoYlFTrysnquWzG3y9=M^?U*sDXR-X{^i5M% zw>~`n$Q!#a1+vCMo#NQQ!3WZBfAng2*wwO0PRZ@Oxh9X#{(Wz!-M|;4pN6GWH|rlB z-mAn_VSDm^8`l=Qx_9~d`<$Fk?>#1d*yQ}#Zg<}J-|wCFUo-EIeF?suDrcr`iWt!F za%;P3jn&H*SZdABoVe0@>7l__d!6^qkDIvNd69KdR{r)OW2d?An;Y(yTJO=bZV^up zB~{Aa-DZ6I^q7@{&&fYLzWsaP$u_T7->a6O%`m?)a9!!g-0NZPsdefvd9OL~s#@KW zzC9e&v6E`|OkM0Se@0OKcZ~-%%lgBv9_9-=vxox=Xdw6B90p)8qyZ$;m zF7-vG@Ttlvr`IcL2D~ZRv*E?8g!Ih0;eWe&)UT6t$zJ(-zzRFJG?&Cp9fLHxZVhU1 z^Ge*V7X_UXFUR%zQ0vIg8`~6KPjQ;Lw!<%YvWaY(ot%nYM{p_dZHWz7$|9? zNz##qL{HPqEk`q0CWz`MrkWm>jh>rcw!I=)*k%jiGNGrX#?MAGSfRdbqUm9$zG5Qy z+o-cmgm8t>(@x`OuNmxMD+1l$zDAJ{?x3;Igv&H&6k?Mt3U|{V)wQ~j{ZcrW{-Ca4 zVRb>{ugK09veO^d6~@Y}u4u;EWow0u^t`%4xTRIPCfq*zxge%LsVnrfv3joQ=^)V% zLKFrv{&rRuvh&lQf`q-*Tl9G%zhW7!>huGRI53&5^)jb2dCNmu2x{KhMAOfv${?9w zQKh>jgssxo2J#9aHX1*LX0V;6hkcdK3Qa$UDue6Qd7E2+t`gSQ~RNpMsgxjfanP`A@!$cF}puTOQzG{cmoGbh#61kZ3d7%Ez>oS5_@rNP7PW~TYryWH!xoC9@ucUc55xUg zkBhOY&|xQGU`qJ)QCF@#eaI7{5uk*JaW5zcMasv_FiHAN7Ac=t6e*u@&Gn5uy7Z3v zaatrjlU6BX(FRE6@t$@bg&shiWgaPimxY&pmZ(01>RH_ssJir4J~IzgJ_9=!g|RR2 za;HM1{Prs#54Hhv4k7n(1oCy@(2I={Fh4YpzD=(KT>-m~La-8bV|v(09nbpNn|GRf z7r-zjNQ~)cukSvHx(C2liT2S?c2R#0DDnOxcz?43l_2uz34onV0OTD;Q-=_{&Ds$Bx%a%WGoX1 zl9Cp3gGnH!i?Q86m9(21MzU}{kOIf{0eupZG?42{qHsMhamRuZ=~QRV+(6=vWF?(2 zs{&zQG?Nd+AShP{x{l}~PpAby0@?q~g(Uu&=ai8Sb&!4{_#aE^pHK?7Gze#qid&2u zYAmzJSf=-}&@?yJ?JT#K%z^Q$MZ=TuU1)s54S4j-G%CnYE21OlAJG^!U&;gbA!;uG z7Y3Mcv%Fvd?9)^v><7RGyXqT+{h6@yQJV{FFg@W`dBGo8GcQw_(4PYxCgJFecphqD z^4su<3Acd`>1N)bGNC_0>_?f=Ez2>IXc?wC;t$vb);W;4DHFgHvC9WAUceoI*;J4r zyP%vCDL?hbOrK^Ny*F)RJ4t3c$xDeFO|M2#t8 zz8XQr1Rr)Lwut(eV%TP=ubXHF$r`0=%2QShR63~dn+SHw;z#Dl6+{RRiC6PLC9!In zjt_7RWX2+@iDRkS2GxvHR1@P;wF1?QVN?_UQnekb8Q-WTF{EmHRD*pmK@91u9Z>DS zs%@A==^8L+`;jFm$N>ozOgMbllY|Zi2`zOJq9p_jR?3)!O!Y{J1__NsAqjsV3Q70_ zQAolch(Z$nKopX&j3|&&CNhJ9sH-}xhD?vb;G6LE&+0=GQGN8;L zpu!-aB^S_!3CIQq3~vz7$h}CwA4oz1{y-8E@Ow$@ekcjqj}2J8BzghM4hjgUC?lW) z$p#^1B%q~1Ks$qgHe5gj6OfH|%+m}48VwW@@CTBRfZt1^_@N|ZzaL0K0+y9TFJRd* z0Riod1cXzPZ1}Jw0cjm01sQvTfC?_49TSj+FN7n5fJQ@}1pHnSn;%L-_WOY(B;XGu zApy%uq8G62n1F!xMgo#ol5qI2Aqf=*2^|a)+Hnc(nS?ALBOK`@l%f~w&+><&kO6-n z3Q70_QAolch(Z#U6-6&$*+Bsb9Sjm;3hwAugkWmPM8t=J^`V4Bp0!`?QwOFYzh^@7-5bA3~13?o8KZeKBdJQ4Wuwc7y(&(${3=`WKGTRxJ z>c09^+F606&mj1hfVI+Vp|6Abr1J^Nr)>U@wKiMBM=2eWrtg@3lxD5SvTWgrRcF#f zh2S46gr^B|A;cT&7|i#($J}Gf6y5rP)*DIg+l%j}f2m6g8I*~Fw9@M*ve62gOpo}ofWm_a|r`t@pll-5<6@<|hAi57_?ywgQR z;+$AiC2mf`XIb^~^(XDGK)I@nvD$~5dG%2TVR3Ut5nDE(y zX`SPf;(>2R_*DtNT4G3b!iNJBK6@m`;=%E$0DODGuR-`V6GLhdz6Hl;kK|Z9I6f7C z??Cvq3BOKaNL|9Wl1#1 z#E^!BUxDMZM{+D49G?oncP9Ksgx@$ZqzU0;(}?6{kK|Z9I6f7C??U)Z3BOrlNOQus z;rQ&49E%6XrvmU@3Ez$ITO@|GB>ajTpFNUe@!l(bhFOOI{rVSYq;0B>SZei?jk@v4C*saJ_|n4xEM z;HdAw7xl*-i8Aj%M|sl8IFy0h$V5NMGd*;s68G#YI3q%J_9xnr~xT5MGP-Kt1jxS(@*WP1NnD zImEpPMsyOBh-%7=CuDz!lLkyy*7S1`{EhO8 zpQ~oDyQYVSrk|JKZ4xs7*y|6ga^z%k_u z_zfu-j$(rB0%NlWoC9y-aqb)v!de&y2<&l0=}ic0${itP1RNNCa^gp)D=7Iw47Db za7*w({91?Gkl&#stWpLLM`tm@3|dL!9Wu_3DD#Ny-!ugGvNDKJQ(}c6uSIlt!|Jrv zWorv-f0?zvrM16}W|h(#bc?T8-9VANgo@VjthWv^&7_TX-FXRjD-HMixRX0USNrfI z_1FNc7}+a=I^L#a56NEgGOQCzI&CBNiG@&yK`;r*9+EXLmq9S0<~-hci~GueygB7G zdPquHR0e@j-Nt+b2y1~SP5^>IYk9n>H$l!kWsq2^lG-4|YtPE}$gj7G4HcoV-dyEc7>4Xlk%Yj$3@k%$3{3HlgMAq|fPpP_;4OM^ z00Rdyu#FD9O%D!a;2;K8=)gPm;2;JLW?(xVc&{ED%)p@xY_9`Tw&JXXGH@6JJLtfa zH#s;AV4S3o*lDPQT!G362C`rcWejvu2O7p($r#L%!A|R7BRR~H!E6}pybcz{VKxk= zV6e+NSTu(z7|f2ra&<5jhuJZhJ%ioQ!6tKD-? zcLw%g;1V5pnI7!Hz+MdeSqEOF2Ybbxq%_QvGduOttq!957>g^9y$gd@^gqkP1&wPcBWDM+V(sw*WDq@u?_5j#Tr z5;~BHc}%~M7YSCc42%eYj3Xct4bhBDC#Cf$%nGF--|e9>&Ajj1oyAF~p;L*lHxZ^J zvJFsBWgYQ3F9=5vLvJ1!w_^?T86cJr#+4yVZNM>m@B}Od86nU-mS6=at(7Q{)})-jvWz|> z2tk)&Vgb@+7^|Ql zbm!rHL;4AseZ(gYg{5&PzAUR@lC)8&!sVtcY@1rrut2EMcv}iCO03Ntu~wIfZATTA zCZwqv=umLyhw78!m9c0bU{>L)REkv?R!m1=DPpiul%zJ@_nwhm04&tXC^=@yuqlg1 z*kBjuW0K>RhW_V*$$^8z2c5vRBSR;2$%8ssOZco4XL0*T#>z^~bfq%}I*nEVYuf4H za>G5WcBd;X(IQQ1ktL|G8SSg|68mwW49MbCDiZ+ZF@{EY-!yU+os1fFHfq$?sNB@3 zEa4LeCd3$c)^Xq>=H6xO$&O=>i+C2_q9Wh6%-tk<(Q!uj>er?*uQk3(7fBAH?5L;g ztMm|O>ZoGphEZKjRBL@l)li|MuQH|rTp-T|9-2CfVx9e=sN(8=%4Hd2h+&;B3VFDlcX`J7Sze*a_pV59aP$7y63_h0^h zY;R}O-i0!+ar3O(1{cgXD&IFMUok2ZKK#Jdm_*V!1i3Dw2(p@ne;b9v)+7`X)&MktQt#Q+qecrg&gXkH9LQN@eFC{E_ZP!y;0 zVi=P{2LHb$$rOc?A&hk9=cwOG^$0x)IVyLm(?luV366*)hVwR#x*#D$p&o6X4X3am zkKg%;@xB&aAz($Yu1E$i3Q?9~5O2=n1tN$CRRSh@pq^p~4a?6r^(6GYkmI12INrFj-#n5l>I}$&|)rcQC z=jSo_aV1f0FH`?QmP$bZ9|D^EQdFugu~ap|#k-kdGL<#RIxwPc_%l-Fh82}+6q=DTO@L+G8!x-R?c?6(x;~o{S7@60GTiF9)mcq| zOP^C+#QLr5OUES`clG)!x*Dq>|7(t}@D#Gdt3ya$3wc5|K|?Gx z7S2DmD|Ob-Qr*zt$Gy5OtTWg(;ZmQ{v4aV1)5cj632 zBj?vJQ9sT@UW^4oQoQm{AZ#&3E{Rvts#BgY68rkaS(tO89EdXR%cP}i&5AP2-fmS{ zMrI+!sI$z}4^36(nHDCR&UQ_qt-9@jpC_Mf4X4#~b|j<47QQdl#3&MqK6 z3!h8T6|H}1Ozo~p_?DXJ2*NvJgYMAu$rZ_W`p_t$aX=Sqc*54DsCXqUvBiJ*LWj!w z5k=#jJBkY&2i+uWs|dmvi$`)lm-4BDTM^KM(2AM`(-ZVVCDs?e0qfK83KXI`2t$Pp zVeodag3JWauW~vplAb5Smw4Lu?c3K>KIb&fnNUaa z5Wf>)*(7&wVn6+>somWH;;jxd)4XJP8Rv?OnDkPk4;#HWYkB1wLZ z=-gM>%Zv@cFj{`qteKBQtv%}D=KYo0u{;UjmF_zS)gq+ca2^Ip*CnL z+lf^djRK*(TTy-eo`G)zPD!qK8AsfW3|%f<8$W*S*yqO6UOp02e_3~XbHf@q)U z+s0gKlde^u+Dx4(2x7nP>xnYGQF{*U^r<180sQPlw_^aY*3L$Ks8fP9w1+4P6y zOwXELGgm3YD2{e1DJa!+wkHWpu62r0*xn)H=8621?n_!YBW!3bio!1k}QJc1#BA4M1#DMc#gTx z(i{;XE|Y>H;4;D@Wh^R0dm6EGSsA$03_ine`f*BPYihoT^B^JOYDv=WG#wtg$a%uL zpq?q~5gD9MGdmUEGju@rMQoJfM%o?Vq@Xe#yQFrU6SDN1fkx6qMV!d@5{zl%teMeX zNwmLb?ROTHI4MXREw&`~P$0e#Aeb7Yo=KI#1~RNu67P>#s1MA7qbTt$DT$6Y4cxM+ zeK67qG!V{NjMyiL(iC0qt55Z~X$OSEtr zIl}a`=||HNis-l~8wPxerb#j@)L&1}vqCVB0w4gpS}e?R?>6*LS`bR)se#JqCcH0s zs!SnItqxh!^DM0{Ul9*>1VwdTM%zKvmociR+8lEtLGkDUPd>JV;WmCv+`O_~)zS z2ebmg3}^)+2jz1rCmWT2H!4pwD*uYI8oM^-;8_vsl2UoXjW5g-10_$C>`Y1kitm5V z&+=3nC8lZ2e%yN5hsdD9rA8UW*PYJ7h8Y4GGyAnr0+&9EVv?+ryNdP$?Lz< z%68Oi&%DKeg4+!_{h8d3jRU^ml?Ss`t33WCl%nozXPR`FHZ3t1Csv!&x`9osX{L-) zsO040evpMWf@#t`nx@uVNXu5#0$S2326mjwQG*C|8YT!jzn`uQ*2Fj@1$|b3#38F( zeFyo;?aUT4m9>0-rAR@3kfvN)OjWoZD65nxlS?53*jTZlzhFV-@fofbq=~VYt20<@ zEC9Atgnjv%N$kSeW6U4T6^77ku^j+zbmy?Z(2=(oDYoq~nsc;App_ z_IK1qrjUZ5G?S!wc9g@U=34;+pj48!*&Cx>WwpoAl2VSOfHK8a5|R~=;B{I4bl^?e zrkR6{WF>~*nJr2e-=+1YJi(oY3|5-h(UB(BnWB&h7}lna1nbPm7e(mT6`mAtd2Je& z??l9zs$vviokViet#L?vUbf&r zSPD8xvewvZ;(65KzvR)RMSNcvQ+Puvg%T-vA_@;9MT$RNWxEO9P&BSus z++6-z0w*C9ipRw{PU%k9-7W#*L z-m#8DE82@h#^yVbEm7xo83s`j!dxY57theGxiax^1}uy3eS&c+jzo=Ar2S0#2Rs)P z@o?o2TJht}gFn3ZgWL#}q#`_G>4B?{_?v9?ksS$O$BFL_T~05l3*Tls%0PiORxyxK zBC*wZUr{1abmm>e>{iYMvsOT;16Vc<54=&Yc+2B&vHT5zmK00SAb!}-HGK_7yvA|Bo z(R8+vwuTdW@Sr{e_dP-3yUasA+Pza=W$Zc`SH>ql#FK4jn9J;O3+jfVu{xaW{`H**)Dz|?cz(j z>uf8Z@2<0re7?KRHu6!#?mFAZ*YB77NKQn4NIv+j6MaB9 z(@uU@T8f!y(kwHzXqGh5ED}GCsO^b!1bhu9X_jfyMAJln-6BpcmeV>Dh~q!kj?W4-DjWtDsq7A* zVQGOp-A|zwP1PkPDw~-Va2%z;Za&&U5X)oG2%o{zw4JUgU~;qd4VDakc2vyUT7eCF z`T`MQ&|GgW!1)IZ`y1^1F6$F9aDNiJ9We~uBIE2NL!iOHy*M7h^9r6=Ih~TncYz|M zFnP>hT2MTJwP{Y8jVH0Tm{{XCB4qfEFGxXd{5guF-cB&E_@@GXB?Dn!9={nhFgW+3nqJ>vc!M+x^inmG_xgLr-yX)FJU$=Rrur*=c?92s z<{EU2riy{!oVXiL9fF~^^pqKHXuO7Npxy=5^mLV;&eBs!Pou6)Zer~Oj;K4|YhVKb z-G$N?@6K`!x+A&q?m{?E2pj9CCzh17 z$P(W=XYT@FaSxHs`2zV+Q<8%G6DRbjXZsO|6}~wB z!lAuVIsz+a!u`)1sLpgE4E{u0kRlRiAR6jvm)A83*&I&~-6)}6`Fug#4XFuz1<=tG zKR3c^mk$sR@~Y!M^D+Cb3<|$}MfszgNqsT^II2yO7Q7^rZ`@|V%^3F?{o@EaJy%m}yA zEWa=eY7^}eY_7BMCf3SEV9`ZE)hP7quKj`w6T0tLNaOeyiW5fT_*?I>d&S^C3~5?t zy3)bVhlyeBCA@$ zDUp$cQA@%s;2QdNC=ie0&mg63U|?Lzuj0$PxKxl{WgK!@TnQFcx*vv;;C(~fN|AD} zzN3uyGMc5_lVCqWG=qjHh3%#Uf~eY?6p!aWSJ)GZcM;d<%g*8geOW2aMwybMsv$%O zf@D}8&>$gGhvG?I$-@3`xJQ9IFivhSiS+Rto-`~j<0&G!d-0=sOc#g_ezGZ%&6z+C z`<(Hv;EdION84F|$D8uYf*T11EZ~+4u|VERED$T?wZsa`MwLhK!8VTkoO%lipk(ng zb)wMxP94(-*+=jASr{f%FK?_>rTuPaTE~@MCY)vxiL$-w6u^2Fz~I_Q-Xr}89qUog zARA7MF)&D|F?{PPK39ioqKVaU6h<83H;ouay?u?@Vbyj@&ebwq+yC56C8?X=BveKc z=q$pqaY`B!{k5F&bo2}ut_$Hf$wa<54NzyXZBS7uLWZ+Ez63)Ya4`g{I?{_28HrQu zE|We;`$`gUm=7h;ub9>#0AqqDk9Pxc8bfL*K1p2@`?78?@oqUr8U%mS(`d5N={W{K zDq8b6@%B7lv8iH&EUgy>eg6Ayfw(k6%EG-kn9*6VV+VbuDYT*{9>-Gx!2jM#KrjcV zgF@+N4d`@|?gTJjB3r}sr74M0Gfyz-;cwEu>2K76SxgwczJ>}LjBot{H!vHjC41gPNWAapmE=m{Z zBpO8xhx3LK>ry*k?MbPc(g;ZG$p$?#~PnJLDkC0fC>#aprtQ=%Dy$^ z6cL7eiAcscj)L+z*QAMHuuMKftcq)Ss$m!Mgj3o>JW4BOfG+Qk+~v3b&`TBSB>_!D z0kd4%FtAsDG>@rJzZA#J>XNZ#c^)hAj6h6I`5n)vo`G6hqIM2+fuV>3rq-8?&mBS^ zZxL-ryryV7YqS(?ak8L(_DNl8rs{=(6e?47HCESVsq2wa*X(KJ_g&F7DLdyZMo5|= zXiE9(8=bvKqx7tDMTifh=>C}I4S~uCil@t{jB}ez=#OGAo1;nhvPtJ;X{dcU7ReY3 zVM!w^snaavUBvV+=ES#IlB%g`QfE^*g;MTYK-Z%#f}$sqiG0pnPJ5W!OL7pZ2gPAT z?j!itm3v%3Igo8wJ7ai>9qucRK3GtE+`n}S&U2ecrMfMd{;`MushW#5`} z+7p9ncAR@(s-97bQhSg5k^efPA)+eMB*y*| zMe#9Qc{w$mXo5ryUyD2qyA){W8Qfb`XE9R^Bl98>n_xiJy}@XDOUUH_VdkY#c4foN+lYCmHSo=qZKM48{%1SeQ@i zIfAEaTOh$l9yc}7et`xsS(}Z3N1S6xVxqMNSBBq9pbd>l`83|=jnI$xFmkRqAj4@w z>Bv1(IE4*z^^>n#N>sElsBnS@<~NN@+451IK*!KRL42A#;TrknOL@X<)Tm35Bp0KC z(3|k5Wh4N47mDb1EgZ zq4#EZr_B;d#VQqQl`u#sOU4*jL?OwC4bAtMgCNZH0ys$Hqm;%cGjq+3EPPQ+NnAn- zg8I7sFR3r@0n|t5(u|kN7y~FX$Ln|MeJQC`cej+~`!c!eI_goYn=vC{- z{hYX{Pw%byJMQ#-F_Whj$m7?7NAwfQ92e7$Bwqy+u`&};9{;OuzKZC~*5xv>O$Rnu z1ezhLzm(V0hyV>*J<`gJbYh8T87_MqV~aPQQ8Tr+AT6aY=vFEId4icE0-7Cz=FTvK zQtQnJVFb+;{~PVyFU!#0hh`*nKN30?FJNB$3Kwb%nS;IHDc}e8QT9N zwMT2jGqfMY+Q%8S7mL~v|CZt__Oub7;)(5N!B3IpXGaV}jM~J%riTrSMHaI4P!&Sd)=! z!O4jlESaTwN})IF*nS}U;Vt9&*Rv<2fzlyNf?PE5g%`2!XF$i*$#G<~s*{O5y7H`3 z34RE)K!okZ=?EN)Gvd$0SjJ<9L(2wyBY6v3jJ=e{(-W9Me4ay@EdGqDDGNj86N8m? zkXmdsJ-jgxWw>~NeH1J#N>iwnJQZN{?;D?k%wl4q^5m_sx({Tn`uS2TYJ-DA-iBDA zucHWA`4zbzxV>bJDM_cNVYHS&XD)md&9nw?@N;h77;KCiq&IOCQmd}>(D)qH5i%Ul zdx21d*oCLw#c6IYc~|Rc9*~y5iT2w-rEX%NvW}=e&SC>Dx~LuzwYu0E$1TA++Rqri zktuF3-Ac8Q7}h`feoDw=vd7p6W{<}Zn5L&5__=WX8ut`et1nk;8|Vi|0-lIJzWCv3 ztj|z#*L1Z+43fDOK{$h2vAa-(w6TZyD}XlmH(Jnv7f84e3B+_GB1FqeB0)}|)3oX! z?BUH$6fyd?vA%KPN^06gfeKP9^=#ZsGEk;=5`>RTL7&y(AMSKu085howHS8L+6?L! z2S!gLZ6O@}#5Ncwu3)e?L8)i5SmaS^J^9{SCCEWvT*CSH6BGQeLRC#8bD!$&MU) z;e-SBb^d<57e62oyeFt6m!e)6vpPkC%1&I`GVlyJ4Y&&6T1s}-8HIW75xPqSoj7n@ zc0&*9p_LqYH{0f3c9G+h!0%A!&idy4x=MJAmaBAWjBO;t3BZf27SRH4!H+qOy#^Ze zl`V;-GX5e?mbRl3feRe%T|C7TZ0`aSaTq|JP>jh2$Sdfgb&|T7^i5_Tyiuo{=qWRt zlVx3J26oXYN81b(c|6wOCuOAF5mTI&=rBknR>Z2muOuO}(>=bMpWp$IRtp~JT$A~T z_BP%Scl(Hq?~^lk8fX}gS>9}pK%9Xw_N@?TWI-oBtk`@3V}konU$>XEB6)I;h7E4K6r{FgkjtJC-4pt#0j{(K+kiBbs;ZZD)}mv;y!)ZS^S&I7$qbt4jsybx^nOu zrXLD-y(lWkc#yK>d(d?KfxIQ5E%}bd0@@-9`aC~~LML`#p>an89de&gi4NB_G#I0a z!WI^$Ts5c-c`y%+y=){*&3b6G5 z9|}LHs0L?;iXF*=2JDyCeqxz8O$HdrzBRhsLy|SYj+_i@CMmeGYpjgHMd*{%NfRVw zjuf`yhYD#AjjfOU$&8fom^txurmpMuDaZPV# z5)2ZU12fk|F0F3gb}JgDa67Oae#Iwr3j0|8N|u24eru7?9JYe<61c|se!n?lG&~$P z*~fw&7$l)HOJTBfN0RkyP7ogq(n1V7eTB+!><9nn3G%!sZg zmUuy5l$@2^qOS0_a(wVlgz{+cUxY8?2^?oJLtl0gQ}tzc@gFK9`(g;T)^xXn=Ok>V zKK<#-?KY_OrK@l(?vTUM?2lB;51|qqkfPYaN6bkzjG=0KLGvTcb%e`o6ye?-8y(!~ zb^gX^sM0`<<^@Du2VtI=hP!I$f2{;3kEP!Acmk~Ff;B#wWHKC|`28=u#s|~jAR54v z1S%s;d`nJ5K}ntotnX67^Wag>niC?X34@r{tA?0b$|vmckH|&%7mEu>rJZ$-=S*1X zd=eLbl(4>6!7yoBeu(8tc|0Wvpbe8|2V7X4901Uq$Y7ZG5geVq!lGb&8XLe}!j;hON?A^IRG2hXB%Igqc5uU$%=H3EB;y$CX4PI1g^j z{^*iMk(ejhmR*b?0S$ITE1j!wM~t7u`*kH5DD*R#4Onc#d0(0wbdzu;9M(T)wTws+ zQvVJdolYr8ET&GK0?ALnEBA}H*fs`dI=|4(Qgxi79~;OfT5`J5N?&^%ty0j87BI#W zzIDhmRDFm-o@8~ld=M_PLma+O#C-lgjV*b6gn=dfxB*cY;v+)ZgZDDv=p7z7I$MaR zG0~+lW@n6tA;MLrla7&GEum_0bfz^et7blS;fCB#nb-U#;U5G(y3}dz8&tL&%)!1D zagoeXX;mSGC1RSmAOWc*d70$dLkx6{p{(yAl6l)pI4qEJ&!;FZBZ>mlbcRpj~Vd`N+woOdnH|NBq2{V72x*6*+0cwilEQF@A&GZbCOrH5N}kRlTRCZP(B3*DhF=Ua>Q~Y_gf{d`Yf?UO zppl`E_1&;NOG2_)lRwRYNIDu~u8c2fQ20uNg06Q!iLSuoR>yEPXzJu=8#hF0spOHJ%b@ABsYi>J(CSENQEc6+ zO9{l6D^cqrp%qiyB-3-g$j4xC=3_ejBW-^x)mOU8$5%$*vZ+JW z&Hb+sDk(sxC$@?!GstzQTL_g&M9!c$%3(>{f*wo;AuyqlsU?9G0tBwjCDBbS`k|4u zv0!{&vj05gmrDWC{(=fuDf|?gF_s|a0-{(*kxx3a;$-?iLGh-$guKjQEDF!&Doft_X=9_m?1c zQc6c924Z}|FQHNQ5nxflJMcx3bQH$dgQO-Usz^;ig7J;0R(u*y=iL-qjb@DuAGqSb zk^@yRpt3_7-UFc#dA9Ndc5`XPd51!)bdb(5^}_1R2JCUt{C_)P(;hZg;&jL{9frlx zE}mhu*@j<7WG(|8pd2I^hw*4#UqGS_b=_BPS@*s`CDFxlQeT~P*j!|6n0z}?X2u71 zd!*>2pcYXuFTUZNFPDC!t6zN@FgV)i%r(n*^$Px>+L+tgI|!S?YqpL@6MpPiPuGOG zIKIun{Pn1=$=?)dEx>&c-z~w0Q5e%KDF)MKe$Y)Gs<&ef4cT$j4$eyrtK*aWz<@=q z$l`qGQXc;^VKX(8IGPY@M~CS24A%4{g$FTB!;@JyFxGT=YE1o*!C7DAV1~wJdL{zK zzIKLUYFQ)qqh4u8%ZA&S^-QP4Jii#iViL7Qr_vgLZ2)KSb7buV!1zvx^#7yM{^9l0 zG`?T^O5+>*YQ#5u+y(Zg3n%ec$?({>>%Ix|NIW-f=CjzCD)~xgH=1ll*JD<8r>Mj> z5oBV;znO_2@IB)De;E!q>TLuiI*;Rbd@+jYeirQ->Iq-{V(#dvNcg-ssmGPS>9fU^1c=nc}0mR4Ub+Ulr>;EE~O88Pe)Zi4uz zl{KcFDWi@5i#UVUI-&_SW!>(%+9-A=eSdhmnbhtY5 z26SmqbB>J2(@_tk4`#ZO#)tMaDy98LX8RSeJq36l$?A2#vHA_{VrywL9^1k+e3qRe zbMN$F<}Sd{QEG50g}W&Nmr{V?WsR8)y=kk6ViLb*@~RQ5ZLE=I=YGC~dxO{7(UzKD z0IaCcUB$$I^NlxlvroGBLH*ma{$0Q8pT{+RwcxNq!1)lEGFqOyu0f+`MnVeU;>9N_F)QFv52}DB`wu8el z-Jf=38zXdsiuR=0j~fF+EO6z`Jfvp$et~pmC6E71&FQi?wZSw{qr2*lgC6RNzH$yO z=w>LVN$QhwC=|O`B7K+0@C2ee4x=SfkOueksihR5s7lb?(`WagL5|HY5Nm}@&gOiH z7CTrX(b&kv`q3WZfdJUz2fUpE@_&U26e(z6h+*tLAIScNTH_d2;c(eYf!v%-!%?JR zZvpajZuo!j_U!>tRonl7la59X8Yvk!smQ3Pu&gktkPykNC`~P`$h=-Fzh&MTwK4-| zK#!*}QZswo`(Y2u9+*~u=BT%a`7JZ+-t2uwtV|2ZN`9Zu+WVY2Gl13i+xK_=m^o*k zwbov*z4m(_;i0NCikz-KRvraHST{iHbbK%t*oWL7zZOo>v#z{P;%vm<8J?Cat6H&! zWH$YGR0G{*(i!3|TTyoSt$MD`I1MB9r&v+!*ac1+Sn3BkxpqeRF#8uYC%y|y9=oCA z1Gmh=;KC}-o2GpO8^z>5i*iH$Clcj<6;MD^rAqDptS3XCo-PbM0%j(e6LE%wALmk_ zu7y^tN9SW(VF6Z_fvIUMI=-s0$ju5P9d@W1ME6jG<6U^G2IOVKP{M$`R6D-V0yM1{ z>$gKq{4b{8OC?%tggE0-hP#@+2PH=oGXL7!Wh#Wwt!UoCS(UWZe zgkZIzg5KH>svAnxjp!j$)471cgawp5)K|5IL}E10;Vj!AD&D5a{i*_h=9Zf#=ye1= zs6kb>G=pPz-!K*nKR6b^OE%s;NO?MTu_x(nh%{bco-s0HG`_| z0hh6k8I1)=9NQdU14qCfBWF;+ZZ=~$MJ8tZ(I};07#@%d9~K>#!BfFc9kMdwA zE1kd49h649)AbZx>1+WrS7;Za=6nKAJVu)g5{QHmOp%mIuG5dX!1?J=ygDh z=`~H+OATKs_GH}^G#Jy-P~dC5#t(|R@?t*OfQw!U`oXm=(YIpxNO|7<8q2fqG^adI zLwTNrP2Cj`38%14_k}_%f9x|N;I2g=k&-=~^7yKLh2JoJsidR4Reep@AB6dHxKlQ0 zB+jz2Q0J-6P9ava>av}7w<_Bc?zPKyjy1-)&$Y^&`+iojbDwYJJNLy_u5({%W$~V? z5+Q#-7EhintIF2j$sm?#D4)xvAI&^W%6JypB?jA=c58s403eqGgs+ClD+wIic}u#w zpwgWHd2#|VE>~Az%5|}%l3-mm!4&nH<;U?=fU~5qOq3G#@Dt+sdxvUOafLX=fMq$7 zfk*rgHGuQo@rq%(Cenn?HWhn9Hz|z>+$NpYP0x3ZfF%I$XX!=_#y+sFOg}MYzj#*T zg}VLCJ~SbbTiy)3YhZ-Xvy^BDkplf#(8*tpmMO1g1DqoZj8WTFw7#k4CYVc0Da`RLQo+Q_X(RwNe`2x@KEmUQbM0}wu8P-5LS_Ah79XnbH zN6c?=HNn*svAw>}<}rFXux)wJ8vGr3LU}57sj)d_Rq+uA&yJCZcXX*FGRJsf)22vhshHPfWwdNYZ^}vgG?8mZ2PstQ*k0s zXhS=6ZGY5sGsuq&*~VN~LNgc>77Q5TacN-tLX9y)G3z)NC)_O>Zk2+Y9=s(z3CGC6 zv4hiaSGCM8^fLZNt>h4G(ce_5xK*K*Qby5-);Qq&j?Zdc+I~P=F}@Q<_m6Nplx`lA zxosa0>3L7)=K{73h5|w2yVc-Cu`nfCr07%)OHYE=tXIH^al_6ZQg{sr{Ec+3e4%?{ z;3OummA8mq7UwFx_%#^X_smaOog)qOM(R(K8>-+aye<&!ILHwSuoMK9Tp$W!qFQPV z1Di_tJsdD*oQk7p53DD+=-Ud|7T#8o2v0VD(B2`V;M(-Bsm4OpZwl9?s8pg{`;chB zZkJ_6uTpS4xY|9HJffHMn3&9SqwLw_=xG3_>-n(;FfBS;yCtQeKS_~mBXsDZ!Cm@M znR!ud9;!$D5R83=3>liLKr;G10PXn1{z3lBtiH=mlnzic2#Tf;x`0-%*{rSo zT@fME)LKWj|MlrF|4t*_z!z#v+G~!?h8hq%J=RGT(oK=$V>l4x?!QJ}lJtjv5W<=L_wxD}oO5RAXTD0=qGgZJqDj z=UHbt_XXCexQB?tATRwYH?Gl@tvxM=F6KW$){g|(JC0x5lII5VRdL4w#eNNOSsKG< z&6kQPi*7Qj20U$pLha=^I0sAByojlGwIcZv`lD>>*#DBaf!!QrNg;$+XDf5p{@Y_@ zilgU26E)U3x7qE>z0?dGPS)cBkexeMW0h?xx(wt*eJ2g*Gr_w6a)2rp`{g;p?x6*U@=`U@HC^o3Ta%7JB=GV?v*9POOb zM?5>k@uJ_;kS!P2;)p!MS&8XEc_(*J*DC?e{GGhd)I9c7^x_-P@eUE%r3$m~EpkA{ z?>h@`j%)l9umvrsV}fR zo`1ZQ$JHo@98bchebJ5d_mDyeUoEg3Won(D9w9OyMstvbHLwYrM=-MVIXoZiTQldv z$??C1&Mw`k9P1t2!<89oRY7A|#fUwm_GlT)NO4LCrxl44298IJ%wee~t-Ww&1bnL` zEG;{(-pBB^wCr@h2dY&RVOobGse|eUY$HYP&*Hc$5`~kZ=@@t%_i2wHI>&}Gitz@i z9`5#Z59OSRp`++T_&NH+AYgrOO4;Ie$sAvZO)IQ8W=o6%cxwFSA_m|~z$?IQzBL+)3Dr7Ij(7F_wlPimyTLb;`~T((aUkAW+W`YYo@b$(DA-biD##K` zbHUI}Fe@0y<^3Cw-|T@I$h5}4+4@g^7Ea?c(z8L)I@E{#hQ9^20U;lxyhBv~0L*x- z$&YoQlz9w;uJtNfwscoEqmT`uWCRIqc)BkzCty4gwIcW!*+s>GkxFsp9B5n&Nf?V3 zGYuaUU?aiofxB{6PX^AGkmk}Muoiau$}(18=tUsGAIBNHjqgk>0c|WsJ|KrvX~~xi zlD#CkN;G=qS0s5&&npy&kYJ|eb~O{?KPk8-8GG}`ao$YffYWC>ODuoVEEZf3agkhd zAd>@c8+%RU9<7Ea+2aGIAx57_S$3%ip6l9Yt}rMd^Vf5}oUR|<^;e|kL0B2p7r}X; zhP@Q}d=;ZbS9&ACaFT(ZxJZJlc;XO6TU?Awpt!tRfvR~B@cTNzjXgM<&KDX?*0Cqd z_<;IlRS!wa8#@QT#mmFVi|1KwO~Wh7_)0SBgtA4)S@hJeNbARtLKb06d&a_l z4qk9Q%W#0FKC738B*^0cA1YLU9?SWSZsJE(vfdlaiZOmh<5TKq?Qb-7M;h&R4gDI! z>wl{zD!n}IClot+I|rEY?=krAiEU?TenirxU`2U;2!WsiY;+{u{?exMg(~nSS`Ome zGDh;6BPc)S`eRfTBIEneZ@<2E;=gM|yT0)?+6jH39?ISm%-p411BZML6V$-Jm7c}! z=gL4FON!FAYp!V>`J;LVc}<^am`lANC4Ha9K)|(qA3X&^(@|(Y+AYllZ9N*#tbpNI z;(A3l^>^v|2ZNq2*?uncR;AkJTBZ*CM?`SYII@o>qi8#tRU-eVtGL#`p~`+@+)TF5 z^#fq#%&e$SHQMb8Jf`di5YE_&W?Lir8CubLK63X{4DG(7Vxb*0C$TFIHNU!_Lc%F1 zDr%{i^{`H+rVI>R44Z{=j{hYr?=mo*XFcHD=UVff`vPm0bDwYBE zG=xUNqyo(~hm0rO0h7vtj!px^0eqs|aGx7=q>VwUF$`=gQnZ1Pu;6ePj4OFKDuecl zwaTR0tJVGgb%aDK#l?{=gIYdEQOFhYvYp*04OPLgIl{h07dQDpa2311GY_@4DPOQ; zRS!!NQW53F5^2PV%Y+-`G+X5aQlgt@7Xni9qrMWg`!l0EZ9$ntSG0qQpA+rnpKU3* z&PIgFCQ3v|1)W^#%%Fc@0*%!dH(m&B=AkV32lT~3XU)|_n=1;emo|xlK`l>-1J&u3 z2%%$aL@^{el6d8eT6wHndMd_}Y)GYO+fk5*h@*5BBmAC<^-`$#&KYHqcDi-6ruvi% zOuFt2l}VJn<&?JDjUi2V8&S1+icya5r20n z=xt+(fjr>DQ3v_xr1@xO;Ij*4tcbx#YQ=&OrvlpJu(0RNI&i1gPt^XV3F-b&LVjrqzjN(Y4OUwb4=>#(GNSQu5SF(?pc}}fMF5$U zREzd~(yE$T1iTi^Q`Q#pF$P~dIsRGB((|TZCO=$UxObJDhn)W~tM9VjQho0TuQ&_4 zwNQcMOp^>$cctctRI_{K9?{RJ$~{z&zpQePQcQ#I<&D7xHv3XJ38RqdC8+dpbek*& zFMSz3ostYzgMjn$ym zFp`c32@vNkk8nY8Da8n!Hliii6sabQCL7lzpzgyr#H2v$ISD5+b|p0JCJ zhKO(WYRN1WouC4EHMkAl=3zc;H%x*g8HkMRMW+!D|EW+v9n;Ha!Y{jbCmRdBA>kN% z*bsd;ajYnJhpG7=l#YV%GHP6_CzWSo|j*c7Y9khd>%DE(+q%yGDOMLQ1LrSUvK6{)kR3MnA; z1)2zMZXI>KM~^AU{$z)s|0*TS*uLvDse0q>;F~hTc~aQ%C$3ITXS`(&$Ur(z^e6h! zISW!j+kce!5X4o>8MPmAAG-3R*Rp`u_*f0S2+e02`ZlD92YDC5gRrQDwye?QZ7)c5 zc~CjZ4QxXXQn^5{#0df?W`Dn;;BjG!{~Qi%^wcgUOA3$uKAo@QbuKJx$3nq4ijp?z z_%_UX>VEo5Loe}{&EO}GJTS`PKea;rdl`-Jj9*pUeq6Oby*Eb{wN);9mk7Pd?ad!!wD7|7}@1P@aLx1;!x7X+z1>vGevDbH$XWy?3tLU?KN=V%=31P$K`7X6_4 zfQ3Nmwd_UnY$LT^0{I*FQ9%zLEDB=&KQop;ajfSwd|UY+*mnNItS*xM z;VOHJWtnc;Z)gf4vKL=EmKr9fP|lBH*;IT3PP)i&6{iV^v|Qq5ytjv<0(g84?0>J= zKO<&;!n}|5K`#3FlZ8IdVsYsAgBa;hmiR3HbzX(2j_fX<)JLPP`-S-dnco9IKR6AX za3@H5Rf{<(Lw&1^hgb3hD2ApkcJtscRi1mP(i~z5gSbEEPZ_qfKTb%(xEvpQPbprS zWu(}jTX+yq_9q!`CR_D=H{yc}PvEl*{G3*g@kY;A>E8NlTs>xcdWsjzcL!XNu|Q>h za(q-WQfy!u7i9jYPFcM)KYA0270yMfYkY-#srb0D2Kl+ZxiE5X^jcM3eJ>+D83*I? z%L^l0qUSIfcrN`675$V!KdfIFJ{b+o$yiC}3r*)ORMpK^)uD>po?2BLb^~vF@~4zR zRb9YWaF5bc@?WB-%lg(`&U(P5uYQVy;}Z0hoT#ror%qW3ef?APrS!Dr&*@2K1k`$W zl+Wm0bl~J3;=rH4werxW?uYM%qqf7oi&RAOvswL3V)ZxGEaFc0Nz~zD=m@nTs{%Eu zl#2c2<-f2Q;RBicNK!r^gnhVgHiCjWxAQJ|Pb@yOr-YK=;eeNJ8%TVfiScgPC__Y9 zzxY5Lo?Wje;tdhJ#x<&*0p+xZ4D)?qX*_?l%~oq~jQDgU!iPJE0|<+u}c!4DA=kkjz>@0X$UAt$<3@ zeb8Gz8aUF99}ZL}L_-M13r2!Mq$3kmudKW(1=X*VPv0P}&B;f|aoL+Q8_jo8qBJGZ zR#3=8H0Jo4RP?HW9yS$P{t-X;YEc-X_Q)}ReNaj{Ue;@*4}X=rIQa zSfizLpywIrpQYA;7pEi*K(pC@IyIh)S}Epob2JOS1QvXXg&bwbI{~K`#9j1kb#F$~oX516fjR3HZOG&*lkIhM-S&hFa@0B~BPyp9dufQ#7|N zeS-a;?;!i#6#M_%^1kv1vAr(uSuTG6Y)@3KDf!v)mP z_i19__fa^C*;~6dL-nlI1<`uO9w3gevj~P)3@?>Awo*18k>U*puV)7dPA)|TVd3Ow z*-`V&W$;0o3v$1Q;vx4J$QhRtDqMz*5q4|eU##kf(-Z0kRT9-!KsFqZThDpy%c%k0 zTzgHhiUO*>SkHYExw_{hejN@{2wlocl@Oy6gqZY<2=PE2k!`XG;}@d8JLgk>&-p}u zYJM7G%+UHXW(l6DBhC^&0 zk#vk*mpuh?fG{y*q&wHgfu(c3m$z|aHXP7mu96jdM;z3G+(jx&8MQC4wNE?RCtJ6+ z<0#Sz2SW)Od}2w=jt(Uq@5Dc%DQrzit)ZSLIL~6=S8k_$-#tL=`yv<}7e;pi!5qS{ z?@u+Sp+=O|WcZf_UDgk`QfC34)2gQw&|U*FhweN!G8ncN9ZLTADJgF4pzI4%cXAy8 z$mUs>@Sa!^;BxFcpM43oQ#PV}7H4PskEOwotsJgLmSV&`){;|qwV*04z;~f5@Cx0V zzMzvW!)Z9oRGHNS^Mx&w5!v;KFT{^> z`sRL!U%+Np{>(OuFEjwpl|QrN6-Yy-jAhcS`RK}DR1*jJQ5yZO+<>9pHd0iD74_0( zM63GlII&os zmh(lFCxA*h03;iq)|hxmDX%?@G;@TxMkVqh#aFV#~hJsl;xTu@{F=Pb3{L*jPC7d=bDRtX^|CM?!@uY zJuR}WPTH{-g0aML2AAVlv#TYjf(!;YZUH#8 z$Z=47z6Ba~b2fAvIFsWUU+e>V>U^ya!&3is*7YBneNqRah&7ox_$~tADt}W>@|N5S z?NA-=QCxm=6&6%tfr*r(1n*k;v^Arei(7o5O?V3*DK#SaptCRd90{$%=bL?1>>c1k zs)4Csn%<`BIVj`GSt)ET=1TJ@e*ADC^K!-y$Kwecv?`j1qb`>AMy_DT#lK=F-uYfm z?>al(*I1$7qEOzkiF|uH2l<{uxvt(b@T9B~^K;Fl_ ze3Q~1{%G@KCHfd%*3fU9aT0uPk^z$aq*mXuv^RQ7RPoE;t1}4d4o;1g;;d&gXV4M< zd)%P^y|JJ2zwi>7kWsrlIT$L1A1x$S@`Yg0nl;n@#^V9#8dmOAp=3E;Rqj<5en#%a z5ks9}BT|vNO;KU2w<;G1l?G!lYPJOcs%0|0lTJ!&Kk!aRh83=joqG}hZ0fhTsPo$# zHV3=qo;9BT7Oi)<;&8-jue53qcDB#d6`bR<@%5D!GYgcgt@B+B@`G#2XqQMif4Qi4 z#o^7tt+xc%7S1l}Exv;llPka6)6zHx>lNusc%C>0)yY&EO~vN~MMxbt4f#L`EHUWQ zNU&o%stjl%*ShO%TMIM#Rvi9o#gJ1gZ0fI{2kHltA3J5`=co@l#pgGY#5i%D4t`Ld zMh45=mLwI((ESa7ur8P(^J8{%)X__t)OTplllOs|LAOgSf;}3akHL!z?gM@T;Njml z(!W*wnNcW5Kqdj7teXo&qqyU}y| z?QxBs?m&}9Pva4szt9c7iSa<+0$&6-B8nuNd-qWhb1!3o(6#vKa!<$iRbdQ-A<}8k zY`gfEmd2YwUwkb!o<9A}{6B3^9fGrmPzZCx+n`w7OTX&MTUy0f#v_{Y_u5xEXa$la z?L^O|$_hEGw1&PEZ^o>p}_?%e>Jw*r74 z2!`FnfBzAp|K5@${ww_{s2hyY4z2o8=-9|gH>>gn&a@@=r?8|1vT?_FKl6fAc8yTi z9pgU=q}uHh-Fb}e69vlAA39ulg@2sl-;Wtq+sCD(RVWv#?8 zEsBe?7MPgQ-&w87yM)C4k-#$~C52|bO#G^vLZT8Q`9;&=`zn%$Dv;q5$;KWd5}2Ty zT<1xX3k}9yj|NU=b1@6z(pAdEZD8AeH`^VPw_)D#s25ec?!#ES&TiB-zTT=4wm6~r zHJf6Hd!VOD&b2b!;#>7MihEqjn$lShG0eJgCXGFBZwB>ZS)-3_W+TxHp`@QWMFns^ zTIU}k5fu|nQH~qdv~l75bD>wH={0s$dZj<7!H3LXRyX(&o*KUCOn3P@mQrYSPKwBT z<_2z%k@(|>m1Obz--N{lW+=M??@42B?`Gx6>T}*qI`)8Obk@W3XW{r-D19hoDF$>B zOowXu()|?Tk>7SsLL05v7ru{!mnf*Q^(DnXW3(Aca+v_c)Pq^br5B##6`@jN6W$pS zB#l9_X|cYZu!EVFC4;vRVbH$w6@N$|ECsUeOcgfSO%7e=5rr~%(OsnjihrmE-NlFT zqx7}B3vXAHQHt+&J%+X0cwT;hBwpeqeurmtk@I+{z~^YX7@L-N6p(+9{i&rEcS*Y* zL&+;x4zZJr?|j7@NU9mpb@_n;cdJdR>R(8N(0StG5Pa34=naG4W0CICPY|po11<-$ zS)VqF7PEcfzaev^vVwO4^=Ei%PV$JFl;%+T8GlQ3C0!;ue|kvf~w0 z8ml7sffPr^B+&7!eKa zD=p6hlkj>BrZ;?{*N{CEf7P9R#F8XORhjlo#! z7eHr{f&4B$LhgscwThFOFgvOX=dIUb-67(@#8}4#NIVszkZ@@zj^LdY3Q~Mkd$~#x zBRd$utr`lafexg2MfKUqlG{Dv*Eok=0u4oyH7CP`7dpRn_U8;tzN&5z71;^aMZJZb z7!~_`v?H`(R_fLo8GzVX5ZgxY(<;;DRDdhf_dipa%Ap%N)2+aQ41X}w&;7`h8!U)& zI?dzoc?X`58fPBz`5aKFUOn(`osW=gIC^0*jB=YDi@!A=GQoeM7b3yx69+hyfG6Mw z@0t0dahbzOCG!>hSH3SwIuV(pwQ@E%cEy)r*0!4%>{FUmeH0GXCV!(#s5eFKJmKKu zEE({Cy*-=t%7?h|hsTA)8@q)B=SvDXJu zlX6D`rUT~kd=+?WaTnjq4gR9(=kdP#Era<{DfY|ElA*z^_}k zKg$)%S26xQEgwM9YGg;o14A1F>!_ABWc-&ldu(7Dz2JdQa``?+dYE54SH4 ze*Rl<&jD)aj<33@uA+HuDZY_#o_Q|j@i7>}cz%(G6EZEpLuaPcSN#+2jBS0J8oP@g znK+jt z=wy}vJn#WoVlOskdD?=OPh=?-Eb+(`ZiQkoF-P#L*P-X|NI9|Nj(1mk;I@P6ql@@} zP44wydy>Bk-|%CwrQ_5a&0ANDdJW|y{ot0*G3yikCxJ@5;rX1~0+YoJbWk{|GxgmQAcV!Wc@eb>+~c!u%T~LGzV58&GX}E+K!*7y7#VA zG_kw1#kHPo&Q!*ihjvMD;QBbOdrAXE>R)PlU2Zv4B$yPY|v0$P^I&HS;@4`tWB8k7dep zrI7~pQFWieV@XVp@5Q?WhTI^!atFZPArySGk3)!h!s82Zu>%U;D3-{daZfd6;6Enr zY^nzo81UU{I`+TBEzZ<#0qMq6H3eiJU`w37Y&|Cu*fx;_py@)i{8m|wpvMQh$)s1? zkfCqm=-K*Dq<1&yk$}_}tBA+V0^#{~9aY_iAn+_WWUh4?aA6y+fE8}A|4Tj=}G z8c$&UN;llTxx=k@7J!i2itFuHi@5yG zvDAls>+I!K`ux9yXMF!}vc$jd?Do}K)ytp-vdAr4_OwLztL)Cc>UpX4c`T2mLZMty z*a45l_xb$)Fgu1<2rb~Qx$kENYOfS8jAo(QA;~u;V6Ya+bD4!Cr!)BpB!`2ex~bNk zSt5PQBmRxS0KnF0SeDRR2slpdc+mQm@qt&ar%3O93y~hl=3JQ>OhbK2KM!TU zkLTmo;wRYL(KqWH4`_#ie$>3ln_IS$K3+l2MUWFuao)jv_!jxFP=Mid>+rQHpoF^E z7kZ!r5SK~IRd)D}%tBLjiHP{^w1d>H-+wYq#Ex<=g|ULK8@~W$@4d`-naJglQvx_V zVajI_A%Q2gJp=K0ne(T91d=!cMQ%92Q9hDLVGzfI2(!*A9<&@ooRxO z-|VRZ^NLO)O^$AH3;bZQ@32kEzOR!M_~GQj1LI{>EywsE%6*H{-U(%Y0ti$|X;3k5 zEAlZYthY$Z2Z$-+ZFmt5YSXncS>zuynS5o+GVlGl#lX>U2=w<$`%*sQH3-TI-kgm9 zbu4sk4iXlVs1igoz|Nfl0Hs5GE5ncBkMA1O+Zg_m{R7&AKieYc`n+|$={xn&pIP<1 z=^qTX<9t9gDCQmYAYpt}>tF|z${h7&d+#i0U9H^kSb@KH;K6vgf!mCqPylm4EbV^2 z*8>i8d!%`|W=1=&RX?7RiQW3#jq*7N??f+o2p;CGO3$dj)`5;o*P-QjrjB_=rBVUy z#j_?+cDIj%$&_IT!;@RYnt1iu8CXp}D77y)-`&v=1+*LG+!Cl=7E<1V|$SF8;rIHIR133dP=0l-w zTCSo5xg;i~$IDghlB=`Gm2S(m6D>ovZe}9{)8!1RVBn$&UgE!w9~=`o?eCJFc9bG1 zt++`V))i~4?tp{S&Ifs2Pspj$wv&6Ow#I=ArCM7MxPUj>!Bd74Jn=DQxRb6#EFL5t z2G(Lp(n=I|ivtj=4 zW&w3v16+yN{Abws>8_t!Y~`wu6kJSOry31WKPZ{!W}_)x^-mI&nk(819?HxYlY)+N zHn;46*-`G}E5OXXDE|b0^ml-t1u#|fn1Yi^s8@N1r08f6fRb>M7Yd0q;39+Isfu}P zffGHIVQE2T_Z1XDa%h4l8reDvSs@tF!)jq&uJXu%!E^218_xsRUgS}O`}P)j_(GLv zdiq}Wbe-+-MFY5Ri$@j{t1yvI^0}Zky+~Rb6mSj>QM=nvkD`E} zSc>WVeygcx7ZF@4^WRtjNEt=5;;qY|%|%UO4sVEgZ!@qWLMko7SxX4;Z*ANw2(S-V z+S5p3U()Xx8fK z3@F%oy{l?Ai9hm<^}3v`?Xl8D;c7pw;N!$K9>J{)rbRJhU%KC@rH1)`E_K8kTCXKPzlzO0Xz-oQw-J_zmfKS z8*fx0v{d4UZj!&t#FklJxi5_dQ7G9oLyBj z$NI-PSJFKTKa~<7{bLLzXYF272`89Q|;8AK^=WMcD<;4OAv`L;~d6khOb*LtZ zC-J>?l9bIaHCLglA(K6y!uO^5@_x1EG&Cad{aJkPt2zVe7~#BM;sWr}P7%CYwFDu) zC%yav1%EuA?QsyKOMBA#*A+C!^ZyoetTeF_3oSoReqxF><5200duaj&#ayaHW^!1egHJ@ftCBe% z>i-+uA#Tq_H%9t#*~QL2!V!QD&%YIg0=V9Vcp^#8oa)92YGpM}cFM)b2D=o)^B*C! zC!1!+TaPtn3aVc;JT&1N@c$7;t83U|0AFr2IHGxEdK9; zQTc!DY3l#1Gu8jca0aHYIu^_#j*A;Jn5*)H{H~JxDs_I=)w;e4bZ^YXIzXV-BHptG z^Jg}d4D|-KGmYQk<^R3N9~E^Mlb9t zYy}&VgC%9j#)#p-$^eggeNyCdiT@vqMpm2rhST8T;YlsVRE!D-ip{||($If8>IG(T zI$Wn^gYhONmNIA$Xj;7KMBIrKLlM8n!L&QvaYar`X?(XPJYR-gQed211NBm>uM4qT zM)Fe^xyGAj3RBl~?UJPY9yz3yAct`9N$m$$; zeU=*S9bXe(A@X)2-(WJQghV+bau{Aq`>`ZaN%tN$Qt|5PYQ zoCeO7qE5aE&!=gO6!3;6O}e^JnI$Ssk`OBJP$c=cAWDS2sI44_CJm;Ypq*(!`|!tnuTfVU55J0RDW6OkI@}? zdFrp9`a`^AqQv@0VWD~|RewYIXB&(KI0@=Ldo=BJ#fPG9u@^k`ATXAVqSxCjDZ_lJ zQBsCkxWk~GSb%+*_%b8D!&fg*fsY}s^`ws2l{s*}5{x$b_d_y57P?2_l2KaYG=MdC zMG8w~%r(kEQe0!)12feOEXp=zwk2cFx0>F;RYjfK%9k;m}jWHS%O6jz(|oU4(`Hb`@s5Q zHP@PG+Fv(5)n)1{38;=+(OA z$)P;+l>cM>%P2~dqNK4LX)?iCcs^F%@Y60H%Y*D9qCRkg+D4+bDEe;9t7(gZZ`fbx zz3{$ce~z$mT}n0`2me{YI+=Rw_JXWnW`qKwbKbxufBPc~TVHf8XzS-sk_$ z`=P({zO?=KNvoXpvG7~yaq1KGoSX2Rm+;&#;TZ?JX*DVQp$X5W&a?Gf1uBf#=rTudeEt*7-aoKIwXB|6AeOBbE&rWeS6;9a?V?)dG8MvDK9=0J>>*YM8 zgQjl1(9P)&v&0{^=-Sqaf=(bRHB zeS;*nbOk?X{aTMoo8szT$>*Cf*iL!@ffjj&H$IH2KSgV?T2mjKdT zeH;q`T&87~TbNbQE*}#WF*gy3&tpkwTwCi5&m_Lhsxt$U$nxR9kCvi2BI5wYv~pwc znBd^DJ>})R?vXfVvK-CZ(su{Rv)swmtH`3Eq_~;cT@MzcwU1$2EC93 zPnb_a{WlpK{N2zM?bx_KqCh9Ju)P18z)!dxZkE9Q{*LB(V~o-<_{AE*4#vRp{+rb2 z+y+QY@P(?u9a5zHNBQMgu@eL^f)p}Zh9or)N>^>Ie-}B?|A`>kIzFNO zb3V13@|I{9?H?&iXhG=y0orHNU}rl$z`i@0EOGJeaUt=>zk~$OD=cHF{SO9N+UguF zZ;_?fGJYJZP<$ay^0^KA*gQchaD7vmZUqB=2amH}#H;Xp?rV?{UgJX!G9L+!Iq(n;?n326uxHTL;=lt3 zE-?30*VN)G-eIKU`?b(M60ulh2eO3uQegy$yO+y0c&4&GgZt^tYLVL`G_C^`+Xa#Q z3g9(tg~0l!$Kbl~Eyk^Eh|3g&Yd=MY*8l-0()%eirBf8#i7`rXdnq(j8la2@qZ#3@ z>O&5$K|hS{`MXrP<_BqFekE}nZhAE(agAtfK`fxe;oyGY1#h54)kjLY68ISDks48d z2Lc?Wanw9Ucc9WtE4nj5*M+UyJJ3e1g%zb#KBjbzqie!G7#8YiVjo9|hub?!yk=3V zfg@*%(u|Tcvq(PMTa;mxWSB*nMoFewlx37;nMK(~Nw!&(Ym{J9NS;xWXBPD{O8S{a z`9?`T&N(wm3e2KHqomL*;)jRLqM=5~Q2Dr8UwlA72fto%!q~wtQAsZqOYq~@*5li^ z!>p@^vi!|lD}{&cX%5h(?FeEh0OH#RL{e{~+RTb`fNpyXK~_YB*5$mwVU|~N$Wl4% z2nRFk@ii-cF$&f+gKz@zF?G1nTPRM5eBt29lfLSE9ju200AUphw0|Qh zjMHfoRod%JLz2KvQ)y3$9u}RZ=kjK%)CH0{%1*siQhlKtsYU87!+tYQzbVI?D36Jd z_{I8c+7K$BW{oIdhpE={9gijNxrP3ok&a};HEr->A0}9<;BQ99TDSmKnPI*qSgzF8 z!win0#LI@`7eyh*II$6SxA@J2sydbI?`5ta5DXO_nQYAGy)_Rj`wh?Q3Oyp^NIc@H zW`2z?+Wq78XOr8{-xO{w_-7XF?ZK*B@t^N~XGIz{qJRYXy%;=FRWsrPuWLwBXMShI(NLs6h9%J;{k@ZxhzgHb23 zeq3Yy)`+{EI4TJT{9&&4pXFRppTc82JB~Lx$ywakF6-}v?XVqZr*|UqdZGY1VkJ3b zUS=9rB~ThPsF~M+F9`RUN+~?NL;M@(prq?fx!L+0ltvTn7&UVr+$QIB4sL1uSi1=r z;rX8WypzFu8`sDCkF@^=Q^Vz}V&%oem@#_;3!#Ew^M3w=gUweUJ|z|%*7ss@u6&}t z4DKR`eLWt0Da#{DB1LB94GSyeb`DE0YeOs&(kz%Z% z9~sS!3(a5|?hw`vHG@NO7hYC?UsXP%qY(|Xm@)n$pk%Iy!9vMWSear~eFp=uu#!Hd z;eI;>9S3)*4M(hq@Bl!&P)DaDW6GJ}|^*GZXvQ=+`UQGBzo0UdJMD<_qaNcq|9bIREbiC8A;o>WHRo&9*z+GM*>+Y9UXPX1 z$n*fGZmenxhSbdmRs9HTHygG@VEyk)>RP*oUaV4Iw|Y+OB$XLSnb}fopR^h-!2&sW zArm(pB8dyEx3T)vPOSVJ6Y>37NMSwlmD(9k=p3v|S1))tgs`%x zK$nt}4^nTqt5e=g=&#@0Bdh1J33Enh%GSxbAe_32q1a9SM3e@F5?1PGR;6)x zH@B139KnlT2zwLhyf~zac91SoNPh!T>-y7MNd0E5+_!!wf1jY=+a;lpF7`jr?=WDK z|10A7xAl7`<#2T(?>N<^-_da>wtf>)#wrw-e#gh*+4@byJ4Wyv{c?CMX3R?R1^Xu= z{d9`--&*Te+G~%WK?T3@swmjm|NH|f$L)Xq4jP^@9K(@SY_9o7TgNk{q?jr;0S$j0 zqg*%>x1->?oW~iCe=fQ!!#_6`4#huPlco4)!?_s$aB(97=gu{nWmQFu_1`#1gZigL zG5Ku$H&9NO{ttqDE_AF*kRl;xHp+NCNO^6ICL(V>85PtmbUiFPapB3_Gw^H+CgLpy zo-0#nKdPWYLTbJ~@p(kwx?$F-r&HhOFIP1L0tPljP0K*2$+BCgAAEd3QvWs1H#cJa zN`#xA3y9rKV`Eh3jHINd!cK*O{lSdA&eA$?tFCso!6M;ckzJLTUrM#(L#pNb+^Kd1 z=xiHklK}ZYrYlK}4d55PBBDPckc&!m5HC=v&r51LS|F@ltddNIcK1-(&nqF=klldW&LmbLysWNubYLPIv8ziPcL?{~e7_h7})FpfV;d4B~n z3E2Mz807Gx9?hSKgO~jHT%YLU$Zb%Q+EvdT1+c&*PAdF2m;%{JFmg5)#qk`ctZ-1& zg&s{~8o&SO2~Nb3FTT*@gzX53Jlc+Kq31E4Otm+X-KNM*ke7qSK5yNFjPb!qS5j0o z=9B$5c;$}_7M;R`^8^xB-SiQC(-%5}ybf+<-Q9RiP%sB%z$6Ke#$d0n>SC0887Ge} zLps-m=E4+eH=jrL;E@$;L7p&OkL~>cixdhKh=;Rjjby9j5pb=KsrC3mQGyH<6N-xt z;@8P!i`dPbu>C1s9e3}KB)*RH2la2!7%~Uav$G5ccIgA6j$8m_k*&#~OnwY}s^GyB zIwaNfZE{b>+>aBHVA7%X+BC+qwS!er#ae0JfoRTtvixE-wzYwmaZEb-KN#fcfxMM9 z)mogH6a$(5m-_eA^4}G77w2J|r2-^!)e@X*$Xsf+=*t7}3pZ)XceHXl_ z%BOpu;&V7A1mv=~C=Fvi98*!lE8+PQO2In^SXNM7vhD48KtouGC60fyd~QCK8SGdl z8Q}X`GTX*dDw7{Wm`O)ua5#vE=X-6!pLekdH+!(rMf&0jqf})iB~{ALRLS5rl>yHO zFXL$qzR-tIfVF2R3a+c&x8-Yc+#e1qW+g=Cqa{cEY{ zU;})(&@9P;4i1AD5?^5sMnZd3nU>*_+gmu!ohQvS*0*3d4czhbh+aT*V4GW#cdDh4&OJ-ar%?c$H79NuOjdk zEkoh|8%ltAPC%h4c05gW7ilRL7g-VAmDYfM`mw>H)>&ZjIO>6^x{LUCJkhT8{C7q3 zjmJoX17CCoX8d{|m>%bbx7lBo^7M}rsry@=)#ZutP<-inawctX$KMxLtr> z>;nPS`IM2q6@>hSG^feaAv#KOQkP8dkHzUhfDfX_V*z@Zj_mq1~Zsz$xI z9ZocBzYGZkcTqmWQVY*tCVNb9&rb>lRI&ghfjLT@(}{wn`y=qL<$2V`drylt-U0&s zDT~DLpUr&2nOsnRcrvicLgrsi} z2tYpzG(4OqgijY5DXLcg7`S-HZw%0d!IEC@XZ!C!#i-{^{=59Qdrn*aJIq>t0>%A& ziHM8(VVbTVHe$5~GD)Z(u>MitU(oPmlNN~KofgA`TAlcFrJ&uU&~!Y7WB+yWG-J3O zPi+bEerz3oVBe20i-P{oQzGzoYm3aKBc2|EBd}Us3@!OOzNT&2M|=$m)q51xzfQhb zd~GdX8Rqd}p}6{Dn6>9Piq~B+;)<`fRxW9B>-frj7w}ro@&x~!d}LexDf~%%RWnhEu z{+Rn8=Wh=dUqEk~KgfS9_0{mW9Urtz&WiUgar#pJl;-$T%zkPUU2FRd5&B~t`W4!K z7b@>=6@PjO{D~SqWGiF{n6=P*zqR~ZEWc&$HkvHg8q;~Z<9Y2fBqTR-XX_FLrGFXK|%ex#Xbze_Ny8H>-bUuVhSFqOe}tILM= z>{q5O8()8{KT_m>P~>luKV`o^%HONo-27qvo6w)B=)-cV*PQjaMD+Cvfb+Sj<)yj)*of>wl2Spe5;P2T0VY2)biKK7pp&7 z%U7dj_2c9lW}POCT&NgvwO?(m+^zgS&R?<}e?fWp`EW|oO%eDj>JNg3Nv|CRB9!NT$7_lxe;cxefJ>;GzefVAD?10%1*w^Z96A3*!>FsifR zK2=`Oj@0Gr1?8Qs;^U11KTpHQ%9oATD~2cWafrZ=Rq*cklMx>u?{(s1{#d)DkY-|h zJPqqf;^Jd8ivlF847OX_*0&cQ^WJJ*J|MrKH{2`ox5=N1kAIZEyD=je;}7G%LVv8H zkNBu%a^mAts+7d}dxqohvHC5eo%(HCZ;GGd&|jeKw-d`qz(*_ly(;hzbVB zFz;AjAI<1nUvH%z+2X@;g?gMN{kgIB=nd~#$qn_}JYmnqu&2mae{_SfA)J0;*i+MY z?JCm{TMtyC(OUVQ4$e=w&k`V7`EE)B) z7T{nstj zz`#mV5co3pZA=u%6SHevjP{@KQ>6I`2R&HdVY2~@NYIM}60<6RYXoZ@ZdCt$8|Db$ z{~F&EaIn@@QDUCWz>9J46a+AZuNWVMO4*hI&d4t>RdU9w?^Df^EFM@SDqD>az45lp zN#KphkAf&N?P3P0EGUlWDyWfIH9o5H4=-!Ryc!W!|4X>Q6VOg>%xE<*r4tmVTow^r zBf|>=z$T~f0$FE9~6?b3^TY=p7;(K^lR+dP6n;$e+=uH$5(x8(PBX;ESG{}M7t9_1v9{T2W-6n&$lS!EHpj~UzR`9u!*1$d1FDFrVoed9XF#erykPuLri zcMj9%6CUTAAJR&Hhgk9cK~l4TLVuJRM6E9ZWtknFm?T5*nc?(&qieW;lMh+O+9_vX zM^L8m0sJl-6EIngU4q{y2ft13zgsPRWytWoK3IzTmJU4bC-5J@WgFWt$(Lz%T+=Bj ze15Xbz-^A8Xa-9Sk)uNJcp_%$&1P`T>C1rEPi z*4LQBg3MiPc&n^LLkJ1tu4(?Jqw&$c4;bONF6fWR44uhiIKbDXmyTH>?F+ezf@eLF1j zNcNA2B{&$A$GzhK+bsN5wFJ`ef{Q!U%pl60fvMpg^%gxN&zgm$5E$6P3FZd?2CuAx zKm=PS0ihaORT}}=&lmcedXL%UTg zkh{bu-;6fFmxmSQf%|)LF znr&F;{HFc~(t9tsO~q4G*61WKgn^8g4Lwxj#XFz@XEA8ATFH{mRb7egXRdd$x|3j% zB8c@)Y(Zk$+NxQ_V#;l%3uztfvRH8x)Jb;1KK85QeN%NEZt>CJn*b7#2RtKrwMxzf zXha@V@>-SrRR<>Xfmc)YTlfW$`z4tVyqc;v;1|gwC7BPrnyTN&FOt(FnGd|0syE{o z$?H-`n-9F2sz1RmlJVhMB=dn+Q}tH-B6)x$^MO}W^_TcX@{b}8A9yuYTlhutGm^{) zUQN~8@r&f~lFSEQP1QT_i{##t%m-dg)j#4F$z&}e4=TA?CEqT|eBjko{VRTx10y1G z!z3D*pMTP416f)qVuKqe8BJxE1=$M#0#lx@E@N)&8PrMpK zvcKL%w-%|SJ6_=U#4B3D!ti1r-pA8@5h;W}Md10wE85Z?A4~C;@Erx7PrRc1NOqg_ zpT=9lZ|X=n`NS)FeS7dv;4R@F6L>!HiXPJ*{3Ccv_$dO#7g4Y@C5{22{sVry?&8iK7=}O#obb z^)=y8nq(VmA>csh6Y{AJlaTQ1$>xE=s7Sb=DZ@Gqz5}THAq7I2BL&`NTK{s8_8PPnj)HJgW^bx=2GOWo1o|Bqpu2#wO zAYeouRPtJtTq4PQ;MFwqE&PJW9tLlDP{|uq^0Si62VPAx-^VYY$4W9Ecs0%3j9(=8 zkYqmaYMS{8ev!N$f<)v&C2v*9GbEW0yqacyiC;jUD9L=_)il$>FOt6&Dfz&wY36qP zBKdAf<^!*$nLF@{WS$ifkq4Fhqe|u>Es>dg;MFv<8NYyLS1uwCD*0C?2d*_?&&W(Z z@Iw25My7oj^{pS0Q3zaablA$y7@msWg~Bh0b`1an6VIGkK_VzUwLqk`Ba%YW(bEy} z+D2Nbk%A5qQ+P!$g%h-mREyWl={yICDZHZGx7Rk(i+D|>gB>KM@QSW$m%XKUO{6cA zY?+wCD|&OgNKfN6k)Csqn8GXCw_T(s@R~?BI!H|675%DRl|O>lL>lBEF@@JY?6erK ziInCbF@;z3+;(%i7q5x*F+NA3jLQ^W(d2fK7U4CK9&?bG!Yld`Vzx>DYvo1@@R~^1 zJ4j676}_rmq#C>?Qh|fS6kgH4wTpBsUK6R4gTxeG(f1JY+h%VzUK45KURx1N;T5fF z7b%3-M7qyGVhXQle^xGW`vKN=V)d~#DAmVS>q)FW%YmU{G2_b`p;84@4@SQ)rIW5 zN4Kht5ru#*Fcz{|kGn!+VIl4Uy&|F6b)d)#HH>5ftT(Ns9h0}l0v3MswtMbqgcqG#aDGw zN4{CDUI1?`?vf*{M37!mEPvH9dBB9~Vh3?O#{OD$DfC9DNJ*(el!LbgvD87lLJ;2~ z0509>&>OEJB}17Qsg|7&ayQgLYz9*i>7x)vcS|BAX?%*5l*wPUtZidLb(w>Bn;^bV z09?A`5-CaNQ>0|L{8gs|T;1`E1*M!mg1A||0OBXOgK{ziu4I$~&u|b&If$=`H3-g2 zcYY$=X2%@I$X|7)gE+=P94?4k34lv?k0K>me2SEm%U^YtgIMk$HnLWg-V|YU2P#sM zEf^)^6k@i6IL<*-{WOaJxO5jQQj)``NXZ2GtLEs1x|`r29xOR-S1*9L19wnPuE3Q{ zRN%P|;zS2=DefWyP8i)yi#49?dJ@}<~OZc?{&nI5d!`g#?8gB`|NZ|RzD_V={ zvrT@Uz+1vk5O_ZEik{yd{3Ccv_5HQJZfTCBk2xR-yjswLI1mnl_x|M&c3!k)QJNh$tuPF=@1fW)eG5vl!{ON2kz z=UFI!6-jnUtSH1CgL!yh%W_oxNxt*f8gp4Z`@a`>4ExTW%6@nP& z$8t=JsG|3nW!^y%xQCZt-$E)5-Zt-`FoeK8Mq=40Vkt83s1R&lsEJQQvkTa!{OaLDJ@gYsc}4&ai%*0x$JnZs2~h1*z_Y>Eutk;n2dzx@)fUW5XD=? zGgbhCS5<)*#Cx51N-V*SgrqSfcpC&yt1r+qB6{Q-9PKlK29o(U^3xx5UF|86j%}%O zP>)DnL~DFa#*>?)#{#(q1F{9`i`OE1lac2Cl5#7*Ko!(Y`p zBu69#Pf6jcS|XizBQ6*jT*!Oh`EN&N(aO9cvuIoJ*wX(!L)wag$H)(?Wq;XS_@jS* zsN0Ks=%0JS1vSjS#E|mha1jJiyo&Ll7|?mQm2vcVyq~nfpJ(F>-*)@BhFS26o(XQo*KoYN_7|FC!&KcLxC;v@ zVUBchC=9|0e_fUg$g)*ILKfx!<=RXFra&7f+<9 zssN{qvm=PtPMp11%FVvwXa=xjaWt9?1ZV%Kihs=#|NM6R!wPCw{F6y3SN!WYyQw4N zUv(Y0L;U0S)x-T*;3Nf!dUyUl`k~?L?E?2stiUn;$-$Ja`C68@59)vGUH@%n@;1i5 zZQq4Fqa1)CmcJZ<@zK-`YJiw<1kOhVj z3XPto3>4tL*ytGxpYHNX`^Ak6%=>oV<#l;$`>UD|qY11HFSPO7DX*+daBe5q)Ae0X zvZq2{^l=cEc*giTs)^>FG+D>j{#fAoC*rHLgZ{GkD)v^3BWLKH=_Q?P-yWM(zn-zt!W9#_-EEfm1(~e%^*uTB@ z?j&Hx;&fvb<00dE>vneu^J%9(P<}><+GzJ4NexLs)9bfX{NE|@|5`i#tJ9_I_V4e- z|Gs}^{AVyt?4SLy_`mJ1iT~)5N$f|L%!&KE+l>2wE0r#sgn34i#}!;D>IZzY8sFeZ zH5b;Yw4r~vp12w-koFZvxa`LjM_A9q)f30q`0d1z&4Q10kVAF{#1Q(4Bh81t4|oH|3~fhFJPztReeIgL45+h zaq1HBn^tuR;PS<9q;qIkb)RsZb# zQscMdH=ioMneOzv!7$Dl?4kVztg6`u`I-m&=XU&Y*HiSH*6}CuEgk67t8{%;`oX@} z4=k#dwg0KocCg1b+E`1l6bHPaVYAs;OYlx?EkQaCErTKQj1)vzXGOsANCn1Y#u>Hn z%B02z`2AyHu1GN_`@w?EE&lGD0*)=={|Q;a^{|Ar^?J?dc1oA52yAa-HKf%^7{!2C z7jv1c&u^0T`D#I#QdexX=rQ+#^JRIMR0)?P1>FTsb#ME!y0-c^!+MyDxsCDc+Rsyx@Lesb zR-``J-AIXjDo3pUlw}pD$T-#!jkw2_+Ba2cZ}NjeM|D10sidt8S(`RE?x+iq=O09qXW0075a;iQf%hdVwb^fwU{r%F`Fk%_^G9Fj*7eE zkRKq_Dgd3si=WBI)|_z^>x)lB%_p={^Kr~BQe6kKpp&E&4mCULSiBRFj<1i3KA8{O z0MxxmB=#}TCoDpajmxnAXB(CM(0DPgg=1Z^wd7fZnut=X98=N5`9}gjS;0430~DXV z6`%d3@cX+3Q)~Ej2=8bq2bj;`1LEo`v2RZyae^Z8rPcf~Mdi0jHbEfs2^r=T@9O`7 zFT{SC>8W`FJw^7P)NoqkFx^h8+89o~Gg4WHH@w0{Ej*_@Dd|;?-9`o$^4@p;hDfC| za8~IIoNY7itN^h8O4D;E&V?@yd+yXj#{MU$vsu&`x*ooFJLck;_O(VlXp_ zPDW_L`G{Nh8lF2LZKe`kh6PZLn4;SyN|CPh?@=1yu)m7|ezmsADJ}k^ltRs=%%|}n zGqt9vJ~@yDd55%!aK7{3>%TMb4G4Qk*dAZ{Y_E|@ZF_Y73Fk+mJl|z8zvsuP{19l< ztSKtb3_V0PqGk7{!*Aibn@bi?;>9d8NoHqsg3;JY*-fXS-7mXM2Nig*~pI5Ms z*vQXv_$_PO^Bq}sK2>5{=5+ab@&;>i6~B$)k66)8O@w@1+5^^2U&?Z+rPjQ09=?Cv zy0}3w?pN=x`A|NcR%0~`{DEk*th2A(jT`leiyG^k8uc`hHN})9>yW|fd5nH;ocW7D zvvtDv0|xAp=K}rw@k9F|TVE(wKi^Y%fIMgF=U=epi0@PNvzboue4$@iP(bgd?mr8? z?fUuHI#vl7Sl7>u71Wn6^p<|UCW&JDLMv@}d{33nPwVGj@a+UX->aYhb(fOoRvZ4= zo$`LVejYuKp$Z?Q*Utl{N&a`#`ChJzUd+T7`_Nyt|DpVUE#-f#D*uQV**d0W={S(X zI1oB(mmLS<@KyU?NL)@5k7U1y^8>6q?!;C$Z0D6+#C&h_UE_c{2-3UhyhT8EDHIy+mi&8JJS!4s}**}He|?)MH` zdt?PJ|27cfCdRZU84!HM_2D5YzT)?i>aYNQTsNFFwxt7zd5_-4WgRUGvdfVMQ{0wC zS9v6RC?3@?x#~da{rp|NqW%xR!qLCzJscc$pW1GCH*Gdf_PHXCp!|OHB@uoo7liE) zAxi{R3bOXEr$6)f9q@t{hD~M|$QaleaL#FBNP8O)>@VaVQskt4V!+;>3-FbkhQ4)Z zXi{4_hAehtRY&*0_eRfc+aEYSlrI#^6vZ6~Fj;7lj%VgwrLf^^1*33g6SMj4LVP!Z zp9iRd{vn2Z4Nfw6cnj)v`M|0NlHvO@|BtyZkB_Rz+U_I`G!VE!qeLeTQCm$U3Q<%d zK?5cMH9%CBsGz8b=%6BY6qPM>8v1&@0Y{?D;ycc`4C?EOf*VSJ(726=8>8a5d)tVj zjuID=?|Dwu?Y`->`}@b2pVGIsQ>V^3b!t0x3V3_NFR6AUpSIU(753KN`Mb#HKi?z8 zo;q77)?oc_kY}ZQ0u07BJ}_^Yrro8i1N8JneLqg3@W7VQ@B(wgsVAr08V6(QrZ$58DNO{w@;L3SPHCO*g0%GG8+}l_LqKc zTz6Std_EE6A#l;>rPs-aG4=&qbr@p%`wriZS(~x67@5M~_|478$tKyMBMOZ08ND&x zd3t3gZ0GUCaq|%Tf^$PM8YEj$gMiDzdsHL+!!q$$2h$&tNL)^6^x=Y_brPb`?DA@B$^n6GFH5(0L^UhTk)3`Bj!Y~de35z3>{xDYcT zcoVg=yIYmH<`{TFH6pvwP3ynuz(BiTFRLyu^7VpyJL@OAvcO)eVY+-F!O^8UK#U-( zm{BTMKZ0Lxgj?cafQY&a%x8Gi7=HJAbjAR3Av2%13F19k_3{mFC?P8RZRY&G3!m6) zH_#rAmmGWIp!bxWZ#K7L)&zVovoHND6ok9Sh4VXl)$O!K zWE0pFNGK=$U&KbBM?gkCt9ujDgqubfu!3gXY{ACI%n0n`{tDRm9$Jbq&S-cWjv5a3x+8L(ax;!SrxPuCe$(EQ0kf6vt4z3Rm3iNMH07N8 zzeF{ts2<_AK-BIgQ5UGFK)9`E)b1`(C#k5O;WnV!L!u5-QN6-#y`y$OqH4K6+=ltJ3G^E=tlCDZ2i)>Gy~@dcuXqXoHN~6P`+~* z%FO22SeUV?R9HD&6W&4jJzm(PWw5xha6qz%BGNXFgRlOyO%$a{8qk7v_ z*%C$O%s-k@*>+VQi6V36AIPXac2!@AB6H^RVTdwg_4p(DMwbhj&3S?N@!z3~K6Ehf z;oZV)b0_&BBMEIS28({@s4}8}Y6$-qSR+IgZ5jt14lNv62e5?;E<)~^ScIHwjX>AO zy;|hb4%X+YoValv-~W5`K8#Ax1%611&xD>i>`0mYNA?Ad7@MHg(4VO?8}5bGQpwlx zu`ou`Iwl?fy1ewiqNEv4TY4d+2o6t!hEbMWM~xbQdV;5R}!*`spI z_R{s{YsL)_BTxd9W9jCqkFPfxW+4}FD-?3H?b;T8+knUTs%E#J8>{z5H;*={K0cP+ zdi6x<<4vlMAFiULk2k44-d9CQA8%59{8Lneg3`yER3HDBijqFwr26>1DoXlzlj`G* zDoXlzlj`G_s3_^P@Hr{o1~x9X$ZE{!yo6skqFNK@eB#NIDTsEQ#y*)hrjK6#Y~DI zxIZ1 zm*q+DGvU7=0TcY5glh@R3>y0dO){C(&hRP1?la9n$Q zlVG;DeMLsJzg@%Y;WFJ{kP*KHDVACuQ045$;7Cph8~4B`ddUzHB|el`Rq~T6rkua= z=RgzEm1<17L^V7@w`IHlK_R>K{u?d; zj0oSKj;SXIH0k4KF$$%yPVvPjLH{y9_apI>bbzy|_;4M-GQ<}jtOLCmI8X;LCGf@f z)&VN-cuyU`#K;%_9-5h;p~Zdi&vXEs^~K-S0buBhzoG-sA-?!#9RTlq@yB%lO!dX@ zRe^GR`{H+iavT%lH{*k^M1luBFl!YC%;BQ}L*R@k{yAownr%*|eMRPU6Kr!3`J}Y{ zayXTKQW}0CzXY4J`6Z}K;FsWWGQR|g5&RPB9K$am&0+jfbm5l}WgmVCMGSrkIlA#n zXz?9{;7K9G=Smy`HX5at+Z6mZJdV12!Tu)zG zBkSpnAVCc~V#z=(l{dMe4dt@#!=~=P0ger|LIG7Ds@T5#T zbQ2p#$hxWk%O>UgXqjw#>Tg-kz@xj1Iyrz1pwJr_CTdZ|OB7MY*;Uj*!FqV6XV;Mh zG=~#Xh6`I`Y_qr4=%HVB$lCTkl(jAiVCSOoe?Y15?kr>JTWG)|l%gVM7#+)VpQ~Vg zAAl+#G5NX=%!2KP!#MsI1J-|8`2TE_}twWr59 z-FN`un;Ag?Rwa|Uo+G&ttln3*4zJ&>7_^)KF9E>$_&^;69Ah#XIi(0bq5LA_4P&1bD+UKzD#!}wCK#37{MfU=CSqnxx_rPlenB0lncOEZH#v=sg zdZLfL!z8~M(MdpyKy*abq6JF_a(xH-Nyo>#0|lU=9BH7?V-qJ#n6T?(mWR1G%*6et zf(DcW5}$NQ5O-xog1F!>_$P$j3r!#$%ob82{yFLblLNdadzOZr2m;4 zo#?Hn>GVIOq(7wf!I3)sA*8qR`DyX**1DWuYZ&(ok+B;o8Q3J;yM$A52v%-pG&ci7 z286L-w(L&gx$`U%nIS-2;y`V^mY2si_ea%+933}0=nqtw0z z;Ae(TWHr5vhJT?>eqz5Yj8DQ#frF?D%B1tgkS{x0vy`6m*i~BNWPfmnE=_FEPrG1q zGfTH%+^~9B1UI2GSL2RP%^CD15cU#Pm9>t169gk>N6$b&?whK{rNo|w^aBrqTW z?Ij*vC;Dlh5$KLRN}i6566mo}Qdw(6=xUA1VQDVotx=NwTj&}_y~`+`zN%uFRjJK1 zm1`OfCCuso!XQzQM&B zK=!S*V;W;jpk!)S5*0bjB$iVp~nLs$p`By`^Z_-tg! zISEy<*(21ie-nTGK~4#r(HjKqPIhX{dnyu%9-Dhxb0%z=TkmkT!x=_>a~9iDzpbUC zBjr37@1HzFa=lw6jpZIy0ZCJV4b&eyzo`K8fi=B)K6EhZ_386Kp5M$7h|3g2_x$D( zVl{SuHK_|twaRl@&GQ_pcz&}%o!?}i2T&wYIS#u-AN>U$b2LKO`C+%DzT?pk zM-)6*2t0zsE3$6>sn!@iJv;+qF|BB`9qLnnt-cw?Sk9<|*d#T=hhUynvXv(*@Q)%V zE3m0%ok7f+rWGM~R;Ayp^bg~<{k6!#gAQPGB?f71-Iy_2r1*@=7$6p+*bE@lNI(A8 zya0EEWqvmyPcKoGeyPhZebs1K0c>0MOz|zrV9~2QhTuC#m`%>`A)B#uGybh_=l3K0 z2dYxG@{MsjQ71c34(i9QzTkEZPT)wFyV;Tnc_c|?0Hu5xUziiPkc`|$1QoJNFNU(} zw0=dxRM0Rnp?_|G3{S#@sUSPju}fFC2M>Ox1*_HhC-jZXn^jP?Gi76LIpDDJIf}pq zcyG>~w`s&5oCMLU%!#R;f8Y%{n1NZx3}YO(%o_Q+wVbz*pH>L-xUhkC{rI^H_!uM~ z!9=o@;(+0)ac{t~>g2?yH$Ooq;Y)-*E$j$%IZ(+nu_-~qs-^_w=o#FPuS zMrD42S&clGZQUmgXH^uCpFsu=#G)KK|82(DO{gQs#(n~RIdz;Sbt-1wTcemsPg6)L zD{5zhT;Ys-J%4c4ygU>CeH(v+$0Ju@3xm8iBAjig?Tosa?itOCK#dzMm3it8u#6L{ z{d-6K{o_4Yoa4rty}3uy|1t0hLcbI9xz;y4aH%WZZIbtp#oZ>MI}24lWvgQWXoT|E z?8Hi&tW!H4_^`3v!OJQlFKBcDTG&bUYW5R(D~MIf$k|EWVwI>Is!5*{ormhvf#{<_ z#Lq(eP!!n5u)EVqFPyBzxX>;5pzT5m53_d6uKC8!WS|&=IMr&L~Wek z8dUUrWCtE!t3{xw1>4d)%yIttC$THp6-EIRGo{D5L-hKB*AbvzlIs3}(Hq}|Afsn} z+hx6rWozW=`3@)lSO&ZuQ?ng=6jwIIC||2#7Os{4fLYLRei&mpRE-BBR7RZP6yw)# zjS{8wA(nDfN>n{XcvUWACbnek^g3Hx)C>jB#appa*_>#mo=+iP)1yEQ4s*QgF z7V0*3V!`@-RZX!`B8~Bl$fwr}{Wp-mgO1ny#d~@jTtD9j`~^c=oF#*RIL4^E(0MRT zAD?YBa5-$orZ1a+79-9#8s0z}`$^*;b*9UV2A(TJvy89DuMy!j0q9D!bh4R2;Xp>2 z8?Qh`YT5!fDlT{RG=R`y5zvCXM&k=8zzD1u^lD^$Z#6g-8xc+o2x-O2n`+!2b6wTdsifC>s>3O86fC#Mxie0AhJJ3(@n)09G*Di) z8!UqWP1uHCNlQge4?@FF6G4q|>w%=yXX&s5L_K|s2-kZUnl!3QsZcelvdT$8_0mIt z>O~?aYz@yhC>V3{M3SV1vgAuCHWbB_;Czbh4AY4p0uY*?w9jA@If~_Ys;9a(Q{e2x z(lXu(4F7mh*Rc>39OWGsZ8!bL$x(>?Rl# zVJDFON?ke-IplG&2w-P?Cc%==noN?Mg6C+~e?qc;(n{7JDftSR?{^xY_rA(aPqF{q zH%$89%l6%R@*1chE^2+i`788)xpU1UdVMg#xuq0MsFKFXQ}b0aPqG)w@L!b|Q`?tV zGq~#oWAD!Eg#ifvz0K`t|dq*Ih5RGtabOV!z_Dy<|keF2&xUI)M%XzE~S!4|gr90!ygiJOsD`RG@)KM`u4nxLO0@{sjku3jDgW)9pCE z1*nDwT|eLx1%a5XT2M)#AoY`8YO?u|EN{GctjPVvcuWvH>iT)upoeYLBP^B5ro-O< z*tI0?sii_(4sr!1#QUKli1&}!(>;Xk2mtT09-COQ?lkA4CkV1*sDPwLaT?SeMGmdq z6JPsN*Ulnej z!||+P4}|O6dAt(3DBM0vogaXV)l#pRA-XFlQR}lz-p84x3k_nsn=-ugBsT`U{{+NQfZu~ zqwe~s+AKtFSCE~p{S>UE^l80WO@X)#sraQfb7mBCeQPvu>Eafb_9Bm}hIfY(^B(T! zsQxKii+-o@5Gmhy19ExF3sI{91MSau_l?}L81%Ru1gfw%J0GAEQYF-=At*sE-H{bT zHMuUtv`r0R;3vd0{wSqC<7kooH&NMOHgH1@Dh^G8d2#zdm38J}h!ufu z)A~>F(tBYdk31~~IbcQ!%2WtRhGHB5Fp%W;00WZT4wC#Gs8x7LvRuHgF)c%BlQz`gl^w zI*8;%fq997>F$tC28K>?U%-u7<#}kdbKilYm9uXHJMHjCYKzPdKazUt6>#R=k1M+# zJ-xk8XT7}xVd7GL3uy8(VfbX9LcSVNKaOKVI;#rXZt1nhpb50`=^_9ZKw71nF3E4?T14__2cN%7gp!l~_Gq8IxE(k;4)uRq-ekahg86O9` zABV_?J;IMdg&DM(E-vk1EaLSKb`pD3p~i_SWC)@}+dUivPWTpsw;@IY&t1Ti0GjNx zVbFmx+z(<~*w==jtdzTlwHi6J~lbmfC)R zj*ZF}4LvH`>S2zeCM`63#JP?zcbl)7AH#6=bMw>iIzNpfuWW_R7-F_rb1}euVa*Jd zMaN~q5->O<+CMrfGdhmO5`!&lsAS9{qC?pLnx|;Q1(D~_Wr)ZuBBH2`Y>Dl~i+iK< zca5HiXgwdhEy$&6$=7F^J9+oY-QRi+@Z5bU9#Ok{Tz_%b81 zIl(XnENv|+c4g26wRVA8vC4eZquj=Fy_A%UqF&O&@GPKG0{~FyRGcf)fjPkIXDNFn zL6zH;Nnwt~_6x{fc?{Bn0y8epr#aR7E(+?Q;1uMc1o&fS&7K#|<%*4EwTf@qILkv2wNP^fo+VYR`Ut_ZatC(qQF$ImpQ0`*X7R1cP7u%)aFWg0d%cB40+RU;k$Q>hrX=f2Lm_UynRQkK^)q_>AXynzZMp z``DiQ21Qkmo?~&kWLNYFqJgN#@B9a95F4J)Catixt1W7&o`VJ3R?4>FZ5W=r4+4~! z+AfbDh;Q0w;bM8<^3hM_w0{v-FtZ3DAXI~Z?3WA%8XDC zZApp7=Vn2RR{Dl#K}L+lC$SBP1UF?X0jCq=Ng<;4sUMV?lLyrU$>=vl4XAgXE($Ww z>K=Cd(W*mOXcav>$tI=m1I$T8`JtkOKQ3mAYI~ zjYvLcC@K62bQ4Y3iD&->X6%n$_P^^uKN$&dYpVf|3UavRPB`Bu&CS?3+%Jv39X;z2 zev-CDJ4snia!6$(%x)wTox00#2dHkcHO5!O!XON6*2dt1lu&NTtJJGVfT%59sr6tg z?$xBArsmsf2f8+XB9xon4}^gZ?-#ZH#SJH!7GHpDE~f{gB`&9X;oBWA6Z^2bjh?Hh`k7o1cXdZ^ETnn>UXmrR)4&|f}&*jC;SB=%9F_9_Hkh*3D zi!m$}l&mvWFTlVw{)nKl8g;k!Q|r#J%y#oL%!^($KUVXi+$&o#7s8SsEy!a@)D?_Y zcMl?rdjN=tPRugDjaFqwCvt|AN7`iIX(T1GKNIq%as2dPm(AjisON*60HAf+>M;uA4~!Y@H3EfIZUnHtlFWJl;?u_`H&(LFvN zF#ph+J%tD8^v9Ap z1z)K~YewY3x=dEA!}n6Mbrw`X0tzrcAGe~_RuK)TK$mbk4u!S>k(BuY;Y#PQ-+C`*8uT(ZTdh&Xd@QAXe@~neD=<%`s@BH4hs#$_+sB0H+5qi|>O}oO=nq zF6RAR&wky9ka?vCMCs)@`R%w)zA3Q~$aRLHgo(cS66`Llz94vVHF{+VA=qD_? za&H;g4o3U*$mR}fZjRN+LDc}ui~b4nfQ^R(8%(0hfhDrS;97TVHTQ_jb_rjpEYMQK zPz28_V{+)CWo#AJ!|{)Js{fE|xa<8iXTKNG_nJ>Q0DZ51Mc4fqY^L?v3`}WN**;)kiw1wbvP1D_$FN)GXqB+N(x zW~nE|UUi&?c|KtlXw+5`=8?MXe@Vcs@{}aZk_60CJt_98voy?pgqf|uj8A~Mz>}F^ zKE|eyLOSG0u~*%u!90U>=L6lsJ^3xwVd|5<0gnVAc}Q?z+|KH4!%2VP=e zeum=VCI&wLOl5nNf!lQ8e;HV#1Ak-SA|3c60t(N2Jb1DNg^3nC=t;3xtGhu*lk#V;YSFd*8R^dL*sfsa?ehS0 zs19sl;A9=xz`$8Lu$qDEb>L0}R70OnsrvXt)h~Kd>{YMmst2&@yV?|4&n3($IxvBO zSvoM9fdh457z3+y;BW>^9oQcMg~xVJZEV$=2A2fyq@>)ONcq5%Vz27AQFXz2NKeYo z4&p8H)5b4Ap3*73Baz-qmmiLFXY+E^!i95z?KL`ZIRlM4Fr9%BI&eAysvUWN;?~aE zJ`20;_+3iMD~Xifds3hSG#(El-I;o;!lUgP)V8M%v@&q84!p&{zyG1Ky@-Iqqr?M~ zcwCUE?dX)0F^QC6DJe%LQYt(t_No~O5$2vqcRrn68Eir=6|Nx>C=cnyKYVu1NAzk zl!4oHpqPP}4h&%6P#xHVf$cibje&)=s%>poA+SoL+seR1O@g-=aOv?P0?Ae{B9hYT z>ovOP)C1k`b;;Y1S+(s>Putk)W06gz-0w-TS8df`_9d7mjpr01P^$wq47{NOCos^i z14lEk|0LC%A_f|CN4_VHUtzN z<2|(zk4qAGO!cJLt7d9E#uAS|X)xCl=1d)EVBjeoxRQabI&cvKALzgo2IlBM4FU>} zd7j#c$A@!WdYGORdsUOhV-wPy&o!8ygt<`%z7HYL|0YGL&losV2i|31xDLF+z!qI* zGXe^aJ3O@!kFyeZJeZPFK@7$O;4}oVo)JG= ztFegn*<9Vzo?#zs_SbJH*~?w;e2S`_@e_a}FuIN~`cG7W1qe`mWh_MT@RKBtsIT?> zLgv3+10?S{U1dI%CC8kj0+pRgKAR}HMVCAuC6ka}Po%%6(<=$N;0y(11bQ9Tm?w-O<#}0SjBxDKf0d9j`ylgZCpUx4>crX&8JA(qe zC4)^yvxeJcg=P(}M$pm#`#_M7Z*C;OehQ#ids$ThG9Kq>1c;4nP&wpo*HP0TTC5T9$- z3sb_yi7@2p&gGP+<{YJOuzcke*^|bOD|+_&vL^?6l#eY~KoHa*0(0&Pr4BhC)*hpr=n-rXu!W)M}`1V71!tJ;O?Jgh2*F}MFa!`Hfq`-a^C zs-vbLeu~oTIcU0u>)8|8}^1qChd&_ zxrXP^Nx1Kb8IaHFRcaUw3-QG!zdHmS9tV%#G7K-q?;c47U^Kjr60pwDhGcVbkR1_| z-AvSHUIJ}V+7>zR#!RQ{vaqVZhhVj_aH4M;sG$UvIV>GV0%oxJ{s?bZ);Mn{kX`{ zM4}p~2WoOqk5czvi>ru~LnAVf#c-k?eKP8=;SWNY-%^35i^K&^|HQMg2_A!GJ6 z$Y9@~h1E|307y5{x(^k^sf*{@yvD( zRaNqdWt3+*EM|0lEVr2XQ_As%Uq!Ik`7|mUyTx$}rKP{H{4|zN)SIq6>wOSqDOXn? zAx%C})sOyg;WBop`s}3s0IQr^aadzjU=S0F#Q>_1-sOD9Enq$G0blX?zHpi&9sLAI z84d_&0=^4Cw~m@zWXl&hkn@^dOIf3#YJA_KDG8kT;QV(^pnSnZK%$)_=qa1H6@=&_eKyGMYAS zl;<+|K2iFa_R_V2-mKn2kez4*Jv|kmK{SveLD)72WTe7?mE)Xmg(P@O4>hH^ZyOMJ z1q$BVfJF-vH23TB?99*sk*#y6pGB%DYiw5*sZG6CjQ(1tP%aS}+l&-83VLl;8LJ)fnEkNMTcr~;&8V64^i>$;a#bC-9VvY0-o^im`3t%TrVNeMpQwcS~XN} z4^x?BQmx$0uao>3efBl8$;@IW2k);isfJ02urfmIVugKQR3)Api)BB zThH3&Wy7oLY&avswclmPNfU><**Kj%OACTN-%vH7R>1ikWJPcs^$I4Mm55@EMuU&- zVHIkMfqHt9+GtV7ixB)y`c7L-wEk09gVWZe5311ht^d*S?m2xBu-$Wd*5k3rFdFEh zqIGRT573o}(p!`ep3;y)m+)6hh^t5LXi$12f!#9X%-P2B2|aRYn)1{m7ojZ6xrdvo z-%zv6!gYNp)1JU;nKh3(SIq@9XX}S47RCE1eHr+M^{o;;3kji(5C!1lMPgtSBW=O( zP$@}UUKk&XQqz}p@xj!p^q8?4_e?Wz%1r-F<2vGe<%Vs-X#p24ody68MV!B4o(-HQ zAiK~J-T!op(tTNv&ie2M_*e3F|1Ujy&@&&V{>T#mgB5_C&WRw4zH32~NOf`x4SN|z zYCsfSr*z9;Q7mu(j&4%77yOqZ7d=MFBb{O%yex?Vl@XPaU-S>e^94i{QzI#0GQo1L zgKk2f6Zha|to0sn?tM_UfSojStTh^E)R5PMq-ZXS@<^9Om97K$ju%n>Z?J|~hq6%O zir>mUeS^HmSa>Z7R^C0KFAJc~gC-Pf`(c0IV z(md!ZwgDwKqNH^rvqRzMm3|TG%RC};GLD!6%DRzYkmHd0P5%X0ILzN>FXNZFj41-V z_3s#Gl@a|-Dq=L?C8oql-O z2!zT3%9BM{=~7n_ZagG87vCHKYtfvJSAe}|Mg+ebw*r!NA5q0bXGpN_IH!4V5+2Oj zaxtw*!b`$(zPUx_qaJW*juZZwrSJZqOkezx#C%8e`2|sFzhBxf_jz!9?u=kt#dhMO zf%pPbI`Df?51)anLvX1Fj|X;m^Km}kl^3D;)mTED`*nG@OcXI14g&F=a-h`wHhrd( z4i#uqfKcL}e%4{%FsJo3*kfdxO(a3+Tz7p`vej%N$s_9?0|?)ovq89GbBhe&oJS^V z;LOf>3-)bkYB)w}80xJ7uczMd2qHjifiKXn`iJPfKlY;DE79wSr2x!s8sV>JWSzZ0 z^j>kv)-%m5G(8r5;hdQsh4(>H`-ZmVo<1bcC4juD4~Ymn6z=Yqr4SIoJXajKJ7YZ=SYGFzef zG@3lB`!}iw<)yzU;;VkI#($}AoLe94Z747O2wUW3O%c8T+$(VU5LSo-A`tjE~TJLq`Tg`tP$S)%! z$uG>GcrC{{tWa?ZW@1h=zv&MkuhhA+%nAiZ7qx(A`N&%VuhzTG82Y`eeZXY&tq$o* z%%8C-BW8X+5La_btAqKMzmdX8HC%b*=K{fJfiFe>X!lDmDgb z)HoUS=XKIoo%NsdaCsKTIz2r3oo*-(th_qRBVVtDNuSR;`ZLc%X!%sq=7B>LZQySU z%&=|}H81$^xA`8sRo%zTG zbEP2w%C_`}s2)}a% zVFHEvkD0X|^9i88WEy^uYc3mg7!wY{KRfF`VyeB65ioBJ;r}@p__-f2IY~t7JrZmu z)dZW5HZ^~gWvPK%8a&tuV+bJ%EzX_D1_U@c;#ga(IY|9Qu4bcQ0X7L~q#!vu$AtEI zXIh&BE9Chz#ma;{F9n=*@_fNU;ox$5E&5;liw@NhTg0n+s`x`XuJuNle?a~w6AT4@nG0!? zwTSntxYpi^-B@0C+K6BFyOMPY1l{trxG?I#w7NFOXskmvOAw*!6r=Hc2@@N%!d}HW zQmGRXL+Ujx*c0XU?ngCMs#!<7?F~`N1aN?3~Uhr8j%2ib7&o@a&}syZ6vMK z?8|AZlQr52palJH)M5=E06X}ZWi%d&Xod1X)QmR^v>&F&SP78UC*Fbxs$ zC37~5J;r{)O_^y7i3hHT*u6g{-AZ$BAUQ4kl>M5O*dF`Q#)<$-ub?InY2(0PFZv#} zndm7uzN2IjcJb05lT4+nYW5Q=f#)-bv84YJ>n9{6Hw@Y9egOW_giqv=2fIWMGQZKd z8P$}A(5;p}i7%!XZ6eXL9+VEot*C5d{PCuVR9`CyU@Wv}20HAk+Q1Ya4DHRG(Mn$f z#PwkI36q5X&hjM1Ho5Ho02 z;*Bs@C)xNms|^1WBU9) z!&ll8Dqs%`vIojGiip1m3-dfWQ}(M8{w*Hj&a}_F|MpQGvFZ3+&%dz$2DLbzbIi5- zV0yRSS}4N=&!c4=g2%8cEm7RqN|*xW0`Kca!=u2GL&+%^9;~s@`@9FnA!!?`qwc1! zNuZWfzn+alLncEW0%mRyk=Y1Jw{5)Bl)P(NCOSwqLEuLQNEHGpyaQWnw$#0i z@pE$jEB+mxAIP9^kq%r+A=^Id!f$sAuiKNvaK7qB%FZ8TS8*9rXg1ps8H>1uyWWa$ zaK#kauW$)CSHSB#ns$-YoZRY&Nk$02Y`_af#B>YU^ONm5_e*J4MCMCqd)IlOJsR!_ zcyJdaZR|M?>{6gGBc!9zz!N9dwqDnUJV7>D@a8zE4*T#PvZ|*XXfiGfd%+|NCjuts ziqOu^CcKS>w8}Etv;epz^Av=l3m~;XClKB=m^019_zg8%;LL7Q^_+oB7-uoZ zc4yY{w-BZEGBKvxJkkd>(s=?ecDoy^1qjRBx#A08gl{6Tm=JM!kJu+L*E3yYaRS61 zABnUf!HjPR*ts`H9utjFBf?wc$Rr+Yt&%&`-bLna6n%AIU!vZ+Ww2 zLzrLYOFz=IB0l`Bn|3!~3(lOOU(y?Mw)hpYX8}5Fmp6w_(RJ%pGm)TjF0cvXcUUy->^toKh6x zH~PJE7`|;=wiw_H1jrONzmq94i2;2;#^x8>Fku)^n3umMz6OfTdmO@Q`Y-;aCk1)8 zHX;xrpQu`#C3$E>T061CJAB0ceq>97eNU`@?Qk2mnibyo#>T#D~b z*cbm0_8)*lpim)rq419oe!GDV@Rlk zn7z|KZF7!&Rkn}Gh9-msB<;rr7UCDwX3{t-{WV>>#bS>KiNAeue1dqA+{kd z4PQsV&9@zv{cdR!>>W0e$88{r9p?VJ%j25>z~!-p@1MuxW_amlW4#=vgdR)MrAX)p z=$Ahrq4ZjYarMXKVN!3(1MHK~*j7MF)7T+E#?vU>;B8O34UXp$D`jtUBMH!jpD(20 z=lt_EKmP!cP4e@Yi^+mLM2FM;l@K(M+=pNqCR&;^FRb#h(MQEp-9|lae!~7MXC0b2FpiM8wD- z#`6zP%k-QI3S>2WJhk4+{;Sp~b-8NoQMaGFaN@fkDU;;ZH&RyxtuLzm{!xD*zt8?i z^Bew{*g6XjY*170W2io?_}!77-{deSr`LfX=rrXlSg3Kt@i-TCg7b)y z8JAZgGdv7U@cr^J;{E3sxCnXLb=tEI`&bEn&L%$}CO_E+c#aT19{=e1nrB0-^$GA- z^RJ)g-@clEt$*ekEMf35siXC+)D>9k%jCbz7nWQ|{{8I(&A*U3A3diJ`szvB*PU4kZRAH=&hW23qDiwP36=ZncAkC|f;QL*yH z=Ak~W;S}L0r=VMz37zmXU#HZq0 zRaOZ2umyCr&VJfEPU~Z8=Z70LTulyz88rR_fr2jpH zf>W_)F^z244ta(92)(~yG&~QrXf39MfQ9BU_(kp+?9XuRAKIg2UBlBM`a!K$HW{#w zUrc6^-+!b=-C;jT4&%vpZi1j9Rx%Wopm+4OZsaIKxtcE3P$Ut5BJ({e{k)Mfj3QW( z6gnk913Z{X)dk)nE*rr@{05wEVx)(25dexUCLsKms4&)p6g;g^p4=EWQ@1&4GSZJ_4YsAp=jp0onDFj>_HgSK_>Wf$(Z(d<^$QT&{frs#`hc1emn?%}Rg#25K_WZ86!QVZbItOhEy! z(0TnPp-98007EF&ladqt`WAd33+EMlomjRairdK+BeG8Ao*8b#1%=HB#P7vFa-P^l zE@~G`4a?WX-%IM%H1d<9M7C*N{A`W}YP@92Id4tr%zhP+a5+I(+D+`791 zKQ;0$mVT6Y-RVyBOVLAmdd#ZOi=6s-QZ(`>Al*p^&5XZ}J%5Ftn*W_G^Pe|F|8BHA z`$bc-(23N35vh&^0X$6G z15W1BEU?(H|j!8)4DyW>#zGK_-m+9~Lcf;691CoSQR^HqJmrK3)UHoM9WuY8nS2INL(PS6c=8ct*bha@LP{0dI!=}~yjBd`;U zq@(v;zm?ugCX4)U6MDZ46_#AT!p7xvXfjX2nXRUDrW8 zq1zp&Lw>2sxliHLLb}mG^VC|F^8*UF^A5PYaBgq_Mkm=nMakc@Dvanc=Vf#}^IMbh zYlOMa2OoaxT@QXec;evGVw~GOn#=2N&figl)tL3%v4A*xb}N=SFX_}2B#JNkOl?$X zF+?LHT!Ajr;rN~ifW9j;6d&pi*DKBAT#tz7A%p0zyqHYWP`59>9ZF5sJE{Gk`G@+! z{T_X^>kN_q*E-2RpJQ>JZ&!mri}NMEAXqSH@sllsIBmmm9JEzv0CS#)baLQspaUuo z^3~<<+QbWcpkW2;K`h}H9Qw6^2^Kc{cpyM<HOzSdiW{=cNy+xc0(_;g|f^Z#Gam;lQiuF7#gxVRWaaJHUJk*K;U5 z`pyPscikk3_mq(QREIh_R?_3nH?Ref5pL^yWdTGFdkt)lTD6scMT{$r5SdVj)oSW< z94}*cxebUV^VGe`w&Vc|DE}>tx7RkHtgIT_{IhFZ69;a!yXFi3#J9T*HAwned`*Hs zgtr-2crj;KDDWN@cyqA|ZS!9~I*rwr4At~)tr{_tpx~zv>){+@NvUpc)L%e*iMy>MtM$DG(b0qJ|(o$9*rZbw2^~$%=RI zYb~a*G4v8c`XqlG7q74Y;GhHE`0T}4xlmAo_F_3I2U37KS@e!RheUXMmP$ok6SfG{ z$aX?y?f|ChjXbgugS4W}SpH2m79CAq<9r&tK?f{0&@XC@a4iazbYM8b{slfU4jGX+ z0bxo~gmSQI#+!IpU%=E2z@>37V;K%Dkj*ZDrLU_LfijTv+l#ft8?xSWCiYV5@h#*g zdST?J6?P$uKPBA=A8?&nY%4PgX*x$mKr2WzXelmK(zd0Lc}r+zH97o&QHr0?*%&)8 zpT(myY9pYgev{kjihwFo`J6@3#~N35IJ&A(3m7@r#rqIwvoow)7IPOuppUfu{qZ(A zQwxDZA&f2}703fo&%Uz*;m3?%BhXT|Rz~C&d~+VKh<1_y zUTnS={^)zGXbRCLf2j#0v2e@}i;Ke9J5g_O#_o)7;%BOUg4XBIzjarAd?)Jh>f;Ab zPN$EJHKpM1baS5XDNxsEH1r2tYzUP`#}7|sc*H(+lJRQ%BV8Vnv6%es^yvC&(scTO?&)P$&APhdmd`Zh{D}8 ztuD2_{+e+z|9Q64{CPZwUi(Wh6KHtOUuDo#>qyT$f{W{^;9%nXbx>k$Pt!?eo0Rda(mVtGMmKgYOK{HGtaf0 zGm6&a%Fjlzv^(>j4GeZPf>*O2nmj@7x)8@h8Cy>OO-uvE?!r0nTG?M~l4%D9#A@~j znYn_Rxci_C7UGQxuF_wLJr8&1KRyYi^m(z`^B9+Q=U<(-^&dm|9Q3r7Pbgb7Se9Hn zb_(GspB=KStJ^#BwUW?22_;T^DW6-=XliPEtt_q3o=@>X=29fJ8W^@xtT05Kzo3&T zf;zd3$rx@TPuIfW09rhA#_O>P-!`M9RMa}Ek(k9ksPK-A7PW ziM+fFSt&>7l>4CjeToCXwkwYSJDtn$O}64b7{Aooo42ZSWb+p~2f{L%V*k-K=)u?@ z5y29rmv|4-xtO-L%{Q>FdS2ePudl^B;9r;b$b|oHd>Iw%<$}H5uXBb={_{Nfw{3Cr z=cUQtNAe%($zPkuzXD&W@VAGEPnIYDwigoc)8xNL^1syL!9S6I1-??@&y)POdh&0B z#kFd0UYh)4B>&}}{I!YvEAW*He?Q58f+zpB=M(VL=*Cz6> zz*j2#;gbJ6PyTK2Eu!J4$=^rvAL+?oo5;TcU#al7)0VY4%aeawECD}F{(B_%0R{M$Aq;HSwyM)F_o$zPkuzXD&W@b{DaCwTI2Ye~RQlYhr7k$+GA z+C=^p_)3MpR`S2soNVv5jS2W^^4pSsl_!5~BL50}rNW;g`NN+4+cqTNr^$bq1aXeDG^U5j=%M~yw!W&2!q(^gJ!%W+diN84?$*>&2a4eRY>+Y7RnR3Ulb07w1 z>^kLN{#@swInDXlYa@xzXHRy;XG$l0CU(ZBb&sx%Bwj-`ezW+CS(b}m!LP;d7{PB` z8vNFN;HB5k#BT)(5zj6B_29Sgu3t_+`d?Zxg5CP&8-Mfyj8 z1>e@XJ_pgCjqE6ATyeEChM6$OiaFu9nrf?Qm3qtDrO>Z!=Kz!3|;Cede zM97&PuF!sD?nel*el91y`%s5sPnQL?9~mvq&P(sRHTO(k^Hx0S-r4|peG&l6PjenD zXDgq1LR$F{Bw?mCGdQ&#>y(b;jjCPTJ6%bHD#Y}w7=8(4U4iK95e<45?Q$-0k%{GpUXBE%0$IUtEs zQFbt7%W>Mj(XEpevELc1bVs51LMaztD90O1<^WU3{!I2k`a&r`2>+}TUns}h3mJhE zgBkdLTBIX16&O2T>&{MWpV8kf&X%{qA>F?eM`UrQG|&tnm!}=q1kkgHt8-Qge)qDk zcIrsPsWpm)tk?eH$}-Y>=_Bdreew^`yLGRwg9~C@`UgENYGcn5iUpnTary4o(|A&k((%)F~e@Oq^ z*t>=1kpILt&zn=c>Uw3ZbSU~>2p#RtCl`gi==x@kBPCb4Z{m)9l?_T!ypQ1m< z&%kNU>{2q}+J}V+w?QM&m(eV!m{2_~h@9`;7>=UbL^>O?KorpDN6RiEEkiMo+E6nc10(dVWAGDdxl$4kQ_ z)F|t9#3c7AH9gK9N_t%V&~KwhKI(SqvF;7`yV!Z3eM{5BL3}Db@S58H89f{|1}EsT z0(Jj#dYpO;>2cAj-$sw@M7yh<`(JlyQ0%;ne(BO<8{$*xk&Ai5|CM}fQ)6_39#Pc& z3+aLR=E$Q-k24KP` z$%UGS7by#>i{IA zU7mAR_&JUt&kQIoEdof}D{OPx;lXe?ty>QNVlg`B=BXD9b)Eu^M)kM{3EaVLc5BXB+ryD|Dln}cTZ6aLZU zeu6Y%AgUIRT|JOhwSw3{z7qb?27t}3*+x5Hh@IPy`A2gJ@bXKFZJ>4J79uX3BDaNw zaXJ{&e5$o)!SgT7Ko{Z&%`Lwi<;ka+h!Zji&k+-)e-8@AgXoe-simxm)$kXnCUJHg za8K=MHQWowd4Z_kz_LfxegSJ=O~GMd#g6M?OJL)>gsVV2(!O5Fgm* z7~z$yu|pg9^x{z=jE1J00eFbwd3E-2(QMw4gd-~otg8AGWhX&qz|Wekz>Cbh!~Tq; zSvE+T+|#5-h{@K8esi>+?$<`+P9)r~jn0lOqO{Zf8gW~Rf^sJk-+z^FbtiIDxE;># z4pmjy^V^)`x00xJ*=+6NJxGK34gp+%Lgu&nIwZoA82$$JC~s}0K-s#MJ&m*7*BO#7 zO#VEF5I{%+-iAFL5hu?dVy?$T7if_hNb!@dLKEij_AGKs`MgUUvEt|zbQ5P(s+UO@ z=0ULPH_)T@qI}9fy7fCZs2&tQ4H4E|f*;)e&_2a_j4Fm(Ud4i~C=*}?WtbM!jRXbD zEy4b4>p|u>8n*$4^3V1!)_``n{@K_er4`>J;m2FStk$)H0Cy?U`)A`09N;rK#Xno! zRXRS!H(T8~IzGiOo7~@P|= zD{77}lByUUIp9!t4fA6H70+QsDFzeqo4~#lvx@kYjDz_Y?i?k3wBgtq89VuC zyGQZ`^xdR#*szUjmq#Lu)j71BE~m}3`9=Ir$=8?WXd2$=_Bf8Aq~h`nb2qKgMt8(- z*ZELy(v_Q=FX5K}4^iBbE~BFXdNbmz*R^kZtx)EFx5@m^wFjv%G3UGIIS{DDS}5uc z>X@dJmd(K-^7K`Iu$uA^rq%BUjMwfmc%PN3k@nVrQQty^>KsT&F#VD32cC7I4{&FH zH2VVlR4`8m)FhSrO$u5yrb^01f%1b^01&Xsg|ibQ5<(V?an=2e#TVj}xHdm4HQH5%zVX@oS`6O>72oU<}B0HokxueAu?Af8bln6 zx_Oz_gU;`8Z=5{7oO43p>b6Ci=u*kq>mF%)wR(n)=bm8j+fS2wbrsfHPIn+;QC?SM zO80*$650{r9xcq!{B?J!szxJMvdQr~pfkCT>}+}7TgpX*C2#y+T7j_^G6QbI5(JCS z;It-54>`}h=^*x>`~IF>-(ij={sb=u%9vw$>_gR!|1S2SQ5s{S(_Dx8h+7D_(ejSI zTBJ>`Rp_uL*jmW}gSkn}=wxFs;GBmW7RsdaYa>eerdj7|{8|wi&txx*+>yb@@mp*m z#ek9!i?D<9OI9bMB$b`GB`FYRff6c*943HhYJ*;@`A}H`niP*kIAP+SfD{W&kj+}F z=Qb9mLq<4)^o0MGwHTLpF{Sk(*pDYv3%w**5tc&TVm~<+F>!704_!Rn>@TM3;=cu4 z%)ur|nsZS(ANAaq+9O{^S&{FA-xv4pX~J*M*{Cbk^$Yy=$N-=f@g#U)=)9g@avi+~~sM%&gvst2X7&@0B#W?m5?f+yjV6dKsTBQw@{}UI@E^TtL{@MOdHWHPe^nXI4 ztCswb|C7y08BrO3(*FtDfd9Cw>?~&S|Bw8i6tMpd_^b54hro=fScFU?8@6u%!nhOW z&S#YW6G{kJ`1AaqdivJT-f^iD|Pe>!mmGXZ=<|5wf|3qY7j#uFS1iAtJ zbS8R!SN|u&)ljDVpAZoKqYzJJt77X3*jhXlk-xzINsYk#0skjYWV`-P*kJy}7Q12_ zTTBf2hd!lT!?>u-1uC8WpHTMF`#%w^z5Y+!&TXFXP5VC?rYMN5P@!9x{!hqw5Rkh7&UzO16cqm_WikyBBA?qVL|&qZ zd>g>9*XL7@t4-Q2elC3D5(K9I6Tv^7|C8~|M*k};2n?$2PGn{{n2nV+gqxHZ#7MV)q<;$J=@(PT{|A~MT z8H4|mW;B$#LHwT#{86tPRF{MuKLCPCe(68z_K7)9?GD}1)qd|jBITK< zUW8|eu^aSnuETKuE!E%2U246S>KDS&>n&NI?8+lQjHcxJ1olpofgbFgjs~tE`ecld z-0G%pg<$JJ%bcu|Oke%XU=Y}pD{Cd>3MvDp;VgQEEO4ryK%bC9tU_njI`_NS2_ZgV z2T};2w1c7vL2-mH>2lsyF3VJG1i+>swA5L2IPOl_8kNb1F~dRlXI=dVtSw>JR13SN z@sS;Me4o*KpoKNly2n-hG3UdlTug$_$Bae&5o(R``XrF=MJlo4p;;~jiB_sPraxG> zmlGJA`rsknPkisN)JRZla-6C(YVB%E6}Z#6yUvQ#{MFDuK?#ea})Hwyf`)Thw0saZ_<0vAAbqG z4@9LuL%wG|>b9)VS+>^wE_Rk9{+H4F9|M0Yz2C;}6{#F^x+gFRI=zVDFQRv07f}Yi zvw&V_CZwgeb2H6in>Q>2t?O4j-O=TK!8}R7RnlwIq)(Cbu%zduNgpoh=Slju&0XQ| zC+R1s`qQNErWtGVfvWyA>DwheOVytyeXXRwx0LPM7VBF7&62)B(pRKOpC{?JN_uUY z^eK`amh`+d>BA-cJXQauuJ!LH=_e@oulzsS-UU9&;(8y?CQGt`g?G^u(-v#g)dr0< ziD?ZQBt&x228n`@R#a4qR6|ACK(r{qcZ2)7te|+I7pui6fVTGo&9b z>8GpmGo+1 zy@B!D{wLx&MdH|-z8hH$&>R?L?O%py?)UTk`(s%nPu>MP|8^OvVMZj4)E{IRsry59 zpvexp^aSk&O;5Ld7GqHyM`l!tXWs+(rW?2!6!HoK+10=Jy^ra>NgD5As!Z!$IaA() zE)0-erAvfeJEI{Sl0b>&uC}xv7naEmY>eaz=a1!F+WPi)6{PgtLj^9?sWh5E?SMwMNTQdPLvp5n%1|GT1w6I9lFhO`Fj z$$Il-gLA5ZryY2*0W*)qYytX|1h?1z9`L2@Lb}Qa_i+bau1h=FkR~4@Umpx()%tJL zRZH3b&b2*|@rC=};aaAwfhfDp4P*Z=o^7F($J!;ym?K)w&Ue=YqLZFQM+JSF|$Q$KM$sG5*i@Y71 zM$vj;fczyL7$GISx9IyJ?ifmb{=pJ{rkv+G90exMb6t#FN$0r^c7Cc4u4>iN1$GG$ zDCuy{QGrOm{e+T;^s`=_pfc$gHpcbs+*aCkC}~@?V#C1kL*U=#|?%ijk$ls-Y@@paUX#K_}8;5E~ALR5Y>HTxehLo7${d1)( zWIr5O;_Q5*2jI)Re-2F1KPbN+F!KF#c2MOO;d{adfB*dGbjt|yFx&i+xgR<*!~5q$ zr2aQ(c?seCy?&4R&fh!rEwsy6cjrCk#wZQ|roYGBJA442+2_bGOlbOVV{O5mulzo9 z&tTH`uf?hD^J`68kNp5Ux$x3yn^we-m)wzv62I_$=CAdr`MApOwSR>CsR}-M{(7>| zGf~m=1UNAr`LI5!c-3PcMtbgGZ52N5S}(C5eOP^W+nZIlr{p*<#TJ5EO3n;`9`t?Y zE8wUBjC&m9dEiM^14^Fn$S1%4&>{S~7xc{`eOID<=s9mzkwaIB{VO1e)l1#HS-k#^w_aQ>HT2~HbUmvs_LQ}s7$1VNHKofEDWOK;C@8dt;omd zUuezL^9gLY7uoSN9nl9h5%$HJfF3)d(*N)8Ghdn~{ofRMapifOTR=Su7%0zg|JLC^ zo+bdb`AYIUQ8lG2&pXhAGRbpKuJr%wQ|Wuu)lF6QZJ@=`)wrHo_AxAS(@X3hF-(2H zb;ksi+zFw29gUmB&SiJtJ$yoHkDD-nLT5kKvV?Gy*txpsZu>)adL+LNlBjJ~CLuoXGKD#x?W|S)?yBUXqF=9 z_T+UKZ(_>}pG<;p-HeN!-gvVgcmF?eEXG^$C#rStW_=#`P8I9Di@!pNRLVS1*Pg3P)NZ)>f)L)g4r#jR5 z|B9sVx=!k!A^l-Ve@)VxGo;5P{c%Yz%#c1?(w9s6mJI%g36efnmCy7qVLyI5n;mp4 z^ZZ}u$G6^x4k{yBvAvp|Rl?Z+fcUREKaR}&&;L9>_PX@oy-!U~xBVT)s(Iq)&X03J z0a$U6`Eg$s*%i1}*yYZT57DLc*e_x+6M89Se*Ecd!T34zWcI{}nY~X?}crGg=^NemnyB{)hQ-Pya_?*uQ?NtM-4HABP`sWU9(; zcEdq?+C3s)Uuk~4;xb)3ZGlw+AKL4GnjgP+e}cZ%I^1nPw-T{mVt$;PM$!Gi0Qo!E z{CNHW@^k4m!q1fX@%~?b05x+?^P1<#q;A=xc9Yd z*VUkH(TbM`&W|6K^w%W4IYW9((jS-f!VKxNC4IT1Z{hs;3-ucWnG0onbE^=$I?kAG zgn1;#ST)Ooomtt&s9f27aHSUz z`GCM_m9`aECefc}BaYX+wBA6$Tu|fB;)+hUwIu_y!}+G4gkIy;GRK(Hd9MGj0xuQG2Yo z)iHHH;QarJ{Lk0=g!_?j9SP?Av!YGYVPCdHYvy1FNG+~wIKk{2JI~*HY=>S|42?89 zJ!UuR*qD8yx!z;$@RU!0-8eRKR{y-eTgZn^qgzq5*;kDVR0p9q)D&5J&9}#5S+!!+ zU(Eio)?Q;VykR{3H6wOS5qe3nwb|OxJ5kO@L67X&(zP|0mO1`&_D;8$SFCgGe#~nX z1yo|z2R)F=(w_Pv;LGxK^Nxv8Ys)&#ePib}VIEe>CGK47&z|*H-48@~Y&KVLDT925 z;A})WaKgezX#XJuymS`sBvxyFk>?dpBQS0NzWI-kN7g=|so-X+RP};+b#XOFh}D!n z=z+Tkgc}{_dJ{(!&PSNzcv&Y8Av}a<#ENk+;hh}3u!|thJp2Vgu)ZV)c0pm#AxVV5 z#On=Z0~T0g`$1x?E-<>!xP7g)8Dtj6&aB1}_vKyrdt=uIA}9ja$}I01-EA!IwEmLc z7Y2GG{0CwOUh_S3Z(gJhCBCep^2%#YHuw4>b$Lek_bSR)UQ=oA z&5zXiaDR`A$}g`OZSEZ$smsT%a1}MUyyg^h?~q8{U?V(LMGYyhIn~_jkJJspQ7IMW zFR!UG_YRHJ`Hk@5Dr#tX%@}j95vju&wJa4iti0y5NZl~m0E>o!?4lhi%^iWR9bU7C zubr26eL%6SVk-Ipg?pH>_-2a1f}uPOP)exc*n+{O_$`T5l~K5M8CQ5H2{Vlyo?XVm zywD`Z5;_}6;{rNuTmXsn0c^w4sX0t7a#D+!S`<2rsZ1z!5=xm+3X-ZkeWO9Jy5<+% zbx>BU%~Rf(U5eO>h(Fg@TrVx&ILH%g%SJ+(BsAuFjKwGDlO17~WPj*5k z8VBXX+Pp|PNvGr(i}#}5O!3Cr1|g+Fr+AIUxB@^@2F2QPk@8)gGRRomty6MiZFxxf zo=yR6@I6SLyjYtLDJSccJjGv@R|tbxLWZ zF?SgI7L*^Af-_4#e;uA9iI2izteHJ|(1$(Qs;7rXAgcFWsKuTdQPNPTR!tGTaIfRs zl35e<#9u~$QdQQ8QnE|S(RgSv0FLf!-QIi4`kK7IK(oYe zM$Bq#=fQ2)I3KVYjg}QZnW0>UPGAVCIV*lNLr_gw@vk!k$@Ak8!28zxdiHe9mUy zG0~q)H*Rb)EOktBK_K;;_oY)zO1uMvU~VVJCECW3h)l*bMfTC5uCtA>7a zhu{g;A-GI+2#Y8>#G3M7kFZkhpYOyss*2+>%b0|JJsr2I075I=&@Xi;ek8Z0VLv_I zW(Wrmw!i;pFV3om*X`~f^a8VEHZdIZijz#QUanXNCm&=8N6+i08y$ax)B`MVr~;Fr z7#=q9ol_Q_bLSUrJJ64faDM>!%w?33URRRp7{CHu*`l3#{4_bt<|C-8k{S!E1nU zj$dN6!#(AAJh()uBsv9{?8pCvc6m0rU3@&uhk?>-!BP1h9vne?bX#?3 zk-Kz@^eX^qk;OoWR^qy<+aiC#xk9wa;lOY988`~gfE`erwbt^$_ieubeEcy;M*5+d z_-M!(w=Lp;V_s~{A`-kYUdYI_<2CV+t0u3%@QeuRp&({D|&oPHc1yqw>j^Eb(z-3dv*}xzb*&HdxKsS6AcFg z;6-%Kbi8W;0;0d~#9s~})1Z)%N*}Jdzu&lREh5A7p__61DtrZgW3_?NVcf0+@#**j zIvF+*G=ZEdt7p%@%nuA}Z_F!px7k^Z=u&fkwQ<8(i~%&?X>9b=6`?5hAHU@f#>R2k z1MkeDDSYjSkJS|+0@wVvb@lNf39tRbA1k9ewwV17RYvT1VDs9Y8@yT3+og91;yFmq zvd%7z-cI>LVHMU?Z}fKda%-wDx|sdLs`u;4_bk2}-yEHK7CXu&TJ5ubPkqy~*wHm) z${s*bA)NEI1amschC(t?{TR#Fni5CW!FKkoHNxKmyt)4n*h2`Qh84h^6&pv!R9ju> zs#TsB_iQn@8l!Eaz8m6-gWkA{%0WqX8LMy-vi$67v)>b4BFz#R&iKeUOpg|gaADEk zJp>$Q_GdeQXVXpu@13=|xk2m`VxsYB3Io=50mjXG6khNxit_wLxLDpiwatdTFA?wWkJQp%oLDm`J zlT#q`2w89T`&`I81zB%|vr-^^glsVT^Ib?@8UZdf7~z)+lKGiW$TQ6T!7gOJf;AHrkV6SM0e4imkV6&Z1RR)5KvMn;$RFBj7;~KEf)B$quq0A*mbJ~=J8BFeo#EK`97w6@ubS2y!zc z$W1|zrx1KV#hT88yvzvrBvhgbK84`^ObC3L5pV@JfgoQY_)#VV`I!;qryv-t5b(Uk zfGP~mj9_pIf*}gQyX2>eM1tc_;pQ0vvv-SaMS%SUf# zr$L9PVuwI7Is!Uhq%m)(**Of|t!i|4Duf3%k8I^_Av$zv^U~%krE9%_zZ>zXR#ng9M-a!Hm=`O7=9FX+m4wp8G%_z1&JdEe zZdCBVG%`AF2Ao2HG=w_wmmH;i8h(#Fstug#n4~898laxy#e7xcLp^WnJn}`1 zdKFROdKxeBxL^`5qtf`oWG~CZz9a)1wQeFKh)s^!9fCRfdB#Jlf>7&h|!| zeAd~%Xtm!O=Z`;+xfbN+cf!K5m*PjO?}>bovSTGaqBqIp5RGFM&=2pkFKw4YjNvd+ z)8<1m$Btix1m(|J4^C-uh~u>rK2Y`yt3GP2o`Ueo6t?@M=e=2R><7{LQh@-VrzZr5 z@Ek+vdQ3ZYySN+$g~ZmqP*L~}L7q^m6+#9uFAC2Z^^t{rTb(a{)E~#Ii##W%sEJJ} za^_ECEwTZ$nO)V%6FmznOjLk4 znCoyU3jaQ)dgb-iFrFjzG_F~>2o^B@s!EqK1*+OpUOx_&bfkWq16Gfvm3s!jWtZ32 zz^IPY*SK(4Z@F>+TuyoY>9`RvQh&M&heepN1K_;n_2bQbgCh0gT{y219y$PSPg!xMtl|7-09;;qeZ9HQ7pbpz;lP*q1K@n+ z^$q5}{78L+3+FS!wFBVt%j?fD_YIEJpW(t`3Fy!PaD&V1&ouW9iPWFz!eL$LZLUeG z#@F>2QeOXkbDuv_|9uw@i$#AJ0Ov2SZ#4G}jnp@~aDF44KcL*9<@FQHeMY2yf(wUb zrOgBI4J)rdD^h=!3#8VXtR15^!(3@hUTJDjD^1mS4RX|GS!MbSIt4OPsywgeaCWpg zN10mCpcS0V;X<^1s9*)=TX~pxj6gM*&@HUts?)eY zXbd8&;9wwJkpsY)T@4qW#ubG|5`d|tPAV6k#&L>=sKy{V%&Cn*%ysM7NtDq53NWWD z$d38*%7?=ZqWvKSo>-G-^k0p|-z4Y~RVQ5A*XZ$-4~`7h7G$I`8*tf#+eO`z440h> zmmO=$A>7O9a5<@PIk6@$;qFO?^QOXiV@-ny$J^Ob${mynHz?MWOE|foF`2&HRJhz& zQy$@X-CPR3yi~ZnSd))%a>ObbpDz{87i-EV+&?H2$#D6paQU&O!GwD}9d2+c+~8Q# z5W+>%;fAEb4T&}RNB?!+r730lQ(^qErlEj2Jq2cHD$LMW(=fmsp-T*ElclF@yL#`rfeNX|dmJldc6)JeNyAk;xpeH=7T*X+t}7{16!oK7 z$?ngpy1rGrWtEKiq^}GUf=7S}!7Pv1g*x+anM1`-0A(1yvB=0`!F;j?#*84{t@p#C zzvh-t&Z~~_e}RWfkap`fIJNmAP)U3i463J#Pyp^Eqa}ua@y|X^#%p~9(~p>Y3kDnx zL4;NfR127rHtK?~-pP`7wr*u9)_+)Dd^zx{*`l3|31j?Ol#Ll9SK-!r;`ic9tx!IT z#Z$FH`6xrOLiqqg@P22-?_|iw&~k<__+`Z{hM>l?;tLsqqRxu9GDKr8emO(1yR+gK zF$5)*6`#rw85^I#kgS%T&Jazk_-KU44vC)mq56=NALtKEezW3@`a@Pz$LbFuw_JY+ z#mDFmA-Yh12;D>Uhmd}tSCu2wf2=>G0`KV$sl#UdA=TKRKcpsW@WJyVSju{x-GCEZ zDEIN$^L6EPywkd=^$=O*A}|+1W&JNP)5JXrt{*-zD^1vy$x}dQdeO7E6UaCj#0{yy z8@=g|_>L_Ijs*KgB1i+UNdE@;YwneI;u*Z|R8ZF-Jsmb01ck>l{p@}9e?up&3tDxd zXkD>Y*A}fSvFa9(_zR@bxFHG~+N}MfUcq{5z#E$&?={UWFWZha`apKbK-~+Br;eLx zjaoxSG1e1W1}Qy`DUpIv@pfg`@9sjsz5%2IqyRg5E?_Ny8(U$ndKB+?mu&}ud`zb> z>OT%#EwKE>rgZJXtG1KNo)+|uZM_{@k8z@_cGtCGQMU<;x(%|A?43Z@+lBcU6)W@i z;=xI1iL6FF{g8Y4?cY`%W@2+e5Mp7#F(=~k4 zh2R%<*EM}hmM;VO8}O}m*KOeLy0zAnk$Qp?Ux4Wrnk9A)*E6PemU$8$C z>wTkM=jz-z=9m%WdLK9Q1an(UAiG|6TFwP;{rVs%WW3fslwWTgv8P|&P(zLazM!`5 z8Fqr+om@Zs+iS%4@kAG25wko#ADyAS9q9OvF~3HPmi{26{?()QaMQKBk|_OC&Ntp5 z81GUT<$O=#eW{5Q*e^a`JN~CqD9Wp{?Ric(X#3sxB0B(r&@MrsD*~YN(v&#g($98d zoCbTy9d?cayW;iTYR9zRQ~cgFLRQM2V&ev0hl5V@<<8w+MkXx*9{dX3r7qn?_GBI3 zZU2z5YESzNp&YV=Z_dnl3~0ccQ#ZbrO6e)U1h%K`HIDyO=?CF|-X^x_5obw@rt$wv zo^O8P>O?(OxMAFX-YPsV5q`tTsrd|+vL)cwRCnbh@j75v4&Rf)>o(v+%~N>&RnIpE zU7D)wzBWZ`w|yX_cnf#a=bmrAKafh%`@k@er|$XYr#6zGe`yqcrtIGyg94*i%N#H7 zRes6++l8c3oW=!qBN1fSza91ogm6&oL%h+p2US%r151;+Kqpg$(v=L%XD(AU5*p{yT#Jc}p2VE-alsS*A&O6&b* zCc{d{0dbqPziWGrwRg{}SWqiA-_ApSc&*Re>Y?Ah9j?Z+>=APv=_;{Lp<0n1Q*58c zc#M6(QVDtD#dgK`X5Xmbm+0P3R+&aoiCbfAg?e(z9(%JHTGs z4;y~tQQ5dKc@-*tjKuZj+qguzG=jmCcW#ptqreHQ47Q<2{)SE^XX?99vSO0?K9zaO zQORX`{FMH7$Db)5e>hX*BkjJ5A)pbYx%XA*e5^72o3{U|MC}v$B4}429^@S4o(lD# z9vDT2prSH`5Yn(SK(*37c!v7EVRooPy)WCpUe3<9hB-lS>fN*SIECB&Pec& zB$T1B=xVl^)s3CuV;DD-q$mP-##*_%dH!7qNiz!V-<(>a^2;SI5Xnt6$Yk`AX5Ao~ z9@dlX5}Kpxj4hA$3iel#Q0PCzOS@o;xPHX2Dww7O(IzSS@4-D8+T%;#AA-GD5K~ru z>lFz)yqczNdoU?g`dVo~8M1J8rp zDe3DZeaoK)re7=R_elDR4C&`fx+&?+8Pdl{`X#FT4C#kU`su3tmj{%u#=n;-Pe%}D zM(_#Do2NtF+Hd~^P4`GUnjh?{zy`@v8T%|dppq!+IIilo;FpV)Gw`d1Wk}T&FJso)Xgg~7MN#nO(iX2JHot}dEpH(ZYFGCur7$M)DE9fujGJg*q!#Sr^PIu#)8or_R%OB-LJv2 z>5!;qb*w(s8=QzL=K^~7lswHo<1!~) zZO_*6-S%8Jw$i@T4OiLcF-$$9kfQF@AiEN^CO@iJmqlyI2LP~nVD=Q5+uOnPf*2kv zg2)4uM|Aiy!$|wX)v0V42?8KiE#h}jE61va@iC~hzOUzlZgznFaUvgbUxzjoAsN45 z(X@qN2!farghTi(g+Q>8s#5HiO8b}87s7}}dyWp{KExlZ*lxQ;g>=(GMPh#@(%Aak zDgl=d+Z#16L7VIL<`&Q75!7vSBS(zlMyJhBM1jIQx6Mn^+q~3i^Y63GVb`J91qW$u z)SA{G+xZ6F&TCo{)w@}TyX`w>Ik6>n)D4%~3mFFOXsAZ=4YZZ&hAlz7*WA`l*0SL= zL)6lxv?kbKegL)1mLgY@^qUSNBkSgpr9oYw_d3+43AOTi(T zpH$)q*A2I!TBEqO%cE$NHExQVh2IiKKQmJsGLgkS_V0D5+rC$YlG^bW#w24`zAysoNR5EF>NScpG{Z3xT z`b`|G_1W)&?WhNog1TA;qt+D68+1?Z=!B$Rh!Ps{djWnMVg>sFo@LZ-F6+0Hvf~Wr zzliG%q-r<#hjp*RYh9Sapx2F;X-t6An3B|K%mwzunP7oTJFM|iz`wHsS$&vwIA z_C*M@yMrc9a2hdW@k#fhXbAQJxq}KJzQO#c9Z3a?x~K(EOEu&12B`%RLyb^qS3D&) z<#=l^)H{_n2;?N^Le75Pc%~gOukAZVe){%oI%-7z+EbMth>S2g4x{{}D2debGCf`7 z_rJzu(hmz$^#iBb)DP7udZE#-_>qz!_&c;N=&`5kIPAx^C%fSWyMbXfCX9p>jfd#a z&FW5W+;O2$jSKX>QtT459z7-;u}YZIm>2`Fmos$?a32w$^cD0$Xd%1BMKe^DNPdUz z_1$*Vjjgg5x?#uz!>XmJ2dL&)xoWiZc%|TVd$&=$Lku8mawQC#*@xysh5`$7s574w zTPj@#%w!wNd%~0K!?5~;{$C~S^&U7=3Xfn#E(NP~o>dhr+inMyYVxuoZG#43tI>7e zX84ao#H_KsNXHq5g(m}i4W-Qf1pV9WJ8a=lNXkgdmazoy9j*^BTL-eG#K-DnAIogS z%R3}%Kwf|E3(L;6x@mH?K2Hi`rwWBHpjxPHi9PWW^oZ5%C=R9`cEt6ED(&N`Rutb# z&kaxfg5Br(ybr&NaHUFDjhJ)E} z_NGsg((FgkM-M#5+B|=X)<;h`mP8nQ!|GE6Ka1cofT4B6AF&9s2M6<@e>xsP7zO(r zwOBM-ouSwXmp}AQJAl~WdoNPa+?Hk@zynWh$cOXLbvupl&k>gddH_8qy1WlZAEMFE zcmN`RmkgozsM?G9e5gVS4H=>bqpolC4y2SA;qL-vtk!3K#Hk`z_M~v0g&|`=#1mNl z!$tTdKsKIPQjmQc$RNwb4(IUe1@Yv+ecrpD(ir!-aWKm35eG9<$|%77m!ulr9hBo> zKnL*JMFi8NkPO;5Bnjjk19F_CZER+g9>bk+_AlX~$A=F^D*Jy`F3lI0G{S;9JN!ex zj2P@$SYRT1_!!lb;HO=v(+YGIeE0@L39CSOK-!=F0CAc&e0H#R3;6ey6L=d%iw&=0=vBhIvFBarCWPiV;Tf3dyrNf3|tnD<1ej3#-Wve;_k zCM&NH=MUPKrxNnnC8>mzc-Xg%o5rUK%3lE%^#N&#WzZg|=g!4;)@?G%o($f>nG*X+ zfK`2Zr)Fstn@1Yf?sz-VGyqvlbm?;EV5D0nsp&2QIx7&GVS`z0t-pF41TksUngZt%xYJ+!P>8 zDidew)O;*84)>g*yKv@-ncx-N?(elvxd*%M9>E4Mncv&j{u{cX>z?mHH!NE5=D_=g z&X;sk(wj4+kCF6CB)u?0`r(p(x}M?~?w) z4C!}D`Z`J9@{fV#Un}YNNcxHl>E}zjDe27_(#J^pB?^Cr@(-8v(+^ty{&%JRl3q9v zzv%A|R#SiXSE$hl!(>y!Jt&)BlKi!4`X7Uz3|*6_L6&6RQ*5_Qcf#HB~mdx}ikaFQ_XOWt>M9VrnFTxB0cS|nU-*SYbqZxAnvNzwVG?gL&m1{~usr?vaB z!1q7gceHsGtG1(DS1skfqm!seGptwkel30KAm2(pitX?PstrJ--Ry>O|IrUcJ~$nu zmi$udXD^P`wH0~u+LgculK!Xlv-i$V(6?HLasSZ|5DUt_X#MPaX%yWL43M9sDIAQ@ z#QnhYpCo^mmI;5=UJsl|hbp%BH=`=Eyrcg!{~Y8PkA2LT6rn>l^p42L-eqX@YGy1@ zl!}4i*#WM5KC-t$Dy*HyV+w^y<;c0OgQAjzA4KVM@&7$Raj3PWML*n zixFGk%Ye{+6tq#pBUN_0qts#5=qL9EcVfVC5U*2snW2;!0M&rsWAd^LZn+9Q$&?W~ z$QkeWAPS_bU!{DLsc3P?)=T({}w9O zb#y5zx2W*X1N`Imo06U*>02`R_t!}JyC*XLiVW#@O8PoUZyuN~Y>^8a)%woVDQMR~ z6!Y292SSIU^$Nk1x#Q%`!=v#yjG=ePIM?#&y9fjgZY8I`^FfdE!eMAr@4xi;uUxLJ zh1%O%oa}9Vu=gcwoxu}@9_-bk2X$(H?`EBEfd6#8PH^sHT=ORR_wILC|1AT@-%0jw zAEWfFCBTeepZ)B8V&3@9Q~Q%9**8l1N+d zcw+4ghG$qCp761W;R$DAisAY3gJO72dyZ4t^Q@h+2W?FNP*1nx4;GN<{FnoT1%v=i zj>m%NIB^iP{6$q@;Fs7J)SzkzK*ijr^ZF$nGXUiAVpb*^I=WC=X;`0{D?@PC>$$ zcKivAz};Lk*R*AYhMIlF&)khDWBfjx!hoK;c9P27V;?#dAyCP(z)HVU?dYPN*s+QV z!?mj_yb1`i%C`4DPdA~+(_upGiHh2^^>?nNV6dD9DUS{nmZMJ7pa#GAsfaVklf7pr z$T(b+)NLP4f^bPC2|{T=$p^vILI9cp-|8hNH0WwC?p~TPz?!?u<<|!fvvvDNN$b7` zz8;Yco1S7tb$#{AIEt8}&c1=Er$#|9OUrDx% zo(Vorxf6MN;CJNT^TooywEb11l)SZ2JwfJXq1|Vo!Aer(uGpS|;>lt_*_Cb>>zAlC zHN;nxyVl{lcG^Vz8c?F$QcXk?_5X5P*?u7Mp!+6CyiJF@?O#lUM(*^|Lez3NBTWvu zi%mS2TOF2bqS}E3a+$Y!LKScgs_-(Cy=ryIi2=CG>XQ5v3U#R_7=OTa7 zdlHmC0<8v+lA;3pLuLRynxBg0vT@fw(kDDi-(t0fx+WpiY4bnm#^3yw)O8&z)O`q^ z262sb=qF}hPG}r75ohLiVW$qC4IT1H)lwnAn9{e`2*7@*{A%5>^_G8GlI5L?}7=^u0cz* zk)Ld%R>Cju!}r>gA$x!?R1KN9k5cUa2Z=FDVcZGPDx$b&Yqi^BuWr=1l~FF*uHaC? zm)KXJ`?DS6Ue~V2gXG_q4E&od>B}X3#lUpYCsT!>D+n_qcqQvD`G-WFK`Nn3_vD1tCryo%0G(Zxf*WKB00-w?b!8@v9y;NRFc=SfpiIQUloWh zQLD>4cs=BOR$p2FZng529U5#rHEibd*;z9!pN{i{u(sqsE#j|?J?4W$5SMG1ZQeco z_~pVyMUZ!F;3O74B&rlF8|lX3j26JE)%Olu|09t2UWl;$%{wr=p@~x=&fscLXK%jQ zBV|O~GSIFGgt`zSj6F6(=t0rCm}F{LrYesmJ$n1Vl4heMs0tb~Qu5I8+6@S#~$-G>`t=kt#1``Z>I_0fZc4@rjId^-}qa*Q|v1uzZnK;bQvkPy3Ku9G%p3yKqM_>TujQ9g#zrPoF>ygDkt^CsXJc= zsfD&5NB|gsPadB}xC%I+?V4j9tTekGdpK4H2u(oynWf?lp+Bn-^ZaI98N1JmcVa>? zfHoTD<3LdM5^j1JLNT_Cr)i+-JvYN5UIVASCdZzn)L`%kfR8lqgp{sZzz)O-(|6qm zgxsS*n_eAm*Ph~2P`=~=3vNOdXr#$%wBd>p?bibQdhJcHkH`&5Qcnlj1jB+`5RzDd z_5v1PgIM~pknoUMVKlJdcck5nl32r-8oQ9c(7u-)1cCLZX$)46?($Z=U|tfs$rQQCMf`uVAq zBLCkK`F|aPQO)|@T!(t2S9RMxs;`fat)X18cnSoK#D&SkPzGy^)Fivi9NJE8BHCX<5{UNuJ|4N$#(CLhliZ-n9A9m-KIk zYE|WA|10~bs1NLaMZ8!e2cHyC-q_|43!b$I*v)lV)=HlgeMSHFd*c%{_%uD;_ApYZ zXG17~%YsxpYBt0*C~b+pQJc%5HG_Y9lKuC)*|?vKl*V=Kizir~!bBUx{T8K$*dY?NSY6LS?8qw z>U}7UbI-}xo+>?_nl&0FZPQQUpklDhyOL|4TiSOvr-7#C<3G5Tf>c=F!muiQRc zW!F?YTraj~y758#GQ`K0w>_|vTi|$_g@f@7js;MTG-rlzQjG z*JRXpdvX;pr}bpRgo~Cg!6flY^5())KW7J4+vwaNTGS%#@Mhz|_>|ug;=2NbAYQ4Q7dfy z&3>!3%?2Irwl|)JSlu3~g_6dPS!jg;XYnpbqwn{?mCATnj4i#9#CR?C!~CC<|4T;< z?BDyxB=_$hB6pHMqxYNWe?NUGkE%Saqh56)1knBqayuP82bD?d=pCCvopy9hURLjO z%RpsPzfPlX^Up}%j;{%Qu6^IdE+tGWvF~F^2=~~((6Qb2BGu*Se3<64PZSMe_#!1= zrQ>cZ+Qn)}21_Z_C;wA~xJXmeTnsYo`og_=)B_JMOne# zGnd7p#gD^rjMhyOF#2pskeFw*OuqG~=L;S|p9&i7OR+YgXf3v*?B<#)OA$};1f!R_ zU0jAPw@|9yqyq2!y$6rZgZ-N1WS8*2A=ZhL8R|6Fc6s3f~zxeoT<`xstx+?SbhhNctp6Uy&hwsHC4H>CG9^w{tIR z*P*I>rhoqUBK@`JcJ_yV9ioSZ6n%MxlDAoC_ZF~*N}K-O(iH!0m0f}554KE?eVGn* z+tXEOQFkN@iQEf+8a0pzQ>9(QRDIqCa_XE2(EH*G(43{nlPt~w_I(JKo%f;ad#y_B zdp-C*`18Js@|+Li>>p#BB8lv_@6sVu+g|R5OYQkuJFrSWWxQ6Zs0R1HkAz_GC})Kk zZ$}bkah7HR)=^}%qpgk;5EhifDQXL5(qKlN8s|}L^c(u`if?1{R1cTt*@@JmXb9sA z9AyV8rEofv?DF@ptcAF3h{L7k*0OeRJvzm2Een(VNZBYU0c#oCBRZwPT1M9h6j8u= zQ(+zKAMRZ3dM!ZtZRUFVmyn+uZY6xtdZVNsBzy2yQhv8(ciEttke@N^@7hjcRSZt^>M#eiCyr&I z(q9i-PJW+g2){oBzwrtRWe%d{Gr~VZj}?Y5U%gfsj=#qEwU9MqRbIHW?f9ra*k0w? z+Im#S_Upcdhk=Gd&f2T8x3&&P#87OgH@D-82Y_B3H}~flH+>rjvDf~@eq#?Q`?TRb>y z270el&5ySda?BntN(;Zl@{9;&70rj+G(y4LNMkTB|IhhvSRebk+FB)ww@c=Az2onC z|B(DYgUP=9H;h#qyWYvo|0FVbR5osE#!dC!QT+8q#*e}yOF6gz$R7f;^Ki>yE^9Xg z(nz8s_{K{Oo@e?|DB|-Z9`}!|s?QF08rB6$47iuZ@o-`F0}}{Uz1DYeE#A_@H4so_ z_5MxsDQ2=!&=&D4#LqLyKJ#Wa=EXy$G3}UnhhC;%glyCv*c&<>LA(4$8Gj1T(>rit zvOYJ-9xVBfO3AOaP7#OY#l!cn^yc#DgnLCWOTwQ^@WG}+zlR%rRzUnKgyjBW8D7kjbc1Ejdnyj}n+*9o> z1>!g3|SxS}~eqrhBK+%M34d@}&xI~9wS;kG5a9lgrYwl|@mTm)` z(Fu5tVAPB7ur?V>rXZ2mXZ{MHWxGcMfw9D527P+3*VnPzh;ZJBE{A0X%OAA%QGMAT z;%XwG_4Kftd)ALaR?n-uYo~cy^VjDM#)Dqq4z|YwzR0s%3P8Rf^^-aa6UwAIKBu#lLG~SNi~oM^ETaE_(@=V5Rtj&39x;qhMI1z`&8O z#!)CGTFZ&pc!~;k##`_@+xB-rJ<`XM;2!vz@XuP`Ivk~s2kGmx2FGxVJ~v0;Kegn! zUd5ZEP%3M1KQf@=jkrqkU5Gc$Zjh{ZGRu4tIh#Cj(h8D!MVI+o{_WjH(D*ofXN7BM>SrakVjwQ4=B2juR)1|Ftx0cy%+TA4seC;0O#_7 zGb|Xzu{TD{Je_{EPQTFc+Ma^WuF|k#0>X6qkDc@xNXJ}vWc*OlqCB(PT+i&!xP9yD z{K(n3YOY_HGtU#h8d(N(m!<4rSLd^Xjbq1X!j`Z26`3GA2zjkQ*1C{C0wk3JH=Qe0 zBkgbgN$-uhb~Mg|NJrNGRo+(B2Z{pGT&(O2hr|?G*@*LDt(RsmBE-S2&cj$c?OyEP z+Fb{E=f(X6>%AVz41>&y&#azYHk^Y5Rp26~7ZB9{Uc844)g8YNSR8rrIvrg`-2wew z_U{Z@!XAIPPkQ`&Kw26Nn4Lag^kZ##Nc)07{}?0O&rXGXcahIn)n%+I$z8Oc!-Hkxnh+wx=_9bVfVD$s zL1Py(DklW*Ih-5_7xoSxu*tK1@0if#I0$rw8c?ej?f(S%jqqp0vadRH-Kofnr{Wm7 zY8dc_Uuyd%G#M_20u3#LvK%5>pA>${Vm#Cor+$^zXoN~Fp1U3?!xPRkVRY}$32kx8 zxs~N`EDzm`NB9*|Uh zVRXb19MxC03HqY||0{&>j(P~37AP67&>BD9y%vT-7r@2w7C#Fh%N)+(d70DrjT4Jv z@)5S<+lYA%EM`0Ssc}h?L&~<@BxT`jzCUwB>r97)j@_-3z}H{mTD28rn}GHMbUf4_ zZ!bLW0fRrqA`Hahz!>A!PGc3G76E7C|3ajq)}crE8GneqU%CYl{R$sto8q_dXLp?2 z(;VRVx9~AwJj*2C-v!aqUgyf;Gr1J54~<33zOW|`Rn3wP$F(z`Ws7o>@=^1V(q-lR z8T%V<8N@5(hv;s_$FzJGST?lT8W7Xp`&=qLGCppOu(#~+N^f}rOq~v9+BYAI2?W|1 z-!u4KRoRxtK6}027_#eR?oU>)v(0aYv_d%i2*Jjpue^ z7vd6tm4KK)36k;a`;GebKFZ&ulQc!`2l}HJ+5j3eU%fzT;g8nRqM|B6yf0?Ht>V3Q z`JD&)<7b0q(k>!y;ANxUcF6Kr`M~Hktsd_#80yKEoS2$lH=HuzW>_NtTA(grX2aR$mYP&a`+Dx zVf<@|8lamPF%|oN1YuXUApDR*iheaenuq3<`vIcWSo9C&TUEjSjR;&Et)I^C=wZ=w ziqQL7QB-XC8@lWwmW>{4=UfY)SiP5YG!!4uW9Kt8@>|c-gXbmItMZ&DteIU8wH^*5 zrd91nLAw;3ccIvWu%&u?F>cRfr@Q_8($`N8E}^zjU!R@)8q5O8;)0ie=Lfw z-unyHpH;qX*~r?v40tBl&vcM~n>-Hx9LkR)_QUYE(9#&rE^L2$D|@F6;M zk%j3wZ4ms%Oa~uLSmLwy;@(@S(FIt4!2WTnT#T2;qv83!)JxVI#$9-e^vFHdpZB~q zdOdo==q|+F(V4&Vf+PDbgz`$-f3DA;{wK^z3{^C|KrziKl12w#g7#tGMW@960W{Mv zYbTzkFxTf94LiFIM=O$WR--$X}vsvVzpn;l0z-hbjkIt5GNvFN#dID&w1xjQ)h!W|qtH#oXToiZU4K z+;Qc+%Gm6wrB7CKTQTNoj?7vPScCX3MgTuqEto)q~#>JL0h`CtL(S5SJ81db0G70>j9;+bNEDc?%@ z@D4LkKFgplDB_K{@`Ib)b#td{A0t8?K}}|PM2$$h(~2S=kaK!wO*4~rXduj5yCW7Y zWY*yU{%Y$2E6VKU_H*-LVIbhDD#`!l^wjmp%Y3PN%0mC{J1R*(cASZ}fP}|C5xGNY z(~|VqWUa@#altn9*dnFJ!Xq@lpt{~q)(F#$CEUN@XoP7>BfO8O3}P=`k|K}NsSuzS zs0r9(sPUCz;0`KBBYcOH;?sjxA)lcQrb8P{vnt6Ww!6}p(_M{;GXlskIay<>T`Wl& za|`NCYyi|6Q?5C1G-fqBoLXN>=8FYBKGG*lsUY_@X#JtI`}EL4tuT8~cVbuaAZJHJ z|56S_&z$7qpRV=TG|^-KggAUI(_mFAJ*IIh)pN5$#{x*O=&i|GZ%rdpQ}otssWt!| zy)`*SZ%s?qTP+!AF~VyX^%kvZW@}9|$|?J=xVDsCYHb^}77vUa28qDQuiR3L-uq3I5BsHyaG^pA zHs#cDfsC%5$qCFf%IC5lQumE=NfN!pg@J*3Z6PU4(Q764`*;8dcuP|AWBD{;clmBq zHS;FtM}_U*A}?miA3@x}0N(>{CN+dq>LKLNZ(|6dy?y32Y>bO{OJmq5m3u~5D;iR? z)ru_i%6qK_?v(w1g5n5;g7euK7=t)K%mE6nSk8*J((2GEZl z2$oi1#}P<%Mkyp$+MkX>Dw6Q%=;n~$?8%GO3^N+~y83fEHnm+5!T_g-rgcCAT~Z0V zxB*oK-?vd%y_6s>~OqfAe znN3ciUZXMb50RafWE$ASR-z2Dl}ap-ei|N(P+T*@M=2@-yEQc&krP&XI!z%Mv2pr& z9J`E|)mTuOT*5zbF$xB{2BkYI<4Y(PunR$fW>FlA-u?6ovmLl>U4r~Gn2z7+H_^RMIcDg2MO@SoS>ftqOz^AM?|9!~Cpah2^D>{O3XePH2YPP>?kJydlwZ;b%0$ zwW3<8L& zl8Fq5STrPNXRU|WYyOLtm=O%(=#tXA_VIjAM8^QX*tZX~vV`Y9*5d_d6LYu%)Nwl& zGjSRTx^{QXApzPFaMN~FGxkjH?rIDcM?`1&u^8C#A>tgLQk8R*75L4)o_QZc+x%D# z?}#v8(+mpIwFsJf(GA~*r^;Bhz<2rRy~dKm@PUhVLcYtu8hVqmj9b^@;pvV8%nAFb z7ptS+F+cK*-fwg~Migs3qc<W(Qn{YW@~e-X~F1M zt-T2QUNyqJ!3iM6=H3y;;y>VH&s*mE#^{f&PmH=(%XX8xk5DpAZ#Yx&mOx9yFv2Ga zoei`3?$$);!mp|CpYVOHiFj4(zd!`oD`2xkCc^#uw)&pK_p&B>jc||pzLM`^O~h+h z53BF1`2N*Iyn3}rPNY9d~%s#V|f_&(J{yh?Sv z`kv2ss3zj|sp0CojqgoO^c&$lU<~NHn(sIR&}JHEH(uVW!&^Jn-od2Ba_QKu_@V%dsD~#1aaB1DLIULNylA* zxSZG&FXNunadQyojZGQExL@nID-ky+HYJyFF&%dm;&NkC@#15}V@3_X+%N!?!;+WhlN6 z=l9k49vYi64BvPaV|+lW9~oc9XHJ`?Yf$PeU;OW!FH^iAv6Tfdk3oVc(C{OiXu6*Z!|UK6k|O&1No)1nIe- zNzI+)@2yD5@7PP}`L99#`1{a9Zn=$aJ{iw_GY(R6HFN%s8cfEm0G&U*>&Zpv0(g6T zEi-X1L@pMMpa-zsW%Pm8om2$z8!`SoHw;+gK^Xqe@sL&g8w`=%@c=_Z7|La6Fhie# z+0W%O^a(>ghHQrN7}FFgxEM^ z-AZ$~jhT+3?;WWWy|(uz+25E$WnBKDYcCd|w%ku#EUKRBo&G9suyu%i8rHKR81Qi0 zIiET~rRZIJ8?GR}cY0lX8ST$cF~L@tbOXEjZp#7T=_CHaG2zA)hJ-)Q#rhsJ@ZVr(o?a&(Q`6l|C<@KEj-@Hc67W$jGb`MuqW zoq!1N!P-QB={QKf8&$qoB42AtKJy^?&XIiabI3w=aK$efpYwjgCOl%BJ3iC?Z^DRA z_1cUI8sS?ZY~admom}hV9HZ73t@V;mOOOIc1?yUG zw64f%Wmz4|0oYSJ9VOuopXgaW^GDM>yQ>4$)`VuGL*@z9-dIDQ`SzYrzS#%c{1+&R z`!Yfy%q{FE0>}r8`%n0N5bpW+NHRTQs0l{sL97%E0!~9P8$ocowq~c{7t@gf$i)#f zqA~TURa#crt+2eT+F5B6TAbTMnbo??X8g+JWK1?(F-AuVnuP8DYtWEr|KH+^a`RLE zCdti>GemAys`gjwbMTk5EjoB>BO8Erv~H6-5EXBw!A$48(6QQ3b>E0zJxLm5+)zf& zht1Ehz0k9zf2;1MU}=#N9svsD9|8&O{gg3<6gqf$sU6#}jhKWrssW6SpOOeHv0+>i zN$I$dVTvK^&3RU$-j4jH*ZY=BWL~WIpY+r=ImP}M)xe!E#!}iG5ZdXna|2lBEFsG$ zNSYThOt3Z^=3KNarwB&J4-k3~f-w%ifQ?;Sgr+UAzkw`h?-F>auu5cdpF@Tz1@6&+(n&yKF zRd@R+3}|E$y>r(OMuR(3qMv|bHDNJ2iV$|3UVP*Pj*1aL!EsV~_qj~RcEyCoIZPX; z2+I3{wA>s_y{MprsRaP6?44wsEbyr@Y>A$%e0v1OuqTd1DzXDdmJz-j1RARb$F4mx zc9jQxE;6AgK9&8bmQXGmmm(a0LZJ`L!AC;Q7UK(rrtp-r`{OPWIU6gC1B^fgD3xeR zSwJ4A;*xXPpH7!t`N%b3F84CZ9}vmYz1WcwyLPxx&q>hq*p;3*t}s;bN2*#m@z-b` z(M(O|(Px@RIbRch5Z!Z?v#8FS-V=4c6>VApHC~D?!D}e(%ib0}%uO}CE)1M5h+;}i z{sT2R7r-~227dc3HEI`O^NXI};r!#J#Qw>|uJp%#~|o)OsH)!sT~bW?NaYHah#GvD^%eDn7}ec%#k zwuIzfkHRUr*YG!KWSDb-*x|SjNyU>O0UefC3Mj?8y);kocUy{wM%q|cCFESFX; z9}9+#32tb34Kx4eA~7FUrY$=9sMRo_ZV&Eql-p^4Dl?eCn2O(R%Yg-umI-3TA1 zIEu>P349BNNxfXwsW-sp&b0F6K~ZM|Y;L3=56mGyj4%y?_|fc$%I^Ic%X8QL zsIFPlBwASwR?}X8UOLUJDNVYBlwXk{KXuZL$je4ZUH5~pEGyRPiR6)aIGevZitO=2 zK%p9!(_Loq945_!0pMZqjq{-g*L(%;2VHh-?!shL4 zQ}0WyKhXQITDvi~=^fp@w@$Kuelh#gV{eIY+i1nCrop-Pd${g{;>^C2-2Y-`-+KpW zN7$RrK)ua29EsxB3;asJ#tT4MrVU6q|0?Cx=<>jxB9y~98YYRACrcaoCL%YnUU0@o z{p-ye5X+Tlbk1e#1x9~?U-m29DcZH`%@JAcPcwVgGx(3QE)3(8#JWuPAv}N;7x@2> z2lr6EjtMuem1%@cf}3j^@I#B0%YpWZzxF|c;PtiezwwEqwK>@1$Uo#gi=hx36Z>!} z$#~>r|G`d8R3(6zYQ|7Nej`}g79y^R*gIQK!IhasfVMw+-X}7dMcDNm4I2*(As+j^ zyL}|CgbDhhJkkFSVw6K9E+ONwJ5^J`aa1UwYzOQg-p@*0z3e%3jQ-wxv|ea`R+yz& zj^jIVL-iX4)#09BoMc}!oy@xBpYHg;p&4XJ?cAXm?a1*}tstP~ZlyRwcW2b6-xic( ziSpiH2nB=myMYjh#aYj$KN<`MLYzR;iHxLQ6p=+{f3>mnMRWwX>x&#q`_|y^fCGdC zIb%8#y2L&JQwM7+K-;k!_X<^`fMUQ9$4DbQgz6?7yjPX18dNRm*|mRC8r)VGi#eIe zSKyB@zku;F8Wss`c)#Z_DhFE$@ekq$a(%Q8qG0tXg2w-!KP%`6p+OAR|9I#Nn0$7= zU<%E_l|4@&*<&oOM#|c(Y*^f7_%^jZBchSp=@Dd6$fQ}&cq859GAcN6y0*Xg9?fFXqwxnU@l8QVG4t_Fvac1&uw=d3obz=4 zZb_e-mOf3V{|xEEg7}Hh`DywN1bE>SfU`-NHS$d_fwrGjdXbxsKKmZxiomXtC{OWo z?_#lqd82YN@s}Q3z>TDTN#R@P>I;R>=i*b}fwb?*iEpmSfkvxovU?sVT0K2Eoo5Mr z(VFSjnTS^S{BAm?7k@jC3hLv{qM-f>!=_YCI(Zes?iYNm{%CHr+7E)cDg+Uap}&#e zV5cbGWAKX>_S@|rLQJq98}6Ca$jd`^Iu|OM?4P<+N?fQ)d=Cvdidv8#*bp3jxL*0C@I zj%KmovwnF%PrLUA>lMEuz2aAzWN(I+;NIaitaz`5 z`SZ9yWLy!6kF^~cn=?FC+uyqZ{W*Q9?>Vya0#qbszUYc>M2qHuTz8_Z`G@uz^+UGT zxHqJ|{)G0bj*f`dK*ffR0wczwg+#`%_t?0J<1Xq};jZWHt{EO^Jq2Y3aNV6QlN89@ z19J2y#3s){K0I6Ok_u^1)&6z^x`_qtFde_j@8yBt%UT<%nTO}L=mQgrC$xCcz8rkO z-#T8A1^o7Zktu!=n567Db6YM}&E~)9^sj-GT~3NJP<9R|6GYOkX5WF(IydujvJzhz ztK}H2!+`*l!7zn2TJo6`=KO{dMoJxLlzNYyBZD&CmHi3gc8jeaFbR5#AwRV~mbpBS1E-{uTn_p$HwD zHRdK*DMpxHlIxBhb2C4dZp6nJuH0U`QQ%pq3m+Bu4uBXpJw?DJhzM;S6T?p{{rZ8` z_a(ubeS=z$mskvS3XAmrG56y$H08R9V+bAU8S@+dlr3Y67mm-)LXB~@|G+s2Rbim! zC(W%>gHS-FA^HA@LTc4Hks5T{1mB-1Fanom%z+XTwjk!_k(MW9) zP4e$cduE|U^mv5k`1%w!N7<%SeE^~|=!0WG2};kT555C>luRafoL3N=tPlPFsO{;{4@p zJEW7!NptYUv~w}M%&$+@7pauLr!k~ceiSH=k3(@HcVk2|b+K4b1`53PaCBs~O&fAY zeR2;73JCH6`Xm{-qffdTlk^F9Y08nPG<|{s(I0~c?O!TAVQ=96)5&b!b2duz(mz*< zmd%e=^Ey~e4@e`8z(mvCr5Ui2ze(<-BSD|2aja3zbH-y;Ucw%jWN(wyKp`8DS)_I9ZnHe{t zNr0y=Is#axz>x9swuUAjuWD%WN2dg=Cd3z5O$E^@g;rBxbjnDpX=HRtk=0Zboq|Gx z(J6Q&sW>{N#A>3~g!k^c_7u+loWuGYl2RWj9eNAQ^Ign(LDH^2Bh&d6;SY2siV?X@ zpARR}eP58S+;9iauTDH1JY602Ie2=(7nHBu5C_jc@(c18eL=dqUMM5}ba}5%A8(3N z`$Kg?9+iBij(^eWf;9NTwC|B=->KsxR)JH}A$>k*RM87%I6Nc@S<7$c^3&-{qQ@Oy z3lifi;_{n(&bO>*@7Z`{jSu4k@XPnn_+q!=_}b7!iJkr@>47_=ur(m3Uivs_dr*$*UP%r?aVQV|Rl*-<2+6NuS?ZXT@*SP<^++c5ck72ozx)6&@wg+BK_0hhjM zDfH=dOkW5e^&Fqwnj0PGJ-!B0p+tWdesMPJwoDbMMws5k0FQ_Jeb*Q;f}X@I(Cb`$2t)xy9J{& zTFzPBklm!91~kzfO}o`=^C&Nbrzl~UOeyP}WIr{5W&PzPDeI3wG8vAA5Xx+daqlEw zx#bY9$qilNFmB-^s00N}Qb^Ycs1|4(2U?r4fR!JGp6AZ&;rKfZUI9e#-i>M22$V7% zrA&=h%Tik698X}=5J4J2@D-b-9?<9rG{tcqM|26o|>7mo8L$Y6qtJ{x{7 zjAmAk5#E5D^n|X2+`tv}AU@%}Xu%g4hb!apaR-ruD|ehC2Bm#hF$J0a((MYY7+`pO z6d)lD@+SdN`!_&O0h~4BwYyb(RPb!EA^nJDdD0HJW&lz2wb2d-u70>+6p6GH#4o1Z zQ_c$;=+2ZdCui!kRqN-pqYYcNDdkYIfs-wMs8dPNsL%+pNRZ9|jUNx5O}ITA zBqe`lmSk3@mSza}%upCoD&PbD(hAM&9`j+MJZS3v@6Y$T@AJe^eEnX(KQDIf`@XL0 z`@OzT*Y|q9uA+i&Ee1A!;OMNEQ!bz5C@uNLJ}6!~iWcbt6}g!Ke-3U&0JnS}aN`BX ze1YIt|20O&d+d5EoV3?wyYi4#=o;=WF6go%2tqagH4zZ@A5^}#GEIQ}uRBZ&B`T6k zj!+!S6Yo^bs!m0&X6U!w%2qtWh}L10(t{cQ3JN48%J_EW=?%)0oj=iG7=H%F+!Dpu zQ7xh=6CpfHf+tm*8H?3b_cZmYK{(bgXE0kHJKC@9rjE`>&(z9>95qA$jk?`j`TcZQ4$Dku#H|JR|C#XWR74?5a}!iZk8Y zJbQ`%^P{n4R^{()%Wr*yk@I1(`ab`%uQG8pC$tacRx5%mf90vuMElEg26^_}uk?rK zq#wDD^rJ}Mt!ebIUMjE4fm^x{xWR%;@AH>C+|Vp@*!Hkl)Hd22b^cMKq!X#)r=UqT zmr1be^xCL_r*nhquWysLgU`XLLtG^(`df17xH_QY5KN26)wl2Aszp}g|bA540Vtq|t|l3FuBp&{f0{q-b-b+!pPY|mUj zTGF~}tx3zrN|-~hmZ6^iiPE63WwnoJ|5*CVGwJtQUm3u^&_Db!20!Y<;ScH`e)}n+ zwhCr}UpddP<)Wo5YOkf&qXc-*I6Q;5CS0#T|F22>9{kbq9Z}sczFQ67 z+BGJRk3wJJ5&hyj&+yG~_{@GhjAt1;hXTFC^!>DI6_ytKSNVerT1!H;u0k7|IW znW84WZKm|A*oNe409U?P|8uhBv*V$(eoaXg%Ab5+smx99|4eI3J0Di^1r7dQ=XG-b zo#DGF58or~63XU>_52|ndHjqq_zUvj+kuCPz4*EPb7?&0FIfL;@JHssHz|Mkx&7GO z^!{Vt7e8-4D1K(|&5yMYSB;X0o=_S$y;GNTi?AAmvil7~?X6QyU_-wjgDBkKAqq&W z)Ba@5DErkT1_^;XdMK!Ww}>9<4oIw@VE(qz;5BMOd&2nb8YzDN{s8<2 z?cw`l%khsiW7Qu1RJ7y!G};&duVC=g@8*K%pn+TGt&1O8zb2?{=|ymcm{YG3t|1|= zwnX(3=Sc;Vzd=L&AD=a&#ig-!t+Si>)HF1L8J6~Xp z4~OR|{ujh2IwyE#G50}lP1`Nu;Z)B>4BulK>E)?l*5urwlA} z@-dEukwOMfiZ7Rz5U((e4&sk+@pfpp*fh(=xJD0m#1y*tO2J#l8(`y?G)D$$blXRe zN5t|V?%L-MC?HI5?xJ(TE+@=dmEFGsVl|lix_`-AU{Hbo^AG&4%I|Uasr;_qyZqw+ zPm(botOS!X_eTwT&6O;2wUYMMu(V&u^GEj@{FZxj;oo`{F8c9DWApqA>pu+s>OA-r zz z8Xkb=sMJ{r4;<#5Uo?mLq{7W9>BI`+s5l6!2^?H)@T?1-!-8i+@Ej358-r(4@N5a5 zWA*f#EU#$$x8)%5Dy$Z&P@T89!Fh)NR5*3moWK*F$ajAA7+_W;+eje%0wV$VclD309`x#^K7v#aW1K*#&x#5~L zp1^(w8~l-Z@J-4eE1J3_KmA{ZTlv2`m)?pzdRJuf$)oprgTE^e{wcqIddFUspZ|FV zKO+x*8SwqndyJ(Ym6v{!(r1;=w;oC7lSl9N2Ju^z2Orx9y{|l$#uLc*R)b%=B3E87 z{mapNe`kLB%PjrXdFfXK=|`;1Pd~=eUyzr+UFoy&>U3uxBVt1JIcYhv#{x`IIwKJjQ3mSU%s*n6HTl}{ze$V#3 z<3DBbCtLjLe&XNL+SJZZTm0;P;{R=<7#6Mv1|F}!^?b*A2@qcFV4_o}|z2os| z5xjKC0G3R(9gM^|Z~o7;lw3VMnR^;@=a=yRc=C6XamL*SG3A+@!YaE3@7)5(%mavt z1n2Ow-^Sa@aLEQD+QO5uE=ZP zP?-$!E*CY1*hr#yS4T- zw>@U{*}^Z%gl_zUnb1p!q%JwVEO~`;PCjV#{9g3Y3HiSFPOAO$Pw^pt%cEfEcFaay zR{xDpzQ)d(D@67pmnL$D%iWb~0rYKic-q`bSyA*b=?s zO6VeKOX>j;g#w${X_Xo_B$}uprk~>@vX69Y@j8SLg50#JtI6YxS99ieYVm=Jg#0R& zakfM+U&xn`Um8(1(S(-F^s|R8b1Vjsnw*drb$sfc zY4C*mID|9YN~XPD8a@ltX-qv>dp99W^9E^@i?M7y7OA~SjQUewbWHNm(p{4=*AU;* z489+P`vq!AmcPHN=W5qJ)CPb{2QC^JQ4Sp5#G{IhUENa*Cild-Zg*VBpwt86PKSAz z0z|4nw8k~aCVldC_iP1P9(JU)vT5NA?C$Y|OAh~^{l($`*Z#skb%Ol$4}K?qyZV*A z{r%@G{w#~1-B0|17Jr<@H}n(#s@9rz9%Au(`l)Xov-me}xBUBw|DDA@Y4Nl7j%WWz zot(#AN-!z*Y$`G2Nq4X=4z0Wby{nP=2ltHpPS0Ql`05&)0k+*;nf{#lqh>?-Er;@v zr1oy>2s!3Vlc$ucP<{yy!-39a$?{#JA`#BhkuNGqo-slz_wOMSn*w2~Z;Sf>*AW0< z7rUtyMO7o(col8h!)Y|`aZin6Sj~MGOF|iL`6k0W1A+F~Csdwfr%)skzYI>@?y0oj z62@b|;P@BMx+{QZ@tT&inBo0e zMfWHuqdbJ;X%y)a|M{P4@qK)Ck{!WC$@%jEkbu4}Ce*60U=m2wIznx|^#nNv@J#e* zpH#IW5ff_1ZMYHkzfJ{|^_m*s$x7Gm))*|&1Pib>6Sb|%P1`mcpiFI^N}lMHayx<4 z`3vQ-=UgLdi9D!cwe>Tce=~ib^Ld%jv|G)DK8n7ZK1AOV$NuVjEfcH%7y7>Ss1Mfn z^elbLC_h-=ul(eHr|;Sy?4Q1uebMPGTi?B(aQbfH;ExZ|cf)xfqVEf9rSEySpzoaV z)#S8tHsf*9cjDzp{8YAdXtY)0xtQVBUCpJO8?=lNB5sjl)&8Nn)9}7a$}2}1G_qsI zZ8r&bK2dKZ8yi(Fe&xVJyeCokDWlA@hWK>^)(7L?6prq);i^}yQ!BUX>n}&P$c5z# ze^WM#jmo5>Q(F)ghpQ=UeL8eP{CfWw=Ggk7*X=73&00O1OXNaAG<<5;$q&zDCI1`mFPKNL&jS1$NxMf9S()8^#fG| zuK`6h{`;^)6HQaBSK$6@@%dkZ0`X3~fxJ-$&B?TMZi%6C=AJQ^Z#be^H%pGonZ=JO|jFoIj%y=rYIEGfJ2pwUv zVl@um4IT}CcvEpOmv4)hmQs6FA%#Z8O5IL!5r4&XlK9+e0vZg9i}xq62$=f9t$>0* z7Qg(_d2)BZkooK1)QG@`ZqAh76|v=xFDptSwLE!di;C_cXnEJ@(xUk1LaDR70vY8? zeoJU>DpK^bnqprlbjEQhdjTm{EGZfQu5ifxALa<7?QfHB$E$7AC;|Cq;rC&pOiMAL z&?X$O#xI>eC-#Mcwi$sKKCD2vwS%P;h-~6qJ>6U$xQV3hD@}VK`6TPVMf%QY@z(WR z9(E4{kK|iLJb9^!MEfW9B6Q&*4(Wj zJzmu5b0Ka(?^>6p$J(x!vLwd_sB0qennF4(ho`bL9;tUphd?t4VFmT4yTN(^;VEq=Yf z7m=B|~)=T_f(g18c%)mL{vM}mOQdmk%7T`v`Ii>k zlEMQat->uS#80^7KR;yehFDA4 zE$dC^_xarXEd5^wiM;qG*3z?n@=qro7Vq*Zm@f>FGhl*hB8BroeTPf>E3L;z_uKkO zvX~@2S7h4jXZg2&TH;!JqqE;o&1g}TpHTBC@Z0Z4rE7I_L0rd?R4YQ#Q$Di?nnaj$ znY{EY|2)GtV{d#ipESN<{ooV3!dH`nZ?NGzGQ`KYn9);Oq+WR@W-DQNbfNm+S#j5Iu()A~J&nlY9n@SW99kmTt4WF%IyR&X@j@}%c)`4~b0-zUHq;0cfL zpxg-0i8**K5AgJ?lzWF<@uIe}nq`hrUL*b|t`b|(_EzUY)mb^n_tf@{A7IU@X@47BCJBFApSvv|?} z1%=o}8#4oWxbvh>Bb@m3y8e8dT74Lc1b;+MxJ}j+3$gxnk0B^flazkMM%PGQEY-5e zvd|8IoI4fDMe zRq9|?*TG5|ron5k1cB@hy~CP2tYeS1e_CQCcM~6IB8?>CFa{wY=?V9;wuJXEMwQ{w z3L_JRY0N?C4koPoIhy~B0lo5XlxKdx{LQK=xzH!BGk?SJEqxqx(xfuC!isV7cEkb_ z3d5(**g$;Ue+}|;f63>o+3IKR7=Uw|76<)&o$8seU+o~PHKLFbr?4s zt4uezS1B$`e8Xaw_$`;%sB`CQAcPXN9e~w2X8w#I? z?+@YQc0SC|qRl$CM)?%(ft1Enb0LqW0WOT!mQ-^Q0P_LJ1ddHL4SR@kf$8lkeS~{ zHB#G~(P_nO7oHq_-5Cz&P8Y{dCbYRcv8Tv_w^_1z&E@gWD!e+eXMlzG2I1B5LljoVPkYqL@!+$8cgcFwR&M`96r#2)TU9a+A?0@`db3_FEaG zj7O1=WJj|1${=M#iu_G>jB5D0xtF9P#>S=^l&pz}@#zR| zr7(!)F5)Zch_SJ_LCBndI656Mjzv&K+*MsW_h5uli&PuJxVj=va;cW^t50mV!X0hz z2A%+0`XsaZYSPTA!=tN?omC^g&^rzBf~2^$BKKZR+olSU2jdn7AY`Q2hG3Obb_&ag zxJQVyZmfe2T1NDHGnxIufg7qHD|t@Rpj=?<{+@SVWf-S>3mf>td$Z;RbD-Y|=Rglt zjYYdE5!3;Nx0`Podb{)U9dB#*UncLPvhw~o?=~ymeH_h(Am92|Q-2)Sva_#y0)Tr> zhI+6WORb1)MzqnD1)S36+#UzDan4Eiw=#HG|9Ge>&#Qmr`Un2M|7ucK9p9+(fI!{i zerBQhZsNO)I9;h>y(ZpmWQAv)hhV?A2O1}->tXFQ^`|Q>hdP(TCK8SX3C;F+&}?6Q zjy2oayfPO>GKg3pL`Txcuyn3%PzEdMdZsJr#W6tSzr$u*Iu4qLXmrF z{j=N@_97oJo~8%cLq;PGt2{uPgPswR3Sl_?*9O_4`F$z6?_E1QqR#f=IsQ_K;q+YG zzOZ0Mtz?d)G%{1qteLgOGIqeM3Pvll;C}1UmxL#&V0T5`rA!kTc$tKi}&hT?>Kv%HeZ7+VN z9{^oyZmAtjj+#Yv@O-6@cFE`F1VQ~CD62tce_FYbT0 zz?mHx5a)G9+tBT=InN<=#m#mZ)nxM*$zsLO7Vi9r~*+5qT#j1|IfEjuLeRp zby^wM?nvFvDH5-4Mpz_G;(SNI67;SrNK);uzR6Hjck4vtaQN2Qt=%WoMS3fdB?;by zAxo&D)?Zl?3by;EjQwsQbw(+&dL{0jEL#;_Jvs5AT)WvRZk@S5rK17Ey*(Qo8uUN+ zv*2J?Fg~pD?{ZoD5sS^?YW#bIe9Na{JF#a_+e!L38h2!3b$y`lv|kn7(AnD7mXn^c z)z>x_zT#-|H~oIx2sz!2sFZxyg+{cQIoliERU95S@_cZs zev%~Na=0Kb2em1(b7&<8ssfh4W%hN8yOsm?kGpMK(%hxx2fmjupK8i#RdN*D9OH*3 zTZY-ecLOOPeVa+3@oO86)iD#n_%{iw*t-tcr;=wj@Hh;E?Av0g#eSIH_A&JMADmy^ zzVm~&NOExE?Rfk^)(O6S9YsGrK;!9}$QxDF@#yRwdiBPLHuCM4pQe4|57Ni5gzDtr z;U#VV!ALz@eh*K6bu5oc3W&yv({gZ=96OdezP58;FBo(waty<(P8JUz)HZ_Mxrpb> z$=0#RCET~9r73d{v5mXBF8T0a63*scDs&)%vp0voC&2#?@N@pdfij>*&kSf=>b|zX zPL^OFLW7Oe@amUyO{V7Qr>eAVQ#d7BJfKO)6FCzDd zoix!K?QAVUPg^*EIcvWM=f9ST`%#OG`wiGbBX*jcPa{s_pBJM277SG`k=G`k%x4iX z1lHVjuWWU2^(k8lS#1$YZ)L#YMm>X8h1L+#!uDV0bX_RZ={gPWcpvdxE%-zTAJpcN zYEY!TZ zbc9B%eVWxCy_4-=*!Plb`?mS7QpsmON<3d^RU6O4syLb^K7zFwEoNPF%XH>Wao1?q6#F1M zT@cu5Xq8oD+R@kc*#2APC;Hx#RW5f{DZ7Qxf{?nhb46YEH`G>@z9iq(gCyTgm#5|1 zgv~a>!GB1{xBdnS*2F*0$`@M;5b+oN!$Kw`o2{33=`HW|d9&Q{Tw&p}`elBO|5Ecx z)ZC|Mp8uW9g|y;01ZN!*Iah;Ne0Svdv9L5|QZ&S5>pO$m4oo)cG-Ig+vyweNokO?WwDP_*kM65E z36^sBNZ7$j_Yb~m8J_Pld z)3gqa|MoskUY*2xAP`bF&J4>3{1+Mjb2I!W8scry4A-jcjqlzZz8ARA$ZS2c>YMA| z$+i#Fb*^P_iOV3(Zz6}^f4*r+swZ5fi>l0`3d+XbI{9a@kEN~g@gWsLYjlBN(tuX|R z4nc2HXC>eb*WSu;->lQ2R{i*zquSwi;B^?O`pTgV9d3;Xuge{XcFAu7mG3c?udx0t z=U)~W|8p|@%ie`b_FmPGy&sb!hxvgVX65Pqrak+x_j4`7OI(I&dF0yrx?k@@|JcvR z4ZhyNKM$`ujZKX>bD$@lX^p{;CF_W>knUfYLSj~S>UZ`0E4zJ0qMY-7vH!kTRsMfy z^6(`}Hw=0?21)0=+?*_2eS~=9(V(VW_b`$Tq>kAVr39C5GOlB9Yuk1F?LSXqLSr6jJl;4s{W4R*BZ#s!$sIa=uMIqF-+_9v z9j{s&hG~%p5DSM9`$<*J`_bxq_Qrfx))SKHfiP|k!l2!E+g^!(l1XfBJqA(NpDv?| zwyQ^=E(kplIv|`LMn~kZ%q|U8X+%$u0JMgb2`h~+1gA(`YDfe&kV$a z1j}~-p7B5GImrL08pt+^V|LQ~!awZ5-wR`K;$pCFU3m7dH}m3K@AdVpRQgwQ@(ugF z`T5?Z^jDbvW-)=Y;Nh!g=jpGGQ$FO8|F`<9{CU3q1`)Ck{q_7TKk@$%5*lr=R%Fm= zAE>`}1R(YPFZHKk$G!EpCQpCgebedhSUmdwMt?_w$LUY^mSpk`^_QRT4h$yH->P?{ zzb9ro{rR(XHb$3!$&cO&)OWm!A6*_!YEhS`mBSBeljmsQnguFq9~MMU@og|b2dBl; zg8}NXb~U@f0Jr(z)Em%Fb46EkdNANbLb{r5Fkr#F$Xu!+)`NgC=>V$s0vMbDP;n51 z<~5ERYxTgl7!<1Yn#=IvrsrT<%|ay84ax*k`4>U_9LkmC#lMY8qxdH{4gE@}@-=8GVK2 zyb~d0m-A8J>$%g~e{V}&)orFOYaie;tDQ&x0*9-?MUA`?qNoY_&|kvPbmIkMDy%Z03JQUrCz2A!+)q>6gAG2lYqahTWoX+Yk0ZU+e#tzA4`b<#+MR zq5N*_m%i7^^XWsHHa_ph=7%O5CqRwvy-2SPkcAB!jXK;9KHxF$d`W*b$)7j0Xr{2+X zOg=q>v*}^nyA&|4f1#QW<^|I80ajl$?~($(HN*LvB=`10Sp$@{dbBDo<;;A&Lt!|T zRR(@*ROo3YO}c}wQuV^MMdMFpOd=nRz&Y6nAHMy3rKC4 z8wpGn-k>o*mCp2EU!@Vdg`CSqD5t4(CEd)SKj3w~HGb~4S}GrhTDcwOPLJ@qfGqi} zgJgZrE2>7kwH#takRa-JNo#5_I1eOGBo8D{6!EM7Y4dWFkLZ$1@iz)2(u5LUl8$TF z;0@suRj8FA$W=<^+9Wjk-h4wJr?m=GPt=U2w_aU7f{SQU(Ei5B}5_GmmaPa=d zS8&;oY_o++X>WR*4YlCmUraacsXg9+2Gu4PC&QeZjrf0@Yuc$%Mk0u3juw@b!sQs7 zAr#4K8qVzFGnT_wTn_E5s9Hus)@Ci`!JwM*@Xx{{?+dr-j5Iec77eUJRK4Xk6*Awj zMC1C&%>KKB_yl8$aasZT_dtzQ&>c{B&wm>ypH{BF*e1xRbmj50UVhpBhz?zXr)Q zr-9+zZE@fG2S%{W7P(=Ik-O%8hsCkOSJ;ZKd4HhdsO|Z@h65(W=GaJY&~DVX6)LN$ zIHx#scCf21B8_D3KX4TbOV=6 zakl-e;*JHfPutJG-cSyG-zSG)|7m)EUISDYbm=ElmLa0AB0-+^3uUSntCqi}Fm0MT zjb_?`X0_*>;%4faTve8kP^= z5)T(Qp6E~mz7BYoOO z51Rk@*XySL?`7+MxsuE0plY6S?ZOsMiR*+#H8z1avt zeUAq+)c2pi9_l+D9tHUz(iUfFzdZ%aCbH{f1{+Pva~Fr=Bj__f-+!I{X}HtrSDj9E zIbf($Fy105$a80@^=&d_2W%w(=-l}+e-rjT%;Wm4V@%ECv)$r!qTP@-l&zmfAf}X^@!Xw#Q z$6K$x4dd-CduvEGj^JaD(zy*msbKSfTLvF(KXwpNx0|!?IW$XZnO7upgOJTGORQ;3 zwya4`e)*$QT!!3ar>C zTXPH??3bMVEP;{)@UxS%pXW=`;A>8D_BOt@>FfU3d>+Z!FA*TY5YTP`J^_*s0gEi) zm1N7FWb0d)ZY@zJpxZ4i)S5Knu}a94lz>@mFuh!>c%1?QhFjhR)Fj#zn?hScm_gX& zJ&pZWf#_X%nX4qW4bEER{-I&ViZ9-B?_VT4R)<-sI!yG3|dgT!8i`Fd4z z$gNi<@g(#*G2()20GdNe`Ta)E_a5`!PR@x{rG^dfTwi=#oSK`z!uLDZml9lAzZ39U z2y7{Qt#kc>^^X%f)_a4%s>1HhM~Bout_D7VRfSJAT@T2#>_ntT^d>kD0y%|E*;#rVdt_3> z3dz~)t@lY=ZE3xA^-t3ljL}w^%AJ}|d%lBgC|ujQw)D7hY!j$0>Rfl=al|6A8ps(} z_;lxELjbBGQ1xHTk`(h*$yX)O>q_e%<8_$VO|r_u?H)mP?Na?Zf*U;F@`k`F2&qDh zwW-?T&UMB0+r7=H+7rlV1b{Wdvz?Dd@9DzFyzb7<1M55Cxz^iIxQS)Nj}GxRBD1me z?~tY%fTmRKVa5Qww18d105z!*b)8+M_3x$T43ss*kX!v$47bU92g%hHZtvVUq<%+X z7c#GZJ2gTpv0DYOCpD}DX`#nDlv3yICdm^+P)jT^6<-8~ShRz6sC|>87i%BV6Fjx{ zubU?Z#qXp1O^8)Zj$W{yzrXYKGJo+{Ht^O(sIX3rP34U*;-(Y#2ygBPWP)GgV^VC&k%L-SXosR^^ z;}lA3y@CSp_dC4^@&T>9gWuCmi&iHQ&0(CVH?gfSdi(o@yKlA{1fQ^mG=;rX8Uung zmpUfk5dw9um-Cdm+sjoGy5GxH6T0KeRTH}B%T*J)>&sOWy6?+X6T0)uRTH}R%T*J) z`^!}e-2cU!$n;w4cr%CBI*d2-f~^f~4j5m^r+it0foFA^?&O^=)Cz-AL79Nfj<0{G zzPEHO>vviH9?B!tZtNir|DTBi)VR^el(p$|`|k^1R_%M^1y=jstlF0?A0#E`c0Cry zZr~xWLBt}xZl%nLpT#b`mGGr{<*FS*m+6%|PQ6Zbf%M^ITDlqUy#~Ug%ho3P+#>$y z!Xrq)Hkj(d=)%KzErE+)iAQ#kP`<}`n@TsZeM})*p{JF45RzE0$+Mco*1k_`#EagE zVrU9DHP)~Bw7OvT+jg?j-EHSWPMNof_6e<*U0qugp3L zo?7eI)Nkp0A+oEpI{M?a(Pe9%eDTR`!;$EW>RE$y6Y>n5EM0yN8M-42XEN^6{SOqQ z{TOQqM#wT!kQaAuEB3Z3CtLc|8olEgYKq?I9ZwW)-aU!I2De9{v5>`eNV%zCrga^( zYRsC1LBD1JD?|{@yjd?wx}b|8?N($uF0rP_iOtPcZn0K3N#z68Gu0Hx1pjUf3=SsD zILtU0KXZsUcv`vKWpp!F0_U>T*67Wfi#uN|j^44sd&UUg6uo18;ReIiYcy~6)(&82 z!tPBdbi?jVh@@%8p&-V4&OA_v)%@r_SC&dOSL$@#%V{0LN@sN3@;eXvJqE?A3($+HF%Rp{<=S7Y|r$c}MT)_0}R}T202l)81~X zOH@jAyvzB0_}z@hT^)e>8CGg!p!&p9uL}{p0mr_f|0cwbUu)(Vwp!-sL?J{n?tt zzoMmU7cGnZl4x&Fr(YyKc0ZfgHUJ|i5HjPsbUg;pt~BctYjl&7^ouSXPl&e&@+uS- zFcj>;Tw!~kh-)M+D3>^VVFFqr>evM~O`b;E%gP8{VceufH?nz5LKdkjOvurnuPIp@ zKa3JzOMy6zkzrnIqS1vX^9s*WeElwzEVT7~Js-<-DRSPTD+?2y5$_bXO`Y*x=Zht! zYrU`WKJxv}ZRMq#TzFsSi1HK2uf@i0FBwWTHq%}o>{NF1?=ZF) z3Vq4w_7p$EUiI` zY$KVe=r-y3Nj7oPwpjD7_YUTa9T#|{46-<$T3Y`zsmVqL(Ya0AZ8s>u zd63VlOR~)B_fOJXr{t=R$7$AezEI?Cqz$~-x>1GeplBIUK^LuXGZ=-quoFx|NWxq6 zc$!Tm?+JLZ>$8IO09DJ2tp(-1QQwJR>PjC2(MzO9V8alY75jCGorR@O6Y-P~@ioA{ zo>j8j&3^>zaa~^=&{)!H1`>$jGV}uSYD7@t|77j~1<^aGDj-~jm#Qe_O?J&H&;P;^ z$aYg@4XLJvax7WAVZXy^cJRii*w5FL?rCqgVwW~)b|jfe4~{O}BMoEStj;RWF#1GiH+d{5i!d#~?Hn^7-xN4)L+6y~{Uc{LW&NwYu zMJ?~?S-z;{{m$)`!@Cx>_O(5SC5}%x2UVDGtwE6>FIBk0N-&SN_@edkh=jLr9V>^} zPfk7PU-qkXB_v0Uf|u*T34Ef()kDuq&h$MoXql#h)AbNtI6kxMqU#>Aq1rD!p&fe(?5m|Ae_8Ir}0S zK}YT39X)7i=*M{{_3cEd_I(rt$)eO{5fIC>i;iJD3XU6uQzD^E8I_%!92H4jR-#nc zP$t!A+?;ZkjWaOFcAApZWtvK= zKsB(5ufh$O!~MJr2v}nfp?(cYotRi#nAogc-;qJ+5K{9gKam8NK zp)%__6?lpTE{djGZS?ZjS+X!|uzX_lihuBqi%M1uI_{i^H_lvh08j(~wA9Yv@R<8a zcA@|hcWJ#tS%=GH$Z>4yZ#uA``v!%ooke*9admXzMohE&K7wuDiY6UlyXdtzf6^Ue za-DXx#4c1EA|7bbPTgAyzcO@r+eWNidPX26Jfc5atFT_H`J(NYkwaJtgF(b)?r;g` z;Sl`WT%K6pI5|3v-uAR-`95vizfjH+lab z-s$e1{|xVM@b_=R-z+@aUvSgD!XG`@=SVkWOUdNug}Vu$BR^wn z3DT#lN|i#0LIF7+kcj>Peq=;dfPXI$27j5T#Gw*-q{VCpGa0xGZkth9l zQLMPiw>r^(SN5A!}D)`)5H0s~Xf(8K`k6wpn4k>d1K z_{cyIa73cBQQ_P88QDuWP))Ds!oO2!qL+7IirAPs&C!K_CJ4Lip6=`uJ6w$&QjA?6 zlM-jmROk08#WJf{Vd}QP!s3OP7`mR8bVf4m6zF{J&m@{!Sk2pd-o_Qe*d@=P-AkV0 z=R#PsWEV2TGp$YO5!-Vp^AcInB~L3&FHzqh>Ox8LYf6Ixo zl@=`;&~u1)8e>JzVc{1d#7j0Qnate}VG#3$JxG)Br-_Uj$!O+rZUiARy2p6F4zp{B zMH%yG!4Qg3&6}!ms3|g&SBN7mMm`aRf_NI)&)7*$=R^EN5cj~+H0W34McWiv&dakw z1S4t}ZE}$_-U8~P4W!sXik^QcDOS~k#q==BHElCmtSwSBq0?yj6D|{&WMn-??6@KT z&j-Ua!e_hzx@nFsa_B*7(;ine%}rh>h=mz%C?~}r9|6vILpfql)9?@T#uimO@}?om z89Try@}@yqh)oO`$wDMy3wB1YkaU8esi+RGb>jWjvx#2bCBs|z7<+b{Q<^OrcgJ=h&)xrRq{;q%;k*IlWK(6#BiuhV|wbOmc`4)LJrS+@K^jQg=`s?smf zU9s;BJXl_R0dt%CVo{`%6bPm03VPd5smq9V1P zzJ`5uT+vX~2~ZoX6A;DGc6GNBbIVJj9c#&lQ^AW^Iy1V&qm?mqoi%5^tQB#8CGx~m z3T92=lmLe5)Ef!cjLTQ zuNEFgNBX*p_*t4Y|G!1rIRCW%?WNAyi@P=gdnqTgk7zGr`latGLbL5<$D{q(3+F#> z7I|w=HS%mf3x+&9Sq>31l4pv%?K$g_c`cBT&F88NN1 zbHv&4#2mUp`D<-ZHeKh5E+p316Yc|=kOLRWJ0I@IG(X8K`=@;V&n7YS#@PPlt-aio z&taxzA5q?#iO<+oNS}5WXY+OWhW_Mj^YzCYg{M0TKeT*8ak_j~_ftN-&V7_m zx58}y%cnY=8NR~uxipWjTk*m4B(utAE?ihX^WkPVxUBNIASb`jKJwvC0Pcg!=YQqk z3H6bWXUF+>HFRjjA#)kHyQIU^mFY??OxrX#5^W=JFNMFxh{=C>I zJls+Eq4omB&R!PGEf=-X4lQNRap`A2WF~WhT)NhA$)$fsF1>aCT)HdYzs}(+w3mzW z__}PJ*-NmiOZ7l5Txc)(aHAYtu$x|R${{1i&|dQ41_S5pVgzoZxmd?&;V?B7{{#2onu<0Y-wLt8`D=}n)PS@V zd}o)Zt}LL4EO?<0_Tyy>-YI~GXvY}`)>sX>Pj=V#G0;SU*63#~DB8{izS`79gT(hArAa@?W7m0*8&NsA zwLim~#OF+|A?U7_lE2j>1l)+!JRVAgP&^eM| zKbQQ{OG2<$d)@3bYv1IIHKBdX2ZP|=%Ypk2UxY^T;Z6`75PjV(0bEZGTxi$%a7Agj z;Plw?!7!eoGdz|cA8zAAVSdk|PSL3jRR+%NsvkP9PQxt+F7%hy-f8ZVfqm=b{{7L% zrAh0LMD^y3OcM>Nzs!>45OeCUYY_;o)MHeCZ6s3l*Vj~kO-y%3)ZIdvt_$MotIy={ zANn7YLzbR4KA7)+a^Xx~@ShKNwS&v@Ke3$rLOtcfod?_p*H_g!ctZb^kLO_F*~|a1 z|8<>&|Kdm!zK_4IQJHyb=$jaHH4XP_Z!o_xZ;TfD_O)u49(zDT{ox)wL+}fSV6Xme zrSo6zI0V|$D&ZfozN<9*IxMfh`(r}0+tbHB5b(E`|MDLZhXsznO<{Le{!0rLoN3*x zw^oRawo7nyb&J}*F7tU<5ycqO7d476-=to82~x0ARgxbgxYn!SzFxY)NUyewNdt2j z7Vn?9ibe+T(e{Ke9hN+^vgdARZ=YAXM95dD|7C<`^L5_+f&Mu-$nC=(ngbW=J0I>y z!I{2W@e9s^Mh6~Zcn*e<$`R)BF>Jdp$hmt6aIW8szJKzt#QBG>^j}|9JAJ!*7tuEb z^rPzA^;bi=g#2j*OSW7_i8}GOm%jI`6@lfBz#M(A1c%f2?Rsm4ST0%T6@5qAzRg~W zb4=I6vvpk->e|NP)B3*p;ePe~pLaWb#}AaQt9$Ntax?k&+->K8OeDj-^?o&>+5BB_ zZz%maf!18VH(xIKaK{MF^sYVEOi`3zl@XRy+5RKFCmVHG*ovdckoyicc3S!Wa=QF$ ze1?5(l@Geh3xKHh@Ca*BCFI zbG?!yW0pVmbFO80iOcZMpl`zXYDJ8s&bLMp{9g{nZrFMd|Bk*o7{sI4H4)oF>aszk z<{2I!T|xL*nJ^q{Yaxir{TB`phPmZ@r&LCX_E~adTMvH)0$_B&$}o1>=zO=HH>F?p zzps%zwu~@&JPUtyOk`31zmYsRd1f5zR+}Om$XM#mfGf6`wwEEHToY9p?S|HSuL#bn zMcP+~*1OWi4F&m!9LTU9&4(NVBqNS83jD!Y{$Qi`$o}b_y-#|Har8c!lWR!tgL(8m zwQ6sAH{?Ku^yWie4`epI=RG9(&N#7O`OeuVy~H?rx98*<(yRH+Z289eq4)1OkRiSK zklR;g(~FTr%*G2)f5B&q^6#hkuz2qOc~JabenPr@Rbx!mG*=4apO6XnimGdBsok(E z&7k}K3PP-;>AsX>41Sd0Z;q*n$LRDL!Dz9_IBILmIGI>{yo{aG_A~{r`n$TA?@JrW zp-e6~l^DOy%5!-tv6|+#N&}^$Mid-OykPG9z0S{zbAT8*X?BKcUg;cmrTFGh4me21 zsk~5bwm1*x)}v6qFMU7^|7f@|{Cw(YtA{CcBTRhXTY5%0Vtu6K#1tDl}pKZ#5Y1%9rqKqW#y<^E`VDgNJ zSN_e1gXl;MSu#KQXYkXot>ckft<|oJxeM?hiLQ@t1%X zUob_!E3ALU+$a7nINtd4)BGKrx@NY^(Kwt$uC7c3fNA**Huxh$c-2-pHhX=QN`gDF zs!}Ib<(wZx{dceOfALE$|J5oC$!n}QZHXV?(Xjg}Str&U>~dH8#{mA|0A4{%oFRYE z%rB*ZMgWwW{+fRfaKqRC;B$deuzZQ{la7(}xg+gX96_!S?ja4&(aOvZ47L15hWRn! z&wSFUYR1GlqNiNOt!C+_pacBQy|@V1@qOK1E!&sA&anb${d;LWxoR@vUq&GdvZokX ze{9t~63G)^G?BRTN8;>BrZs#Z;K?tj>8$1$DEyzEr^C;p?f2qT5)*qi$0d*Z0$WP8H*XudFdK`#w(~m`{w?5kOwIF0U zQ_6uk`Z@814b-_3__d@<&PfDl!&gqKfmbcvlD;R1^-uuSJwHkSuSk#xC3GVNeM4d=jnALr|? znR}}3G7tOd)HiR)A4wQmE0vLQs4bIrmbN}|ht(1Hxmv0#l(T;m3tYhVOJULpAsBB? zJ(GpUf9Ch*x8mp|Z~YtPrGD30e#c5l_-Drk5@zZgDK~NHOZ-w5o4L|0!%G*RiBlC?t zhJq2EjKsMclz`<|TM6iDYq#>STh`xmMOq?Q-V)Xp^>l^uRXNyOzWFA1@9!uL*T9MF zAO0lI{j`4|yU&)LBZiX!rFBr|iePAWBOw8V*+tO*s=y8hOmyOpOYfHKkEl1<{~0gQ zn2g8lrsUl~CyOMsSM}C1Ne6_#$ZO*LzIe&-x@d=nfWz~N;-96Ijl;L#bjo;b<*B~Y zSe}u-&51ql$InHkuD_5Rh2xF3KPF^zXqLqv?x1VZ_JFu=&#_DERm$x@P*K0FKrhc~mZXR4%KaU0$%EImo@UDOV4M~M&l?kmpos9E0t> z+%`E0Om^7I8XeFLw4q&MoPpd)vp{FkAN+ zO{SCSj<6c0QDwDJ`dYQUvE)9ahe2~GvsEcV;~(~0!gN@MjVWihm(TLYSne0N+%>;G z0^ix9TsLvX1@GEtE;%)Xa^&ecx=wC7!Ck!83FZ~N8u{pS#Npd_rViwUKo-H5t%*8kCD_&dc$iH!4@l7tiWnb}QU3}}l;>Wr8@%xIO;NmClD}IuT zpOP1!mjBc|`A^ULcHK0P1okmIFMdw$_tN>;CFj~nKWvDk6nN#d_uaSLU-ox-`dj^3 z^<@R2{_McyB^6x>8rx@)%%w|7N)P+zx1_XdV2BuL(i}~sftU2Bq-|pC`#A?1A>ZMjcE;N)k3gsX7xVV>6_icE#yDxQdV^3B8oV!r&@mU|S z{thJ1JCvhBN53lqhQHSKQqr;&FNd8+gncQFtgFKQuH|2B`5*3BO0VZgydRx4JC!K; zA2*JlO56`=!d3}3HC~?uSJIf#m*z=bj@Z}5O4kVM9euM8OWh`>!UL2}fXLxpbH2&$ zw={jDNeNY9cY}IX^)o>9AEX~iSq%f8kxTT9#G*V@+54AqJguFI=DK)+IZGsAj(&yc zjW0=Ea~&eJO>pcfPhGQ`FE)~=uDQit%DTTtYczmY{v&eoAGweG-{BZn#-!AXhi;SS zs#|0tPsGebo}zu<$i}}jt+lbYG&hcS(%epb@*0_jCY7GoS7wEPD+$^7|9vK}h~2v-A^0b-9LaUEXA7s=$AkE7Q9oOq6MEL_tBh8iF-~1- zFiXy`OX`jS4^6HwGYO7STo^Xv5DYucOwVj}B^sT;UGm=$l~L|RkZa1-xycN&SaXBq zYNwUk=sC2H45T|rPp4gfIS0iG?L&yxOh8iuYNi*{|LysCdfsFI?Bqtg$f157m?H_~_%v6}QtJB)N^KO`@bP5Vnfr<1uyjm{Ms zSTKA3qsWKvo^@{icK___dN8?u(#eRy?CYFg%f6-^Y4(*q-`9=FX!(F>e-gfi``-Gw zWj)`YA{yh3c3r(u2aL<`}JXzZ8PdxH^wP za~e4kFy5Nv=+Ys-2?EUf=A`p~SdQ6fKD$FbcjY`wIj4(xe>tm|U-L5?hPf-Ry`uhH z%daGkiAR_?)Ss)SKNqtB&Kj|~fh>o2{a2Nl=pcnWLkMJ9UoL3=^5t&k$gK}e-v7E; z8T3_K2FqCKKOeCq-lI?-#d3uHT;$Giu24S)Z<#`^4SShFeI;KIle$md(LV$TW@Z*i z;QWy=a)(GgK=Nve#gN#N3xP}1*R zH77ETzU4tyf4V)H1eB9ZYo$uS*>^@sVqGDZZ^qhIaD}v6h8{m0y_f8S^q@4^jBCXI z0&{Ai$xO8(s(FVJjku(XoqGLpTrut6h32mVO4tE4A3l;L8kCY{QC~+FM)qNlli)$M^fKZz26=_P(zVR4z#y%< z_Afs}0(6HSUU48s*cF(kJI?(F1P$L4J#7z)u4asK$&oTnMi~-)rE(Lp+2~bw3#HEu zmpi@nJ%{wukjb*okzllyLXmr%eO9OK6D54w$l6*Z7hjYw6BK5q@pd-0y4{LVt z7DngAG4lhWYZ&bfcgR&>;egaIt|=r8AFcoi)j*8UVabZS=qc4Rt;hE0W7w@qUx`ZiNCS_v2?T=-c9YJl_%2*Bj4+kR>`&9RVayAs)Fwwi%f%M~7n zm~suDjcqKNf}+~to8#RwUL6|k9JI#~voznyr`mt_S~SQD-YhWQOntL|_IAQ`xyGM{ zFF8~>rrXDM`c-vM>i$W#T?RDlSo(*J!AnmJYH zC|Rg3!#q`lYL~SY73R35Bdp1M_1DV6is2Ud>iB=8wJ$eXqUuM`YJ#;hEFI+L{J|j+ zsL!sy(iZ9V&7~dld8bnMhE`RRq#$vp#B$-+g5FGw(b<&t^FJU%=jZ>Bwm0XVOF_ul zBlBT=@A@xen0Jje0+mb!HEhQIiH-%PohI)-k}*u%?53LlBpS^Z zsN6&#&~wW02Z)lh%5*cp90$8 z6&c#@(@-gRQ}c=vuNI|d7ESh=-|u)duOJ4K`5`}6b;WwMPr0_%kfd$|m7n)-IsO3a_O#aYN-dh`Py0LYebw-tpTQRc z(0_OtwW2QLGwgTk3v`&V|LDBeLNt?Y{-VSXR67JVf8lNdIlvTRQw~f0Uw)=n^mWCz zgR?;s6qHzAHG2^8e+5pe!GpZHl}_aA1Abk?Dt{T^q^@GIrK@1l>o2Zk&Sk;FHyvu? z(ENo4hB-%S5DRMJ(-V7&0pBL#yc!l<98HU4HthGy?$q2nJ9xbO~ zs?kp^YAVrnVDfw;D?Ft0%`(i6~^LIz%?eBVNA}}tjt&s za(>-x>hVuv$tCkoqmTewX&;bjdPVW0q_&isQeqn17mPsuYTS0t;M&z}UHY10HE4da^mdPMr0#oj zrsm4x$61iZ$x`?2wxG6f4!T9 zO}tVo$`0b4sM$ny`iHZT%6%&-?FTw!n@0Ba-BJ|o@C6KjjxJaDbtm=peVKAv5WPy{ zHJt4r9MP+m^1I-E`>@!BcM!mNLyC>0+$vfWQx#2I45s?NT@H{OxTd5a_$rKcY~U*( zjO4YJl?{QIobM6tp`8Qd-e8e` z#ejv@r9)qDx075Tba8CCMbC35g!^BA-@?`2);7+Bfd; zw|slOJ;%F#gp-09FKh=qCL7J~_q`|FZ9kMD1@#@ad2?(6c?I^EtifzLUSk=5&r3>{ zM&Mcp&awh@cXE?+Sg-f24%>BQCoL*#=&n`68u;j{A(I~}Dwyn*bRR&F&IgrwsK!Ru zdGt-=MqUuMU#K>M8zU*n*pUFL()1WZ7Y6`e0st}9cC+Ws^#eFs$@1xp zh@pI9&yuSD$ca{chXhzRlNJ!--QMTckgF{_S{V$lum(t~{Y1 zX_QGC&pUH$ZzE+|_Wjtx%}x{Hy)P}H9?ml7ryGK*{WVMEww@h)SV3|yBS-GKTNy!< zjVnbol0=plktJ?Y8)0VJeZh+iZaHuSFQ*cpZe!PnV#qt``TJPYz&i*{|E!e8)6*l1#lz-?MYV?fE zq9>qbVuqHlWoQ|r*V6)8P~)ePXKQTbY(z^Fvj>8Bh&vAshD*G{^yX@b6?Os^8aYz%F?%udjUUIKc2H#Dw$T| z+FKY*Q_`&%9ZSc$jL{1lf7C`|)YW1mJn~1iY6zE$3fY7IBSwcH$IXR>?IGm#c2d|6 za@b#Sa+cIR2dLJZkoYgOQ|Yl%ls@Yav92)+zIMdzUQAuY$anw>^0`QaOQ3qX*x9C+;kG9{fR~>056E`<@i1YQw2cOG!r47cj zS2LKoygIpCVab~Bp@rp;nHO09uKY#(k6M15DMfd>(4VQDwi>5i&~x8X|C6ZF^c`Ph zE5Ad14X|)q3w;rS?><>R9{cEl1g2WW#2E^gE6=K*OrHy{l*DfwFGWA~@G z(&r#rC4a2A^&1%bCa#u%@m6sKFcV#Ph59Hlw=OW8p|<1W zKhgPmx%Uo>_3wDP^EK8zMcbdG_(fN3@7!KK^l2}6)W$Hp>gcLX17?*BI6VUICCOR3 z*DvC2j^6RO%<*|zV<#D4W-bgC% z@uAOnJCs}}Y)6z${o3TbiozYyRa?BLqj$Wn*6X({{nMSVmJj9X1*P7ctc?{uZpnKE zSpS&Irm`Nuo!-s>aEJl!6yR&#PBh&Uodoq-|Qz=uC;YrqYujMj`NOERf{S(Ti&wDR=$7^E0 zz@Xj}7q9EGja)vq3^;w*faZqeES&`96vCbm__)V3*`G@4yOZ-8vlTMelI~j}r#Cr; zY>nRWw$|C7Wa+nJJVW0J6@uzg74=EBQf%Tvj!1G|Oa0^GV^>-my$mLyoqTN|0Aw`a zw6O!uZcWY|m#2-}45)u?jL+4^bW8dH+L(~5jXF#JA=;RjuZP?RO9nor_4GtCp`?>V2zaiFPsMYG#mue6VI#s^62ZoV)2@evopmVs@lpz{2bJO|H6u z-#jg8UaNmMMwxkNIRM#;`i!OCx1z4P8Gu|}y+r*OUG>4bdgvCw^3`>X0q(2tTze-V z1D0svP4dAN{2E_Ra|fjJxThGjC>^@llPYjL@@W;ZyC<_H1jF!CL3pPLOBolxM5oTE9K{`!$xZ&wD?5$4**d^P;O> zbN(!RIPd)EfQ3ToCR3BQ{F(OwOE)M4-@6VXJ1#@`*4h~A58V)5^#ncy(5lXt%R65z zFMZrQo+IGT(I(e24ej0wO9ex>W7{un7Gf-a}8hF^qg(qIrJPv zP(So^qK*tb9eice(_-H_^bE+?pOeoYXsBoCY2z!Ko(B8Qq32CzDFb>!y>9NliNMKA zGxSWd?~J~VvhV0BUq-%;i=5n}`%)=wW;mW=?bWUG)WCcF--oI@b2HP+@})FZr(>vb zdeQUwRD0+*7(;YrU36t*Vdu-0y0Kt=5F1_DGNANvemPiQw;DV{+p99Va(aZc++$&B zdxI4&(UmicOS3)(b-rA}x4Sy5D)CxLbkQfssPnY}Y-w)+QA29j&Jsvqw6xk=O8{#> zdJgNa^|*9tbmiDDLSxex3p-!1Ts!qKpwu2kT&LmQ2I6%1P-$i``?8l5Lh!(k~JMaP%nyR`ELmm%)_D`$5N^bcNXqOFb(818}6%i|1A~o z?M=MDC))lG+zM$6cP8F1jxJmfL1FEGtfcc$_-x-c=0{hSn3@71q}4QiKH* z1%?~+cQg8dpJ7f%2xpFye2$(V2oq}hqIA`gt*Z_CDCQO;9)my=0YP==3({GIdO}jy zSpP0g@+G2M>Zz}Hxh>u|UXU{S^K)&oExg?cIBMdnM)I5eY5h?jwSDOoi3 z_+mb!9cJe$(NF`pHNeZJ!J3SwMo3dxTKX4)jjq%UAEy*XSDre6n>|!)*799cx|ta4 zuSC~?FD3ng%Q*Rq-EvFM4ZJ^ZLZm$GpzeIeoes;q*SNF?CtrqEUU(m0VAdYVKQf zj$~KKT3{t@)wn~YQv2mhe(Qq)+bY@cD1B)}s}f&P8I*8!Fe(=fvVO**(S>@JEE-+p z>2kfQMWY9}c*d{P5m_{PV2}WSMWc&xK@)6n*NqSB5;&n#7QE06Tu)aMKVX&UYq}n% z&LvnEM0XPS_9C}_tBS>8GH&cBR=Mc(fs2auR*mJvhAld0z@lcfLb+aadhw#>BF|sc zjQL|gi<$?e$v|y=sqgn;U+AJQ)yC~C<)s@_7bB~g+&xoS`izC2(wCY-P$P%@mq={@ zeGQ;;X?7HWm8BcdNhKHH$vovvblIVG*h6I&=#mx15x%H-fHP9GfU49}U4)e{Iwv$$ zh(4zXZ`dnQGt9A0Z)j(rZmTk1Vr+Q5CW+of&Bfil)bI6=c7G9b^NtU)i;k|Xj5Q$5*5xkAjfxXLA4W;Uy640p*iY+|Ht09$46CN z`{yJ>G7}~_gGNYesELl6Xw(@@Ya&qt%}W~)H3Y1W+Lj_JwTKhITU6jAFsI`vR(rLN z`>UGdn*5E<^d!UvtLs7ocpselkmo7MzE~vv7h)U!RLZw8maAV@)EQ8SDwyCGZSlfu^^W zgM96WTerl|#RtenHMfwR0Rn(eO7UA{?gOc2^_2-3yyu}PzAA)Qeen9l-kd3RSs0pO z6!;f(Ittvauh&T!5-~M1Hi*D&ka-c}6ebggFv-cYK_FDg+WJ>QP`YtAMiO6>KiL)w+OZV`Ja^8+c>o1F#4?2SM!q zrah{3DcPrnN#^<%}?_uV0qs8D{r4x`ct&&l<<} za||PnJz)1dd$JNq$hAD3AwB=?{nEHX3N7?yVR)kI+7{LGMeN>|Oh_#SZLxd4#qRkQ ziV=0-#-0X6-@1N@@c$v3|G~oG_*oIE8`tUUeKK*|6NQRu%t9QPm>fzxuLGXNkOyb7 zSpZ3sFt7ArazY6gV{){=vemqZHE?0L3GBngFh0uo;Z{iFOsZ;Bv;Qo9U>@|JjozFK zLiiy)&O!P!sQwLM=%Mnt7?M0+z#{+|IR8kJ(U{cS_XX-5%@w6&Zm=U>LIFF@P8bI@ zOd+8V*l-WZEI?XkcnJr&KLn9cCPqo224DeOMg+&Aj6{C&3-CdbbDSjQPOHw6Rsnpr zdgc%OgyITe3!TRDMXaDrDxa=$VG;nBrl>J?@Cw^v2&14;f+p3U=;HS(2!?mK{=*gJcIU0mjIZ098x#p2X1qj7g0H$-Rc7x z0xl$jFIqjGL+T@!%nZdDCliozyeQmuz$>YtI<@98H9zu^TCU(p4k*6g)?@E@JO|9p zvHdx*w>_SH=At54Q$Z!p>^^frG0b-Wec$O=70jvLAXC!`2l0hWu@{+ zFYxn#0^Zoc91ov?b+5#U6P00BImO0WdS7f#`by$9l_FjCC<#CK%8(e z7gV4e6zB2`m`7IPkPhN`26Itmq{2_6_If;@m|J28a#SYZZ&FJxFc(x4hFm5L7dduT z>?kd&F^{0WLeCZ;YJQ}egSNQfn8_T9#igCw(0I50%tz*;#@IfPo{1R67;@Da`~KG%`AuS0sGQhHy2GSVDkMrAiK~-sKqWaXYrP@i*!Nv zz}Au0BiAK6>i~L0$if~$yU|69=9xP|EY(l%dq5i!mah=IZ8E@<)S`u~^Pq#?B6CDK z;b4xu-RowK-N`-z4~8NzyRe(~Nol(gOoF}UvSom|9FovNpQF0ngc3e$IoeTxo?$z7 z!*V~61hb2V(AdJXZU}S1i6@EC6Cfg=Zg$XKyMmBIrr7HM_iQFm-dFb8Eqju7IWmFt z1M&~)&kRLyrteu=-XsrRP6k&eEA*OS+Sf?Fc%jdAl6oBAj;{18g_>_ba!ihvg8+D8y+4%@`s~0G8GHM%BZE=Y8I-($Mi&FOv zQ~O0+gm4e6Xj}&~Qhf`+aCbc{A{q|!n4Mx$i4C7La73cYdSxBRaQkbmx$)_+IpF?% zxgT~rZ1oJE1dC$-zz|w!_G9~}7jN`-GWU=QAT?zqhi%K;tic@>R6 zGjugRFp}Gx=8H@(FzY`xd*d6SF>;@d4lu;wFE-#Jmm`VWyv!9@DcyUobmU6;doN?q zD`LMCdsO_OV@d2=G3NZEbqx=z#*Fw08Qm-YS_$(kGIQhI*6*wf1pZBdzkU?>WPyKK z;5|oykMKBY>=c1_90mSg0?!iovqyoyDDZbJ;V-*gVs-*xQtmq_|=IO+dV%JlaiJN@S+{S+ttALLwj zNbfctvh#>Z&@_I6ppBlK{8auKasT}$w&&0X(jNHRdmQOZ==HzL!*L8_9YWp4lXg+a z&top5^8ZNk|4!u}wEm84sSMpx0Q*=~jq@irO8Qk!`l;L5KBp&+LcjAR{pC*j6Y*RF zuD+)b8cXk7Nq@4F{>Q7ZUvH38x{W`M$|d6p?Y~jlzgM*%&r^SHUxMvF8Sz+s-QR&z z;HE)VwOjx6X=skauUL-!Pzw01D&VhCqvu2vz%>My`Zz8z^m*PzYRxl^_f#SDW@&x- zbGWBs^dko9Y0#=Y{u3@Si@FWVM$$AgaFEvSytJH(`Z%;fEG#byMUVh&Hl z-mB8ddSl=QHc?j?z8;Y(P-||)7*zFp&@^>!q+6n-!#1#fh(Bu?>VUrQV)3xPAm-oM zq{Hxi1gC>~J0IbU-0b2(yleP*hZ}pZ?Ubj;<&NPu`qBPjy9XuJ!oVhSvK_hgTN38e120A5pe~=XGHkg_J*ijx(G7{lfO;G{+%IZAr zeH;Z?ytLCDP((NYEgxrvF2nf}p>VhS#qyJ#R)mG0tVupbp;qEQvofq--Ge`M*`KI$ zde#PgBw@|}dv=C3;U&mPYy2Di32Sv7PT1dqBamyYAAbe#U5kkfdy@Z>#D$o%{?Pq# zBK|F|c4ZVEiPOH`VyujaNyKrcNk80pjR#PT0v3yo3#E=j*A`4720HNZRQ~yWDRY! z{&sg(2JlZFXi8g;KX^S6c=BCApx+R_NrWzsCK>3w!m$iA8!_m1h2>O*WsSn})T3kh z?lpp?I`RWLeiQigy^ixcNqjr3lalyuaP9-qUNAVH`1urmdlb`Sq7I;4jVt%!>~BWM zhgX!bQa9<+K*TqY@X>S{6;ctUdh{fIT_OIe6Y5|XueIq~_`Acwokq$H4twK6^g9`| zV${8G1Xd(F0v*6~6NkHPGdgZ#se<=;HX+ z+j+KjpsQHE>9}s7%Prr(l5afBiZs3Qy+Y!5$#;!>f2z{pFPv(k8nh6Z_4eiJ8-MXu zjQU1pdi(q8`v||sVzDRRtT8~>){ z8BA95f?drw?L1$WJe)s~=Tg=ZlpM>FwKzF~c8&?@Im(zLf&EwO=ZZS*r!ZzecVvym zWEoG}weE)}5E6eg;Kqh^s#X$DUZ7RdnXG>TJ%-SpCh7!u`!gjyEG6MF>Nc*@RL+Q$ z*e!VwDTC;9?94M%h8#?80VeTX++sEsB#T>X7xy~R1YvmZ+}LoJDz1RV{akWX zCUb=C96z^ntdbmUD#rm}6JLZFYlntY#dsgpBK|3TQs(p1zd?a^(VHT0U#D;)jaxy z4Cr)EcQLN-Pxg2t64RMTW^|z9MSzpH^}VlRoOOiGrm*5-3KOi=g0^E(QUt^Prq&hA zTWcpby?$$O4i0*B$n!Nke_Zu-w)V3BlGeh1IOi^A;WN@$yYT!f+i#W3m5NTqvW5P` z@1u@jilzW3;?fj|czH^b_(Q%2RRKxIFNkwt;&!CF)jwD6vAm{cVx=#S^+)xYaQyQq z;pltQj8*pE>)4_@|0*qd591^dSwO33#aUSp$i|>cU*kt7MB0qG_J;0SP^+4U<>?8Vy49dEsa{~KTMRkag!20p&o!g=IB#Tpl49Xi6EpGN(Fnz z9hu=ZaZ$AioUjKS#JmJwXM@QVQYVDQ3fworTi_fL7j4S( z0iWvVZEp10trfx7)@6pq^9G5jKgU6|P77g!!Id9&@px~g)-HX-aT8yG%Ge(JzVZb7 zzVa8iA%Y7aeNXA@v!l0pqD!>!G+H$(4NL3$Gs@=eWJ}#nzVt|6uiW2@Phn}&zq99< zyIahzE3B+*$zvz}89erge;%j>idet#;5P=p1!OsO;c4I_V^}lZpe|8)0c;j{1GkdA zrylnvo0TDGJ-v;B#N4R2eO@?I9%<(wLJnn~rH=ww&M+{ooJ~xux6u<2ap(6EawE3C zaK|4TLioD03;#6~QA&a!vN|5ahb>QR?67^?fk>P}<)w4=>bv$4s13T8n_G3G8JUCI z72PM!Hzz$0>>RpJ47(;_Pob213Z*h8R?R|kY-wC-b{h#Tl=MVPjzm6Luh_pLL(w4X ze7qLM2IL|u3JTbb#Ai8>c3GP?D>$9f0ILdM{wzM7WNq@Wy`+4|PT9efXfJ9N!K#wF ztQ9u=Aq6id9G`YkF3ZWkLc#F_eKua$?m$Ri^+#|3jH(s!-DCy$TWgcY*#Q%(ljf#N zF3#2<$~tu@m&IC>w}9tWQm_e)nl^tQj%lr5wwdxKnvFxW$L#p)hNr}FnJ9?KY z#g;kT51JUgO#}0)valw;EIc9fo4!fM5Rv*b6Vo_+&XGRDDOmYCQ1jnaGXL!s-lh|7 zG~pp2#f!rWxDIXm1v_h&92DQqPk6DxUg+ugG!mJi&*MtPd}#cS`0qk4QTiP}W;nsH zjwR(oV)?*uk1#vimMi&)A3YCKt)%Y#MZw-D6P-tnSk-OYHvF^hSXne{wcNtYK>t|aPqhYN{ zIpxO?C3ct@xGU^qH%R6~#F7k$m}(QU*Ru9PqcE`%(hZh!)gY7QAIQZV3&kphx7mHI zAg%0;s_C3^UPF2tNgnVJiU8lpB84l=(4WQi6Yv!W%>&>VpiyI!0k_(1BAJ7nSn$4q z!AT>?3ElT9Dk9I{pnhHR`Rnpm;0Mj|TGwIC9&b?mou049&bQzg`AV5jSNX{F>s&xe z^|P5R=NK?x($=#*bID$NUYF^)UrjM+1aH&>Jul@frxD(yCzTs~AhMNpxghVQ#a2Pp zg%n(J0rY)b$&IWL7DAS2gKRE8^hvHQ|DP`cbG4ppkGHAjHgQ^UxHI!_kA>Xx`GT0y zooT$Ig|fPoqcdkJdIe$lcu^UDcVcLxO1v)<>2bwT-A5ao!}j=`_G}=7Z^LxX#%w`HcM+yV0%_4+fy&?>HQc&h0}mC-+URltn!&)o_V%sHq3Xk zpTl8xxi$0+!Rp_32$f%tZio@9X1V&*Xzrq`=ngoF#*x{VI-tQWeeQVVi*D#bD)RuK zZ9F6RT%JV!DH%!o({mK%(G7d;$kr)OX4>PU22CvhkX+`?!PJFcH&rJ5f+y4*`TWly z=d!jp+6DH zEBz{RfRUt2bi+t8JC$*}%*>s3%65Aas)1(Besg7`5#+DBhtrUzUIG0%2MwYfpNU1s zrEbNH%)Y$I>UDQ9WPJ)e-$FuLrt=t_(S@70{$4Anf!EoiMFtV%&p+ba;=n7>KT~QSv#ur(}8I4z7@ji{q zlrx$xYx_cB*&15h6#d>soY(K<&GCg&Sef2CA^i>e;{=MbP8xj;VhUw{QnL!nq*%^?5Dqc}detWe^t zrjWv?yQT<#@ly=ZfgisLm1bo4YPxI688VN?w-*vHhHq~~oWr-)#Wvqkev@F2UPgkw zyjh8E4sozalUl>pp5=xZFb2ozYtE6Cg0aw9!^--t#RXS*`Q~oV*3j|hjN&IXbGAQi zJc2@MBf{<`n1++--!*5HGJSd9pVsm&$Ej#0)}M{gV#4&O8>xc;CH0&&=sY$IJs6qo z!ia%#Ku)D~QBK^{~;AFt#U3`b&mAovlH$)o0$WL{)CpQ>oVeRA;;0+4+`8JzX)^!+(#LR{G;UJO^9>& zE8IZ-ifbrNEoX7{)>&r=znym}`R&p_2){iIk}m++=5cL0E;~7MK8KDsyEsJ`gYWE_ z^QC0uR7R>fR_1LrvJc{Ue?8S%itJb&p;knKEOR)I79Sng^N z{w#EB7TqT8Jbt0SqH5ogW$af@7AbixGaZJGXzyuL@2~2xVT&dpG10Ha2yc=_rdns9 zL4dkE)E&TUNO7Hs+0FkWuqINE$^m_Lv8!rm=_rx!HZ>MKBa9}Akq4M|;_>6jy)JtKNUhm^SJbJyyO8>`WrRNNZnG*S~GlxBg zFvIF?BdFP2RBA5c(!QEwN#5oXxp)jZEVRpy$B-B8Cm!%c*9P(N1Y>6Pt{C>{Yrc(d za)JI*?`TGde-E{AdBcv@*VG~1f48&sH9B%Fc2^DQYsRsje?t7>eWQuL4Wrp1zMf>i z_8ZYBqz-(sl|$z!SUMhGrI2L1kzPm#fY}du2BGFiG`;;fmUfHJyp3xyMZ;e*Ly9gB zAn4Eqo2CB}UCu(f|2|y?u=H1S;eN?Kqsu$-(R6tZd5%SwqjAs6Ob^?^GJ4lhEq@$Q zNj==*iw78K^Tlj@|0{fP7SjD6v>#>#yZ!k3r|q}Kw4X)^dr*$$i=(!m=@%87%V@^3 z+mEP}9>}G4N*;;z0Fp(l0%`K-^V3rDD1H+PKxw|$M`d+Z5o5EyRim@j zthpRJyuA!^Kz-vZ2XM(+cN9evpc5!m{l+KDO0(V6Oy z8gm@%_A~=PZ+BUx(@=gp%Y~$LMeC@{Sns}<2fYKZ=PTHFGgcyaIhc5%qpld~iQflrsf> zOP!SQ?|?lVy`QbI4WEPSmG>v^0l|>?G}2>%dK&0-3`6_wr&WfNSRNE?*>k7_GH#-0 z7fal%Z{uzai73A2@0X%s>TF_H{Sf^L@l=f!Mt~EjvOj}1NxZJJ@v`^f=$I$D1=4Jz z(1cQur@Bh*w&-hUKLX~`h>m~Mh~w-MY?DtV8lkpVP+S1WyR0X1*NVtja#B|1W547D zRuH1cRhMqujq3l=_J}&JnWk@(KtirS{B6vM)RU++as6a1`n}jBmZPp?5dK=c=L)MhFLWUi(zH&dEwJ#H46eEw!ewx z{$q4cQ|Pu`OAbxrkPB5Gwlf}>--B7!7DxrQt=HM`i?;wjZkF7sVY380cp0u>a>H-T zc1Z7-^R!%!7fz>e3cMuKO@DL)#W}D@w_k8H;&>I=#&#)o#Z<(sP73vU5$gGGjk4f= z3AwBrD`onSgIBgc=trlq!k1r^3VDBzcN&^GXzIXk=_XTJYQG$w-rtYQ^@}zuPIrCS2L0w~@W1-PO&Dq z>GZq7F)_?I)n-p>|8^E8H(0R>%mTmFI#~^+7g4OqOIy`fJ%_?Ft~Go3#Et0P$znN= zv)JA!#0v|JU1jz-^K)ADPP)1OB%On10O`z_dVd(``@RkYq6T{tA-AK?%tNfbaz=N0 ztxGDgdVVeb1{u^8}jV{mck4ix7{7vT;GY~E-wC%SoTIes~>y3Bs7Wl*|L zy!oL=($<%37a1u)AYhjw2OHiHA&gS&0cJ~Y_m{Lxz-5;1LiKP=kGud zDBCCr{ys#^1M+;EuN1#7s}uegD4k*El>Xy+8HEK3t03aiGVsxYFH#wR^QE?rU@pKq zyWHBD4M76EL8{^15XdBi140Ar4hli6uh~@$Km}l7tZoCoqxC*)ch4iC^!qxE4qsK5 zeqV>XQ*XNw6)>eSc)Y&)8U~vE^9KHGyrWlj>J7bg8?Uz=0A-*aVd9$?$ie9Vy)7S| zrmwHp0u7omoQYE)$cb=fpdr&3&eGfdtioA=hAd;)1aUI%ZJB=%$tq4 zR<^Tj8)#f=9yAX6Vh3H=Tf;@T_g%(NKBCK)G_#u_?8tc4+BS4_AnKinpUU9&;A@~P z{E2IS)4$^)m%^j#L6;9cQ(Zoz(^oaL_$`pM9Dr(8p$%4z=xttb1%2B~xv--L3bg1f zt!lTv`VjCkH{+&ywial@$eNYO*uP5OG-YS1xGcu?*l}4Z&c!(D7tHHYapM^GkR3Np z#bq<@E;}w;#pP7(Ub39|a#Yxj@Ir>&D(pe{YKA>3oQrT1!?`Lv9^q<+$E&ax;c|w( zDx8Nft{*mK=c#Z$!no>Ko1HJ*=9&cR(5mCrK^IB}r4#TM=N~YOsr{!yE^%f534l^3 z4>hH+c@`oM;HB~Rxl~m0aV6TEk_Te1I*L3vG)1hEzfR?AAC*rmm`BO?yvo;#d}xy& z)@uy0qkAS3`^5^#Y7xJm$}Nx+p3V7dUxlYk`-piBUPB;Y;= z;1fVa67Zx07`TjBRVD$O9l)Ccs7?a*Ie?73Kz8BXSe@*|5E#Z zGP?am5HQkyP!BbVL*4ZHM1R};MYjInZ>9CG0z^YjW{@YdS~LET6QtHMMiAKrY* zSN5Ga%HlOT5JB5RXTdw{G5j-;KAl1z+%Or3=~dfh#9USJRz7V~j)kEc^?IYmyEdyJ zw%J5KzBjX?X7>r~9xj!;jhvpI*f00J^6a zvmxkEwX3`~vf(|9h`yKcFz==N5`8b>B*8nZvH@A`D)B{EV@1{?OhBxb@J1VMVzD?E z@yPcp+8xyTXA0Z<#BY@J04L#Uk>2(zWZ`#o1KSVA#1V_vLN^8XtBAgWRIjAIBCcP7 z3Kt!7|1PqKrWj&0ml(m2V!eimwf(T!-})|Vi}+9zWKPxQ#ZNKW)pjx>{!^r68ph)~ zm1IY0)*8g8#L*~uJUh6ZJ^K3~Te$hxsz;#!*F@_4INIG^$MQ4amt^3hs=A`3%W)<< zayxGp7e?xMV62FmPPe{#5qiO_D}Zb?>f}IfkvYSQ*UPl-X!Uc^ij_R$2IO#QEmVnq zs4+M8O%%J%G#8$?%`x$#3v^;+8b>b~7tU zVr#$;h5bfNHIEY4q7+wz=R6Q7O3=3(T#U4Cj7$+X12xEe64@F_E;QSah-}K@~awvu^V-I-)7dHXoV-XCresUCqnFcR0gh_#thhWKuW13 zS`d}GU`^3_(Om0m6ZcD@MqRmvlLg&%1p=Q@2u_fLRYu*_THMPi=Wx0_Sb7e*=bp!G z?%}Wp8N2I+cTjMmMS84WdTdGI)RuxQ*w z?*ymc=D?G$m>IYVK<{U0Qb9H}pe zv~V==sBBU6ejiA4k!nb0H+5->y+UFF@?VGkMJwSg$GoEeYtg9dSraAK2QaYU&b+pQ;Z_S?1-M6D@Ja-p)i* z6f0ZbM0d%~MjXyYGIZ{%Wo7Zl?p1=d*#r z9#j?Ro+kYZL@UVBAR``+6&BmrZ%mWEzNK*LW$bGU6uZTTmPK!4Ul&E-EK3d1n~*hN zZcB~NnfCacnLa-0oGdv$m2D+$d;-St3D+8##0#xFAp#be2A5p({Ke`VG69Hc=1>yH z_9_0A_E56oBn0waiv|U#A9Wi0=uWF>SyQyU9Sb3KKZU@Ih^rJSPwAVG672RD244gA_cb z{zd%22gDJli-2R^C>%MzfXUNw{17-6YDAP+781+n94ys+rU%ZH`R`GC{)66(IeNDK z(j-wZYF^|N96T)ih-nB)pEYjcCkcLh$l z%S+^1B=a8b)Xd$jGi^iteDfpqlAv6V8+9&wuR52F>vN~n(cK8u4ww1Z=7YF6cjT|n zKL`b7N%It+oO6u+n>PQYt1?iCDmS!l^!QQdw-3nq?I@NVs{hxa%N9UDEdXANBA&<+ zcXWE9eLH%+(cBD4I13Jt>=fwy+Q`KiBs_D;t&3*8?F2Wd?Dd<2AoW4Cc%k_TJO_65 zmEe8?_IP2tN7`9XCK^%xLe#Smr8F_2zW#D}R9ljXBPZ}G1)s&9L*jsJp-DgZ0N21X z+2!Nl-jFUqyQo?-yUMyG8*n%?N@hY3KKKefou-9>;|=zl;_?TrEF4eHf`HZN9&%x< z10~LZBdnz!ef^!ea99=lzz6>{^zgLM12=XpQ^bEiUmJUN6yfuD;<`y8*r)`dilyzij7BmiqWnTQ&X)18H=4h!Okcm?3^=qcRS21b9?R1&ep1PtXOi1C0+Rr$rt~Tg zZaxJsDphBaLxZrcE-D9^P|jH>=WH-cdNF8}OFY{x1h)d?nsZnjUEKwMOGOmgpw}P# z$lP4A(>xRu8bn>^#5zEzB>{1K2pkp!QTmkF`($I&A{w4S@pilrhX&Typ9{}q)p+~7 zFbl`of+I47DnYW5sOt=luvib6`o=Hn>;LUb`ufEcb~*bz!{%lX^6{_^wC z)o{iIZ=}Hy42_bF81MLM0vKDRC>+iaZ>iGP-*&#XQ(u2sr5aaoIkhp%GbBT6o4J+A zf%^qWFcp5$F!WF$jodXHDxd*Q0b;u}*j;ikxHalMU$~S=#=v5CUI;X*Ww3g7;o9B8 z8bNLVu1326f!oyNsCAhGC0orcD61ye9Xx3{#}yW7)k_G$;=p%FqT)}2=}7=8SU zs@{?sr4cZ*Z6i?*q{j-b>n8ck4M6bU_D()Iv@evRw9 za#H4n^CcE-FzM8mU&xjC7~-l?dR!Y~$@fo@STMgZc0q8f2HM2B_29nf z)7gXthf!aJb_h6|M=WE%0aAKUVzjGe&|C?B7IMjMgC727yI7>~YCNf^Ql zH1<+sET%)eH=&YB41H*8wHiE5qV=;xem7&qsC{BC;I3&cR5-mo6MLr6rsmok*C~DX z3ah(>`rKRpVXxP4#2uYj!>z%ypxtnZAM!Uw3;L^i^)+0JMP?MB*hX`m0>+5Dxq`kpspa=sKqyP&t2>rs_f9?D6^L86Pv05QUl8kna3R+c+b%a$Y(ByM(TYS9B{Ngi@oO#&%6x3@Dg5s1?&;@|2y;YaDB54o6TR0 z+rse7mT>(X8Aj^<-WNFpYxchU>=TidDD{D{DF-o}HJ1<%jF^(X6ca zwe>o?-xt^;_-~KNMaB7Rp;HvSd=XG3%J?Dmu(|MZB|h0d_h*SIOKiK+chGs8U`)LW z4)t*t<@;bp8K1mgyH5j$_x(V^Y5XtG_|Z7}U=cau$p?iaaHIKCRD%1(VN`|Z9{JoF zPQu{Pw};^0oe%7Vs&PK9jfkj+*$`U65HPit!(ofv2Uaiku82Mtq)2Kl!VxL+5a_Uo zkMSw9d&`^%uhsFEU6a3HcI@r!E8rg?UK7c=Eb=v1fkPhCvO9WL*jUdpN72|iv>()uu#V!fb-eN5iW^vme{3C34Ae$gN9ou)etQ*&k2=c7*74Hr zt4-Ds7+c556V~3uIx5E2ao;TujTGQY?owm<=ni(^ zPtN>R_xiY^`rqM;_mu*4hpOTl-#NP!MaEQdML}(*!gfp*EBF2kXs~C;)Y0?z9UmyF zkEvtt=C?}}MaI;zE9bmdScez-{itTF$=mrc>nI*u$Nqw^)+wrwsbgIH-T!1AuoH|X z)!@SiKV=<7W9#@+=69}V9f7fRe6Q(@=onh<4sv)*uNqFk3~_UDtiz=S2fAYA;ak?Q zm~vJAcn%G$((fue`Ro7jZ75$iSH@y^fQkbH{ot*9Uzh`3&3>4~VIgJL?tAGGmhDR~ z`#-n7`4yIJk6CSzHmG17*-(_<@K7W@kT~PZ>{kpk1?$WWzNK|~ zNcu-lx&JXDP@oMdSWFLgYuh{&OjQrv_bGc916sjeIROiSKS+JATzS>ESfBSO^?m=3 z-g{UdM8{|9yZz&X3D)O2N`2d|X=`VF5K^D1@6tQgeTVf`AEmxMd&`foK8VB5)K~Cj z?P1neag_RgHo-lU^+E7{roL5oTrt4<@SdZBrP1??ht7YI^+CjcroIi^cb~!f{70$p z-W{v^P#=xJe>b{nVy~PKxjjSs1DN7=FnQ#5H#+=wav8LNYg`e`X}CHv+gmlD8>@yA ziMdx@^R;V}_Ep(0z5WDFn0Ma$f93k(dxQV4tS>rneDwdXFaD>kFD^NbgX0@_|Ks(A z3u{AYf=6Fp_ccG^+a7wy0KzkGdBG4LU`%0IKdXu`Vizqh{lpS2&w z_0Bq-9NH0a);r#+qpx>r690U?^C4ykXT5{lm7~@>D<1#sdWZFwO8qse{@$oj#QI?) z!D7pYb&^_a8Q5Nz#nzXwB(Fs@mRH>QtC3~aF93C_9m4vM%dBF1ndNb+4cN=9&zzTg zG@k@``FkM1BYriVXP+2t{|TR)KV0#^`8t|e*u0^iQ=YBEv`G% z^K?vUl-EUYY8<~rEP&re{8pHQeJ70CmvsU(GV1G>XJS{bDHGdr<#_A}8~Hw%zpIWGhGCSKZb)2z`l!5j|P>v$XvhK7T%g81;v zT+4BMu*406>^>j%DvI2EY-r{rR9GIaKc4T>bue-*3IsUM4{drc;anfAluo`J-P4F}dmO+4zLbRBxYv zk20i(A=KYpM|3ixvw6M_JHr`p5O*qu9ttQm_71i-1LxAR{#JUy^a)C0B35QBPzaYt zXsNy36|D&B#w#emu5ATAQCsUx>f&-*UfiD|t5{}*-{O0)eLo=^09zu>8zaUaonnq{ z?vG^dI_+I3t#7SLr?(q`+hyKhr&IP!S|Z1Z8PY}j z;u_mb_!&Frt*9DyPTC}I8yCg{93Z4^7hML>XVUWy?byh^cDd~=)lH*`vXo|3I-y@n zdHRNj;;g@2i3M`xzc^$`qrKC=PW2Mf#wcLavY1}_=Ju`b(e z+f|$GS`n?$AOghf_B@DrRxQRXEsyt;t01D0K*p6gzDB-%y#-lkD>Mx!Kyx zWcfank8+Ap#~D)%JVllWoeVCgz=B1P2bRP#IHr7@UiL=}m%=T#TfWfJ4CJyNJml0l ze=Uv^b*G=t0=aJx1Xi{Qxj&2;UK;_{1SHOyYV;F{Q_&H;4o69ejRD&DO1VKGi0~Y@ z*du`l`~ru>B_-?js`e(~phGzeP?KLNeqGjs;85W8tn5D!4hp8j-yjG7NMQ|ppUWY^ zwizeDOE((~M0m^17s0DW!1olKcg!}QA{l{5wi#i2fYu4-ee61W^TRQNOR(=?Qa)NU zcy=~+D@$K#larf7E^}o$rgcf4{+E{* z_I=y)q{K^AiLc9E0j78Q5qKXg$3u%F_?-$pXYqH?JF_@v0#Vsc!t`pfeC(6ra$l$p z_19vT_JHhKtwuKPTD2~~juqv;T#m=yCeYwcVUvw!Ezz>L2Ly5#nH*})d1_3}Wu2PE z>M#neKmHs(0RS~EnFrzjRoox&8)AZLK`m4 z;(;c+S+vy$Fq6b7;2|F!+>eI$0^#>Kd?q9~52X2*g$L#P6rbby-3*+~ineNDo(-wR z9#Q<;$T0Ri*=%zgS?Cuove1hwq>tZg-@a`A)ccyiueVE#CD9K5 zL%$%Mx61=m1BcCnJ3cV62OYY6YUFC9y7dyX$9Ov@W@Ta1B7pa`%|rV7Vg2E)i!U?x z?Rdv?C`>Pa>I57$E4mbj8k2Ewn7tA;YI%bJY`N{pkL4=DrDNbdHvG3XoIa4#^M7i? z@3rAG#=w``@LK?v`C=XRPN4taX^)>sBN|Z^TY6>WDUu-S{cTmxtxb`qNP((dOTQ7> zK#FJsRl~Qo;52P6MrujbmZdjVZCx@SFJx6sbG6=qm!(X$Qr!r`JPSZ7f~}rA1}lG$ zYV}{9P^}hkR%ujevf&$SI6Z@=w|bEc|FI4K`WX1rHvGGQQ&2klcXt10O8?)H?EeLJ z|6h01{(tnS{oic&f73Dg|JEzm{{!1g#&ST-7+f6=*!mkqi!YCXI~?$Y4X3lbbXt69 zxAh(yK5Y!#;ehV|KIXhAwhwVa^^2A0;VZ0rG*ac!+l4BxM>dcHz@vq@0I+5dB#0Q~ z1jJx#s4Au#?@1h)My}`-MH{L17h)I`lnoAq&Mk~Q)eIoS=I8s)RO56Vlv$oi$C=k{ z7REiC2x7MohvdrfGOO`Uj{fk@TmNGA#H^F__I*fKg*CW-_a0V+k|8=#@{avxceF0i zKB%{^0>B)^>ElnHN1O2iof?{Y+uaDM?tvAP5POK~>npN%ywkobG%HQYkw1BiAf2Z3 zUQ_%z_1CIT?!<~S9q#bwiGW)Z5+BOY<)Sq`QP?iz@Z+kG$}yEV9lOhh^C6e?{0?KR z2VBt)_c@|xv9~D2-a@r2Um5tW^w-mB_$GUet~(2(GZTuTu}tHgx+1NgJu|s5vcc|| z6Z%f$@L<23FwX9mWT#Z%p=9ZlUAMjoRmNv`46l=;V+!@VUHGCN0r6gRCX_Hp%=$!o zuikzp0A?>b=CJCRT|4%gA89eY?GP@bIvukY->HtN&OyiQ*4sK+rZE?7#60MOWJJ#w zn8VQuI(Nvh&d00~F(|WGvDR;u;X*B%=Zn^V3N*MZuZ$l;N2v1|%O~T^qgO`)zy9zx zebrRdiHwENJ<9QBI^wHK2K6V%(=jx$NN@WbQ()g0$n(r%DcHHt=*JE@r?o7QLyqmC z)Ph|7;bH9Kqb`)_M>U8T(pOoGK*m#WQ(S+d8~Mv|fxrD^luMTiH?#a&Kdvpn?Ie;; zt({z;N9p*U4aLOO&S|7Q&Imkn-u{}|quc^iHBI*GtADFX_p2!fSmcP3wPOz_Dz_@T z82FHKaIG*N)ZsHjW}cXw!D#RZsmOjG z25V1c13*eZxUY^;o`qJ7X#yQRqK+aY0UoLugH|op7?B)l2446@GYG|3rbM32W;CN2 zy=X=gno;mQd=@&*co;Q0&3J&dLkYqOE1!l^d{u|cUUNvF-lf+cGGM?WlVOz)CIoZ# zW6XfL!9#7IV*{46t9Z9PvV5{P)m||C`G|ytM%`GH7or?d#53}$<%d~hnjmsI4$NWu zLM3(6T0IjMe(-c94vy4L_JP+gkj;z9KJ!qd0_H8la*^Guj_B;Wm< z@MOXK8zVV)3^4=d^2cVeOquNmKG8Z%gLVyoYK{g45jX;AYM((TT*Y=ROOkvL4_h5oOmiEqFK@G22h4~lyV49?q#{;7aCA{;)__^AW7A9s<$4^q9j@j{-Dw)ePNIC28?|cZvNlu;; zZTk?=$bCc(Ydl%h@Bz0Bv%nwRZXLv7smOiQ^3;TCy@}Ie5y{L7q+}d;XCt3Rv9ZCE z%(&S#@F%4Q4(xIg8C{vMGrOX-3lb%jE9h}wUYtJ+rR|biGakVEYRTSP(_M63%#*F{wGQ%u@9++$g68I|38~ioRRS& zoixUOg=M5w{pN=Wqw=&+&Pyai-@QqdHm#b$x1}!{2gIQr8`+NfMh#?JIDFw@CEAQJ z@T+b3k)JDg+Zg!uw(xn=hW|p~-akO(*yH6@8}g7q-eY+-^)z~=-zpg8{W6AGM{ZV`dgAGvP0DaavSoVK*$+KALaf%u*uvgP)EFM`4=1j)Ri+cvUZJ%R_BR770L$ zTjPb291&Xqu5f`p%W+Y}pt!8+TB6Tit94*yQ`NO}fb%WNEQiJyenT``s;trK-%CTF zb>a>e=Gwk|XJ<(LMk??;R_m3fNX2YqQH1i;(kG3;pG|jhs}mtM(x&R#@{910^ATrZXaoO&;?P?BGsRA?Fb2 zbYDlJsO#7G%Yj)CzaC@AvF|_uQ-*||#d$V;3hspxR-^Ei4C$h~MiVo`YWxz8z(F6mE2^ zH5#|6pT(^-i5sX_Va7<+_UUODnuh>jS9X_m+R_y36$q3;^(U~z!u_DqDlUxV z(NM*CJZG;u+a?ydFKR(zk>JQ*Xb$qgZilNK8mZoX01%*7V8)-t7YMjxkKD{ErUwD8 zE24;Y){`q)4A~&HvdENdYH{=zf=6}q0TT15i=*~4q17smjZ+Yk#r3Et@Z3L*n*(Qx?%22Txt#a^>kvMpe zFNMF0YvNwLjeb7uH8HnMg-e4JsYgRTv^atVk}zvkCq|>vbX;Ks=Bn<8v$$11WMvVu zuokP@q#Gu}5OAx`MO8}aK*(UTy0Zbo(zUyuBR>PGS-Q@G)|POK`Bg44MQ+Sr z+xG$`e$BMd?y$@48CKz|C z&+6MNLLLW+WFD|i#DNS<4o(=8{c|8C_J3}W0zZsA#lkShR``8_K{?&h38lh zv+zGS>52IlwJ$!-<_3K0-|ygS>RqY1s0e9O1*!L{8l}SPRE6A+EXL-^wV0i(n=yni z|9>@=|M8z-In!^of|oJOab1(i8or0qLxMor22OodU5nwEkgQtOb?XI4epoaRE`o^f zgD3+yh~@%%m7)lg<;Ev}UDkqkg(L!Jhh90R8yr*KtRF%@0>Q!`l3))lu(hK!{Q0i; zX#79?vEcuEOtmTe*O;Hde@+tr8NmNbqws$NWu)P6yE$`NH7tf2MzTHj{@*+QT6sA?jSnRDXtv;*F}C32`~36Q(%yJKvWOixX>Uw30>5e78b3xNWdx=<7=oAXHfnb4 zFB^=`7DE#)y_mSh8i0R-Xh*J!>yM<}#YF>fFZ@6xTR7)O(gDt<7kT7Z%l+~P)KET_ zIoJ!hl^OrX=HL(hT@`XHG1+ayk0mA_1>BYwXyvGX&Uq7VisH-(HQHVXV?NEG>#H~8 zQ$z^82m~S_43N!z*&P4y2jDaI`;2bixpVr>iI_mno%68?XF9Xo=gt{4Ti~F0{5Pc5k1<1?bM~u0Vwri7ArL@TnutW7iqCQxDMxnGU3-g$wHmR z2Rap?%YY2Fv2#Uk8H4)L<6sHYrr?>Ba6vZR4h=4jBU)ec4q8YMqNB6mz!XtiC8}A| zjKTbHbGD|p(Kw6~PgiRIi;s=#$*|TUc|u7=@0D~moYdVF)qDrjU6-27|cb? zxX^9Pk!=im5XuhS#88eg=td|fbPYpzDmDipcj!`vJjP%)LY~kxhH~+25<;i%gGI|eR6|_ z4s<5{nv}9D<9tvAULi)kcdYoK7wLEss|Gw#i?p+N((NXQ!K#CL+qsz4jUgSomaFdr zIdIBnlcyBi? zhZHsx>s^uQZnNGUneGK6vJH=tp@~Qn5K(6YaRjfJqL|3g3oan~`bkqbj}B?L@fMz_ zul^F0V;%l*;i*Ccqy#qnaGe%z!RsY_#~vUY&6|@6(8)uU-UEUGME@39 z0G(nC;g(!hxFt(p{d)z%8NE3!fZ$1J94^p>TU`3;?E zQy?7bo0ARDX~s}axGp=~lC7_;g<1mF|0s1OE||1P`NRbhYNlC-oTP7su^Jer@gy8L`Vn`6Pp`YR}KQiNE#Q4pIkLd>=Vr9l4UxzXq26?y*0%pdi z2$!1;pF+OC@7B^EIPyiw6=P3-ba{@?9Erb*<;pSNS47Q3#})Pd09!5SIQY3S-mVU?wVqLc{YXRT$TNJpE;`(1^Ucc<&N4l`}uq%gBM2_bRm$7 z^!09Yi?KJS?9f!o(w$51Fpn5-zZ^SI7Ki zUt#;Zf~N~KuM(3*MWnv8oyu`xEA5N6zb?2qUy)x!Cc$#PUY(Oms=0-UUZcKPGg|x^ zD-($$kZG$Q0oC;NGjaA8XM*8GXhNX=ICF4dTg>tWc;Gi?xs5|d0yx|_7^pu%{2}Ay zaCoL~%y|dCnA{nfOmzdr%+4?lYOp#5nzMbFa|8%CjP>Q=X8)vg&NO8g8hDW*COOFQ z8MiXf3tG&hHW|!eAuP@=WA|)$%1qysmI?92NMpm*eB8k~81%V1(o%{!3ZuanX(?Y< zgQL)AB2b{WRdX+XPfi$fL$A0vH@Cq?vlBpg)z=}f0EbSL-Q~jiqxX5*%Hg=KY!kJk zwtIwF-ickVi5bsNK%i`&CkB0b52TwO3c-q_K*x;*U6}+OKNbYah+Fgx zt{^=4HMoQIh42I%tS`c_<3rsp6aH}2PN+Mvjgb;cGN4i*wjr``1&~HHMXjYP>hrbM zlULN|X{|*o>b+X)#1-}9wN~GX`dqCwcSXHNYjv%tcWaRxh%HDq>e4{dtm}_7PD7El@(qN>4@~YabqrB4B)PhCO3i$Yf+Duth4dN}q9)I+6$2E2+EKSbl^f)=QsAdde30z%qxnHVwR?4PpCj?2Q>;qh%{^;UUZ z7)0Xq|EH;R<1nVg@qZ*0mmR2|h{-baUAwHDKs{z^cjzWN><-iyV!{nwWrsb1`p;oH z7DvCtF*i{Ec}&)!sWyCkp#DTm<>H-#aBrXC))75K>cKps&%{_&JWao0Te5M zBmoO>9^pn6rXP1=Cz2HN%ak5b6|P$W`~r~Y@Yk#L2lVOjA(DxS(;g^?H+o(`gNkz&_F&F_mwB0D?{ zuPN}IGdrGYAD#it2~USsl16aqeCHVncX%3flQpUIRQM{5geN@R9lF&ngPLBIk;n~C z^Mt-;$5F*Q-$;xPPfrn?y4_SG;SEn4A3D!YN2RXXNaTg5dqbz#an$H8Fz_bpw7gax z-F1<~n-P%VgsU6zMsa%3#8;58gUK zdyY#Gi31aD;m8CE7@E+L{AY%=1l3nxnCz0?|+^F%e}a0SBg z??b7<$%Y1K3bx#q2j1jBE82%GWE5I14mIb~52#^fqV)nE%aY_mc+NZqOD<2bWKR62 z(5lkshlQ9Q?vVL`rtv$R`2l8owR?d1;dvd+=Oi%*b}ug*7V-Zm1SIt4iO+FX;2cmk zM9~j@4KIkOxxtm+<;u@^PUeOo4+XSX=6%nj)v%nde3=7w|-<^}~) zl_avwPRMqE#Xaj$&B}tOwy19iAy62kP@Bl#kFQ2<1sA520#=yb|&vbT&fc zB{UwPVuW%fl#3AT74;qoc@R>vUpF@Ta4re5pO~DBQZfUKTaa+VOg7?f;-3k1UHFm!V z*jh^M)VQS-vBzyZAGhT<76nX?qGJGXbUn&a{bKJOQt; zlgS`FO(xvL_|P0XTIK^x2Ap>j-cXGlEmJ~xnoPfmyil1PEwciq1kS<ovFB2Cga}tQuLh2*mxJdIEFcPieh z>(RmUA~QukVpk+GQ_073px*iQwjxT9H2K(5wh5kAF&srgQiX(IQd%&jWZ5Q)!2hwj z^UX>=Zk!57o_c#&DS8Wo+l>y`%Z{Zz^Sv%xd;SeRO$(;AwK%AVv50PJ-;YkH)Z0!( zP+t#5^BE%;DX)MSu*t~K7{SosaR`KEJd9vGJgmYp2u3gnXfXs_IDZ73Z>X@aJC*@U z0Tccn$)Pc|K^S_(9r_x+g@Z>tp)2q$EIX1LYQVSf=?D}N3h2exn@Kl36qSRT7T}#Il=Ci`T!ZUSf-gqIGSAXMPv&RF1e+>da zU*Cgt`7mN^3(w4lPc%DO9EXURW@<7`p7@5u(_Z13c}N$ticGk*#OYm0(c;y5S&bJU zJU%aRSi>P^yu|zsZRQlO^@QtlVN%fBc$5=%2M=RB60;RC8TIaXx6nt)wHuQ5F=&l5 z0D%1@hunmTrUv6GjFH6WIKiEqd!`v9nc?XeZJSjbR~gfdk*x4^q~inGNXOac%f^T+ zJRPI%7b=d^Osz4ZRu}iGIL;n1?dL)ARKCwBEK%-plL6R?RV+zwk2UD-;6YZ!@{lyhg=Op2J9czf|+4AZJu49e}HEz_kb3MSYp zzKkMbNrsZcqAbcj30_pC@Zx%59tE*7{9u4n(HYW0zaaqXxrk%PVlD-SGD8p8(ISx{ zj=2mN$_lNpqeUn~B6A5a1nq~cWrIXE!|X%r*$_nWB`J`IXvk+S0fw*yI41=XNewYg zTiOr=GhLsL}Bk>U{H zw7U&KXs=6wM3_U8b15(c+0AF0?Ycy!L!i?dHv|#BI0X{X4!O=H!4Ty5oD@hTJcK(` zGm-PyJWBx`K@UAGehQ*Fj??A&*^vJj|FC;@YViUD(&cfm1DhvU6QfgMz@L%Pfh$>W z=V-4*Z^^7W6mp9h2j#)4Y4&1;P!MhP-FosrdVBs_vlqrD+b_ff`wH`k_7jks9s z!=uj8)(PQ;1bn*o{nux%An!=WFZtew@(CLN8R2tSZ+{G83df)>Ll`fBgf7O=ssVno zL((^HEgsxB!+`S0-3TNJU|#|)tkKsuCbUC*(yM1mrmAKtzv&RqB7kMUIFE?(YZSvOP|`8-R<^oyY5rlx~s;qL*SXGhuA_MkGWpUR zhnlTJU^VU&RY3@ek4gJ%UxJxH3Y*sVS+K%D zM6zHwvCN(*Fht8C7Hv5&aX=Of&zIQ&fgxsgj{z&n2g6-vc9FmkIo}=wHYpzrADh{e z1cvyzbqv_#d@!7IW=|GaF$V1{`o;Mmc=XIJ7RVH$@n%7$D> zFq_J4GqcTTo=PgKB&Cv6Y{#mxW|qXaXU6G`-Z&+Y{(Fwp9z)k0O|2d;{Gk@OnT!^e3E%YjhRu!gj(dm_!OAch5K*nW3#u3nl>3j@`Um*T0h(CqPPR3N|eQ3Nu z#%Dpsr*PfroiV1C2?Cjr1(}e-g{SwZct4BoM1f4qf=o=|%G3LcF(3hf1hOE36fQlz zQgm{)6bYm#3sRKAwa1ueav+lgGARo(Db+DK7RzN%R`%p<_T*GYaco&GyI9%9+3ey} z$CQ|Yvw5_bqU?s;|r{=nCYE>}XXH!$rc@n$P9CrX%+qbu;${iluZkKbKB@a;j z@zWJa%nd#X`@yL?6?|fl)P~VPEt`+q|F`=qck#Im*nTcf{wTBwD(+;G zb<%}{zu?c7Dm<`;2j1YXnT=aR7rW2;_71#*#!)nwU?-zB)Zjkpdz_S_R}-B`fcDUQ z4+MZk_>r}SF3E!!Cx~bs1WSe1P-7kho?`8xraTC?cUnWuc@PGhmOO}nATG^=kXvEs zGWS`b1s0Q(f4Tdl@ZMYWs_*ec=j8XR;R0*Ts|ZK0*3g2yidcKJhZbfa-b~^QO@*C~ zImM7zG!=i&7&5WU9YhOzW<cBLwt!e-v}!tW4gwqB{Opgu9DBX+pJ*o?9)Wu;>vkR=0>g; z^t+7&+zPmj1l%fi8-?f^<1cBKSV-=T7(Nt~M`{q-2Q29hR89R5I#^;7$)zWDeeC%v zGnFv{9*2}cXz29pbn&j29Dc(8zlNh?CX`f7pksw+qG42Mz6XL|$sl;b@wX2`$dObo z$o0uu>Wwm?&ZEHy0fdU?##pFUdhx;78L-A2&9ghrRQraRV*lW1f_({M)@p)PJ)R=m z$K*=qL?ff-uFmLK|0F(KM{cRnfwR5Ps31f9AaqAJfb` zxE1Q1wY-nDe8GgIe~#!?-B{rI=W?FMU)|_;qjND=%n4LC26)9FHmA6{v6$ClyD?ci zbHwP|Z!i|1h!l`09=%Y_x|(QDzBaXCIR1y>RC6#giuzq+F0UyimW!4aEpBZ_SIW)n z&{d~W%G?vuwe0_AbQRaZRy9>z=a%r#5Cu3uX8RrhmAmu z&cS$aQDOWT{-1MEO@8a8Vmr8KT>Kb*qI1zkbnHvDU^ckOA3ugaDFHr>XNXd<7+f?y zehk0Ux#%1cNJ_<6aM6VLG5k~KqGreyN2%BeE}9rWh9B$PiE>}3+erz;kKyY&HxT=T zQm_hKR1`mkFYMeRE_NgZW57j|;>YlnojWOZiBhluTr@d;3}4#0lVeJVoVLuIV|)q(ocDYw2aewGs_r;u~^&4+_mYeT09DyCOYi+kE*0< zK*Tz`w0(2?UPv<-qMxwq6^9PJ08@s{MR2XgrYDySYuAeo{J}r-9e&95bU8v`a-`qc zg>ShJfbgv1Xe? zYfW3dZ5TBQF0Byqwxzq(FyCR*Mk;l8um5)6>t-`o-BHQ0KlMlOQ?UJk==&IIkMMCUR5zMq%F5S%kn zdn?g-DEHD8GPN-j=LEFF5}g-_-I7UVIL;~39!qpyQS6#bDnoM4B<-?9=S_+&&7?9c z=SnWDXx=)5VhX_-`p=o}?Y^>J!-a2g^X zdnwF~zkkOh234YIG84%d=Ehs5BVdiiCOtEGDSbksiCA|QJ~MeK-JfV0pGnV5UP>=a zG>yxoziaXu96>gC3e-=aTfs8f_m-x|KcKT{XGY9fw8!A#HfHy(AbhaGx$Sn#J6-q5 z@vqBeB@74ZP!X)|L`P`%N(MCseYjAQ)$)9N{^RUfMmYW7U z;nDN3#ul^Kik+h$*k7l_N2kV4(GM)HQ{$t-9##a=^VkWO1K;woD(6ax1B|Qe+AJP+ zpI;Y^yp9jwWaq(ItK6B7U>hSCn7qRMvl9N9xZ?}D!8qa1H_GgMqs-3NIPXGS)R{n$ zIHmVg%lo`ZdolkCSqbhOf8{9MP!V}O>7V8LXU4btabT#pL904$Ui9rB>f7Qz&05ac zdg*Y&NiFiFZaFaYu-TUY8~K^13yJo)%Dv{;&^?w*JpOp)2jY)+&L7Jkj`(A}!rEG- z;B!8;Qe1+p>B_J}{1rzWGjqRKCnK;VMRl|q!Ige+7sotbcSm9mz$BGWVlM0dNxrRODAmMStT*Dskj5pjc*RaMr6AU-ZHLQVugt%d@VGSH4 z#0_%|Yv3UvZkTIW0~ZN#!(77}_(+Hw<{H+(NkZH(*RTd&65@urhBe-C3^&XbYn+H1 zrgLHKFsJj{Sz37^!pzdDqu4b|t6V2TPeXqQ+z(OP&6sp<+Yif#zKq8hRK~i@bf60W z3uLf019HX8V~|`o80y?ZZb-JdW|GjxP#deNFa^Vu(}KLld+Nro0^cxW&3%sKI{n0L zz(nO6O8Y@HRX$gi+zdW3GPU$XBejBU_J-sTy8b_Dm6r2KgeRTuxGs< zzMd5zup)ys&rI+ci>pq!Syo|26|N$Q^-<;K$H!G~{P#zbbpf|-l6+AQ-0&9ks7TdJ z@(m1jF;^46+773ouXuV;-e@xzIK7_%Zs-M#qsujp&gU}~pzYkcn2h+oqmkF4U1k1A zs=VQVM$upx06Sj1!Gh7QqHyTPGW)ZAF`Qc9OWkyUqi;(04SnNX^49bxT_+3T)J)T| zdi@Gc0sfJm%#g<@OqMWK#%5=HP|kEHCqB}#`zd0&)ARYNFrgdTNFCF;{5HL6q;Vx3 zz3%#K$4Y)xIu90PPONyHORzc(%#uP5t^o1gUB~cFMQ2&|wtKi0u4Os3(?*LDo#4(c z_s#gr3OiL9*_*5hx;4|{+x(o$fy~l^e7nWnzCG%N!R3(L$SF@AE&HD2(WlNc^61Xw zy~gsu9dessHEc}1dVDUlg-86IpmUod^tfre)+%>;Z{a70Z&PhL7gZVWFXtOIALRJ1 zq$lprn(umzO#?(~UAw%3ruD#ui54ZYONYHPbf-SVPex|BAIU90hvdPP_i$ken$HEgNZ1o$t^;uwekfL z!g9Nib;Rg>9wy{q`w68Qf@GAl^GisHFZLI0oAZV?i^JFtLUyw_+`G-`UCpQF43a>) zfCIao-geU13ik1TD!ak7hW+4){4b)3l`~SE<*9|`IBc0XBh>#S-dcetoZer7wcNCR z&XclD+De8l6l_-O6x6W>4p?I*FXS3LSRMqHZV-ElYt;d~SC;c`I-+;Imdm|{$TT`A zlap^hEi3VeLC^T!0MzK?K!nmaJw^#$2J57D!DsMoc|^i9?0Wq0@=*aKi?NoCFVJbN z-8ZO?Fq*N2@NEOx5SAvWpLI_`u?kYIvP!Da;b{rn)OvN31?kgBTO2=pQlfL3)2paq zq@6_ClKA116P+hveFhiOP9|+>{BTL4^JJ$tZPQ9fYmXm3CDB;|?QGg9q%Dgdo}TDD z#p&(0Y12vTh#x*R(TQ14H-}Q+sibwr50@r7Pjz|~qnxx-(z@b@PfK)`I=#I%?KIM^ zh#x*Z(RmstF>TuEq4s7=}zx*n|20iSH=&QB|6V=dRuH-8EMPohtEuOmN~sO zHtkH(J`z8CR-*Gvr?=duokiMJz5R*Kvz*>3CaGx#4n9{Wnr95Yqva?&HH73hK0izp z4ZZ}|#dla|fM#+U3KNTYbXY%t=0Z}&B^LAOur2`2<4Ex*7W3$^JO9ntaT^ripA@^{ z-;5!*VM1atj}E)f-;5=i=Z5{r3s*j@c*G`EJL#9|&Db~C>jV{XHw z#9|&Db`QT9dv3$z#9|&DcI&jCS^)uF^>+rQQyphy+r zKi`Z4N`sSF%%j6@%5xZZu`~D$?YZA?;}cqayyx4JZ>jft^6gG5->mT*F(>&Z@7deF z&v130MZt1XhR zE0|m4@k85r;1SfqiRB22nmCv2 zJ&{@@DOWK^t}vCx&jmppo@2+SEaVp>c8d0V$Ot)XqqxHWW;|og-eaX1f`rrxn_79c zd`&Cn+-ar+RagO3*k)Gr;?cN9c+>JM$Tms?V1(NuG7)MHGmEAaUMFT{4ax!M{kV&^NNm4xN-kuwt=WwA4ruz-Y*#7AZ%I?n82EZ}&^puZ}?*)fD_DmuPA zI}6x#$5wwJ;h!|POY2hPwew)WveGJd(tkkq0$NJe(DUB-fVVW~!VUqm%CeJzdc|ck z!m@5K$AHD@Yk$m)K)U^`@jWs6$E%Tk*BeO82r-xsjw~h)h9-o!+ymYyOO^P1BZI;0 zsyXw0siV131m%9D7g)8TU1O|D_O1V z7AUKjliXw>f)`C8YXKVyN}j^mZjz@0xqz&xWG&=K-BYiTKNi<#D{m2ZO2k5__SUxbh&X`ie+R zAz%o;sI%?vp|`#Z^Xhsl>6l`OHLf|Xk3v)efb=E1MiS$}Uo4Db5@~GVrOkyve*%a_ z7WZ3EavrQ*g9;}#JI3^c|5S=sN{xavX5Y;Ca z9W&)#tiIhZ!-o8l`@Z__PR+C-zhg-o)0N<|f~A;QCB?9w5(SYICw?~7CX@GZZ2Aab>8}yo)73ks*~us%1qB$dBxgqYNEtZ#?UL! z1*g2cd!u4c4gDqqXXW`vM7|Tt^Z8`ufw7JuuQDq{C}jdyHfF8^QaV%dOxh`VR%c=N=GxWYv?{|m3#;5I?&-ND|wH33y$B-&>`_e!-_wM$&UwVx< z_rRW4-ABwAdw$@h8Q@V~^t8d01)#x}H7o@Q$L~|AJ+B`61wa*>U!w3!?gRUH$nO!$ z4e~_lqvm$^5g88M)ZO~K$9>=)p49H#d(5|Izx$=T_*rzA0+oEBg2FWvEVtG39f%n= zU#YcU+1a>)0(@p?<4V2kY+P+0YxJOa9mQ*?F3h)U-PGrl`lSSaoqM0~?HP1;gK-N1 zT;vOKK&`}ZKoJ=av=3Lu2Wuzm@}37anL@{W5WLRa1x(m|q?a_XW(Q8V^>lMK2lzuT zlH0cVWinrK8#hLdP*ID!EEbV5rPjSk?iF?JVMCi1^RblF7T#Li)SdP%s`IlT(O#`p z1IPE>lr&0UDo9=K_Nh04X)~zEcDu&yGdxTgQ?nd6R!}%)Dc)DWV2C{JKH}#|Kh#iC z)`aENxWGn+)qT`c;yz-IxXN;#(%pxV=Q8yG7jz#8sx zd7eEj@|62PjV%-7izV&@b@tbW$a8%CfqMIErHJo7(q;>aY$_PFnHz;>7w=R+gIbho zjdr%iRtvT|@)XqJ3+?=l>~i~-^RzN3Ss-`U!q^8=@h&G%<^)eDb8eJ4D$arJnsP!g z=Bd<8z8`#RM`Kp<_TGl88}r<%ofDbkUoDL9EF4@%lJ#Gbr@Q=LT8fjmOX%%v4uchs z8vCfVk2>?XT|UP4ZMF9X2V+keW_<%Ev~U4{%#c*)>};+VB>5Go<`q23Q_b}|o1><9 zbBlendLUd*BDV&#&KBfDJv|n6_w%b>6R$V_5bXvHCB7pVZmeey@<6z;fybNS#`!$n z3O8QD#jg34Gh8vrB911r!^B4&?w(vL{ZoHJok#OT>JpL4Jyqw3;aAPZv zcfyS*(M`v~jSG2UVm7noISEo1;o)2l0Vi>iBSTqf*&%_QHdJLj8nrbCXipZB}dyuilB_=4Pb^V(Yz> zK)AU@DMhi5dnrZX=1Y}gcbHYzq;T_PN|_vM@L(o~n=e-in~h#dak#lvDN|x+dMQ)F z%?p%bStJS~PEg9nHlBJDR5y@aY}RQ+aiKLz}Gvm(i#4;$11$m0ZM|!pS={ z3X>f*uuw4BB#$%Quu_t|Lu$z6CL)N-KBbV*=!L=R z!9C{6zR{kkL+8r>+@cYiF3-6AtiG3x62+=sPBQzPo_)ZUxTc^9sA8gSnRN+jOR8yw zMnkHp-pvdKxS!Bk#2vD?ZV?Ep_ar{5TlKV=VjUqpUpcPo|kJc{DZu+-`T3I@EN?b-MK(J;V1LXZs$UVxV8Zs z*#}?b{#aB*UoXEZ(vRb(XTO0EI5MxGbMWu3cV)XbJAFZOR6ICyXKadZ`{3JIy*)BY zxC_LYJ#Y3+((OrA*}Ii)<#9iJ&<4-T`K2rQd9h#eL9v7wA^CZ+FK^|^&x;*+3r8Lw z*I9e=qB_pl-Kcwe^J3CiK6T>n(*d9F8&+6Um;Ag$x7%6EHZ_VxY=dTRoo#s$1wFZ* z;nS*!n-6XPD!D%Dex;WeZ^XC{8t0q!EzaZK;Bg<^WU`GQ-rl1t|AO*y1aa9_0C2yRPGuo7JVSda(I)oIqi8-I6eGgw-u^ z+rwD3FCegPDX$!*PEI!Pto_iLbP7fmWw zzW4Fk&D-@W^`!#ts24R{GrH~B+mg)?)l`;g|Ltcp_ffPRFJ?JNz(DbrbWK#q>D`VG zt@_Q9Mylg-d__bBjpiu3{YWJ=ShkY&{mkZ zbGEJPB|uZx``thCJ?iNg$FsDm^JGS3i43V(z=r@7Olt9X)d;A+sYyl<_rNUum|! zBCozcRcEQdWQfhyrw}@+>nCOFE3);SCP0~Gv-Rx)(Be1Qt8Y?O=jj5Ii8fo`H%xuS z+4?5i`pyub47OfS>>D|SWd`l;D^rr3JU6p+lgnR?`s-X0&o zSj%Qx=UK{@88=hMDatn6Zk;nQ<$5dw=ar!lXp~p*Ug6#@>T5pmCM~0b`_aK&>`%|- zM0E}%eq^6>`@>uUF!(fotRRm4I~A4^%7i+NQp9XWiWprIi(vpZmDnFiEJ4R2r4)T@ zeeqxk8x6)D2^&{%d05|{RP#exi`aST`1y_@>dkk^uk4)1Oy|vcq3oPjlRxL_?%2FJ z4|`txx6B=G-b`nP_2)JJX`cJFhL$(WeEI*#oLA}1d11OvbDp9S7>B|kuwq~I9{7QnBIRO8&oP&m$9|7EF(T7P5?1`F}-p=Ax{FN(yJoA0~sMv zQfl^Odausb!dA;NgoY79R*aOIy_sGuw#k#&$kl>mkN_z)doqtxu#^vb|*Yhf#983MwqMIxir?A`Rhf;}$*dmJq+ce9Hv!x{(N+lX%VbUcE za-|vd5(=df3NgG3mNE9dkDi4fVD=~-r)7a=D<=5khk8b_3Y%F?ij^3UFD&Os%u{e! zm)?gad*hJADl{qL{cbmF0i#u^-uN3#G)95qS67v^E?ntRtlCCk#P21`S zb*|A(N8O_CT29O zoD`794SZpwK<^O(nSn@b;MI)wBEt<6+H8=oUe{)R&khB#O#Roz69@P-WmKl z2x#GuS#L-7niY3HkZnmMGw63EH=Ef7awj*NRn~UyenUP9ad%`~L+#0n>u^uG@uV@c zjNNC8D;}ELP|NKoDzUhZLZRelGtUsVVIy6iY~WxC$?BO9t80!QFynAwtyMZQrmp2f zIy1kVl=E5F__VGGX&|x~Cq0CW&#Y?fxs}A7bIgk732C(4j7Zto&4$7TiQHtabv|Ac znqID{PcCi+6ZhNF-;&ov-7lCmT|+$>7P#LwYr1P%oLxH`jCIcawpr6Pv?_b2X^(kp zutqyDH1iv+VwHU31?KAzpJo=PHtQ3-1yT(wc=%Hd(l-FnS^}V*lvZT~=Qb;;@9-`% z2o9dKrRv;6hCDKzE_V-l{YNFTL?Z1yi>~FPCQ=(ahr7LJiD;`x_Xa0(az@Rk z(Hf%u(Jz=~ySg2G=}NF@D7IlHDh3|}HL+!U1a(X2j0Yd$4-xj*e3dOlt0C&*zt$oe zs_nE=qrDhZ)j*QWqS>cwrz_3YK&}16@k9spVhVE}-^7UHuQ2}^-xKDX>S%Y1<#_lm z+=0|rj>8>+72@jPehC}9sznhksA>o%CM0^N8SbLdItigMi5mX64dUnCP7&I6}}^fKY0KWEbD6A6M0IvJUJtjq^U} z^nN`9)HdD&@>eyK=}feQrWk!*reK zX`+1|PTFy{HAx8;(8Q{SQ+2qfX=1h}83+teTagD8sA?$HIiIFLwx(AskAl-A52&cB z;WQojX)4OrK{XM>uGy;@>d*c#;MuNtOQHJqtqLL6hYT^lpgO1z&~z#hodss_R*>N1W@ z9jACXPF2GUF7EJ3k|?iP4Uy2`B80nC4lIN9wQJ&A2JYQUw{DLu+WdwWQUhuBt;}DsqXCyk~K=Qo7 z%JZveO`E$1vDIay`Xu7bTDe|{3}>q4SDR6=I;@cj^;v?vs(qra50G$QHrn$uYN_k% zXViA7G~{UGyqoRZI`=pU|9?)t*Bvk4WrYqwg+C+TD~)^)AzaN?QAWPY(kI#eM^VL< z@>xTl)1MVI&{&R0sP6+7t)velD?LKIThh~sgWu&FtF{=q{!fzY z_wk1UHH3BJY9cf{ce{jfj_EsA^Bh;}@Ng?sZ6a;4%Uo zi~ur1UhykE>0XzT>t0r%+nS7!$9uZhlkU`n6JJ)K+nS7!SAFNt%B(=QH5nm~ zk9Dsn-Khx&zpOyFH5nnV7?_@PrzX~wS%GeAGD03t>|Rg0Qxnd9S%GeAGD2QaGR2h; zm6}*vW(B&f$q0G;wavjW1GE7Lz^p*GH5nm4f3lJ8)WRAwE6{B%M#wi88|e-%I0I${ zx~;(o`T0|fbgwhg9gvJbw{;jH-)xQvaw-t5Im;6g@?r|4yB1P)gG(ixt$jyBCCBP6 zZ2srud)>R`yIhTC|D9Zo79A>)DeHc|y+V6r9W}}C8RMea6wB-mwwoEIBH2-wY^v4Q zy$m)wtgA(7@;2%Cj*V~rWuvGwtDHevYT=61ZAN$1(sQAd(HeIzv1(r`=@%_of1Ofh=T7)SjN4P^2h$7H;V=+E!>Pk2KXMn?jMM zD3{zsnp(IyCeqYO?n6S`-^K7aG`oMtujtClzzy3N@eFC|n!{ z!}qLpP;mr3M#`+;#19|%wD{rTKN^1co#+cs$TSd8gL#^UgJ}8@L}L6{@FC4*^i>Vk z1*d5T$Kuw_iyS20XgTplb>6cqbB>4ONfE`3$|N}tM(*KcV3pb9jXgW`pB_5Ir|-E0 z7q*^rbzb$~i5+?{t}BxwZe4LXz zeQJphYhL0qY#$9n-yPdtT03WhTD$md)7sZk@jmZL^-erFAgF(*KXea0l|Fl|E*Euo z#ALq+X%ewaS1zFRB`-kAm6(RjjjeR(k3Jw`Elt0;Ue&+(mZ?5%tIw2F4_(b?L{fbN zMoOQ4y{U)`Vh3kY!Mh^F{P~1sOFKH_ueH->ikGt{Ig4mK-0+vYx|naMm-MZYf`alg zo}~o^_3GBLf`S!ND#{BAHpxkp#p7LTc(Nha-@+3!(!O?{Vy2gP;VLr# zWn_hhaXsa~z%xqu6i=42{om%v8h76Vs1OVgt*`>_@=)=>P|4=s4pU)r%~}3r$yv$P zvx<|;&k98Pf1)_O+L=E1^_t$`XZ>}d;p*iR0@bY( zimOW|RIi!fU$mj>y`lT}`Hur1x?B3K^HXHX6V8(&n0s}xyC{H1gF7q!So_siUCA9M z8G0`F=qcx?)=vsF&zjd6odz^J})PAlK z{A}?oXWg51&i>*T768R_Iy=Mrw{57V7Qs>^Q(2}Ib$Uf?iK)O3{WEg>zgFY~*o>`r zI`sln?%ezY`0^NVZhjJ;eFCn1(pfK#g|_x0eH@2%bARk<8=XkPc*ResmM0OWD&)se40P5KYOY31{sk z{J(M&_Qym?D7o~j&RYGyb_<6#H>oMkEi;_8e{$A6qYdChd&rkudXKaA@_U?hhw7ZQ zAG^yL+UeZVnQ+$a1#~Ul@<->EMoK=*&yN(?GKI;d5AmUgoOK5&bLD-`&~wf$i|99c z>y}RhowY}uTb5D9&-wYOfGsmFxpWt}?6Tjvw%-|g8kD|jQM$U+S<6YQ1yu12Wj-FX zW&FvdFM!(%_B$Wj?F{Vzx4S&t%AK|EfE!g9+)8bk@yVrWa7)|oT)EE~dLG>F@o=kf z*1ipHRAF!{w`C?ImyUqji2csB!_LrC;C7#fTUhkEWdT(f+$wCDiOHo9=kkF4&igFc z9`aDDwPd3PgId@Y2_%=&&Pz%?vIQ;K`aRU@E!n8TpjKS1uFWZNKxe6_##k4>z*JZd74# zTVcygO)lL4ZW}zhbz8a(d$@I5x>1F}ZM7|fM1Y?SkBxW;QHOYpat5JpQ=K@faRk;T zH=OJWB-@I&R4*>Bz9Qi4kEAXQx?f|<4-s|C{h^=+-{-jI4FA>sfo*}rZg+c#u;fT6 z{dD#}?(E;|tljt+1K|G0wlF#qyPcaEYR?CpwZCz9I_sVT=tqp`f&wPXb#K)Yi^$mz zyeVyqIQ#$P?7#mtjpnMdN>y;!+4{>&9oxM+j^@?D_a7^{s_?`W9W@md*Clo*@3aj8 zp{N^2W&i*%r)?>vB-=oU^0&dR!10v63{=bZ#2=y268a8;9{BObQO@mkQU&afv zm8k#!GI|FLdj9_{=nWh6{)%4xEAaYn=}yR|;qq6Y_uta1e+6FuE!_#(ivK#YjqO!L zh7mZ3j64A%!GT0tcfc&g;L8vSo z=d2qpcJ?DNpD#x)aH?CvPsF35>kkH;>z@fYLvNw!bRRs!`RRu~XA~5t?}yrj^pqBE z-R%lEw}g{-8@0t*Z7-3flQoZq{=maEbKcQhE>XjH+Y`TNgWA4vaYzne8e8G3Me zrtkj%gJs&r(>5+X6y$y!n{yVaH$tu2f?w;;ANl!7TCSey{taYZdyF5yN!>`=+~}Lo zXm0d~>G59|IKd^sE%BjpE~saE9V#7~e&Thy*FhrY{(W1HC*&(ZXzq0GFx2mSn(xm8 z?gbC6{cu!m!8@eDR%?Gn&;LqXB0e=t0h%DqkEboF@6Bhz-U+I0e}?0_|5HugmtnB~ zv|mw^)mVO+tmBz*ZuHj$P)MY>-C<2Pror!SuWjiLrxTpbXrhhp-Msg1(VuBYt_klk za{7Mh^xZ276+8(_pXK$xdOgeY-7jlY{a-cOJ?6I}FKcgdrcNoIJgF!!al&~2xI$k6 z%$Wag+ljd{ms(J;&DT4wsW33{i3y+cFB~77y4SgLN=I>N(TjnvO}c7wdD+Wn-aTX0 zSruozdiuSk*PRwV>CKbxpLS!g_LL(fKbn5?sr9wD&Ux%Z6Xv#D{MmUwtDAaJ+lBvQ z_RlYvUegu%hw!he&Z=G!`sVw8_knZIUH!iAoby`w`Db^Z_k$0N${ z`a;9$^~>jf{gQp{=PX;<`9C|-OV3-frtN!+hd*3(W$cQrT_YcvyL{tSKfb!)rEU9q zUvBzs;P+4b;d8Gn{9SPW-Z$=it>g95^oxUE8@lS%@^@Z7diSwaqZLP9{nNdNuNw)! z_2!%R58rs8_U$8o{L!JC57z(U))yXoal$WKe)HM?{MoOk{;KWy|MA?#+@Wk7@E_{5$&mMmA=+pC_+Vq9_Tm1iH z#}^Y{zU(W-UwZ1!E&tDwua|u7xqtfVS3mssW&ik_f4D34(a(kM`2FYa`Rpf?mF^pf z`{Fm;TC?fk=7)Me(^q%!q9 zcfC2FCM%)+y{X$i?^{Oi{t zJ^t-`pt+@CX-oO4wKtS+sJ*bV{E{VCw6!m4ZdkCi{G*>Pulw8X?i<$DukHT$b?erx zIe+a9pO{y0+`Tp^Q5=LYaS2W0NNPjSw<}dL2cMx*Jof_qhbJalL!4%5aZ)u!>@=<cw_LO?w@Hkw){kAY)< zs(aGA;Mm$~DH;REj#zi#U2trswJ1tX?z`;4bt^#R*zdA^*D`(#9J_wq{&&H#Vc0Tm z3>+RL-G%Rh!}+8|vE*~#g-~IEDT=}j-$9yObRfR(_JqPCg}6cvl9v*UhZqQVYS&kB z|F#?2yK76vHP>NBw*ewoZ6Pe~xD8%{JCZvWq%vINxWvz4e&6oY7yl8Xz1v*Mm0#GK zi?4^5v>QWjb39EBjOpKY%6cE0AJw$<5GXyY~g zvkrEzn{Y>PdjDPri177xuM4>HpIPBHNp)T6HU)Wf5%oCLRA%B?vOQ?RbiuWhes8Gb{qDwLpM8jLQ;j&^(h5wOb%SUjFHcwh!j= z&m$iK-e=eWQP@;`t zm?@9kX@LTn^5mbBXk!>=@{v3(XOo{JNqM3T`IF_6up!CCmLwNLlJIdPnP*6{C|Bh| zs)Pc0pR7x?Ey(4!k`D#)^5-VnF3;s(M*bKuHaoj^ zKQBLC!gt8iOngt5X5#*zo0)i@H-+*|9i{i?PEFeBEsMMj`T5L`^{&~F*V#_Fh-=D} zhi@^@8lLhFk(Y=+J&CWN2uugla&6XMZOjLegF|n~j6f}sgKFR%-pA5UEF}EU-pu~$ zvWGJILZQL(bc^L<*c*(#fZqc5guUVPy$@1m)P+&iHINqpYw9Z3G12P02v}1Se&h1P zDG|AUb-Bdw#$&GUar1MzJKu!8HNBHuh7(V0sZdlfht$6t%?H=zWTUhn7gc8i7=sVj zHMsNZoZf!}EO}E&vZpT9>2r6ohd}_abxo1SN3e84t!)s~(cO>n5U{>4-u`^L}?+uO%q$~gF%Tu&6|zOf+n8Ln^iB?=$4O59)+E5p0vD)o?R>Ytk0;ETWNOWo*81O}HW z)v}+p58Cr_TQH6$sF@H;n|P$=>r6#yd}OL~`&&9l)*Jd9$vBaiTUqvzl)9<@$5P-j zA+ml&TBf^|?;cP!yq1H!vakknT|075)&AXHbA57_Q2z*;FCf2O;w3U^18vDFeP=S6md-8IVjU}PJqpHyn4NxfF7e`8YDDD`}k`YEN( zifm(j5C;CbhXb~SYn9&V4#f9etgEPAn&|GtF_TkUvMq1jSoevUPw=G~p1atwXMXP< zaJI($s}c)tarZnk>JIC|s~OMia|enJCl=g{?=b!P%rTQndH=`V5oId1=s;q@O*+>X z^RIkn)Ihky*-T1rROUwi$GqZWOa7fL`Oy=W{ERL6wsvk=*s$;t8 zEPkKU>R)X{k+byxDaYIcfd#i9mby&GipDf+@TzbP(jC76XkgY}Ok;f@iqU#}iTs|{njJ!0F*S6zo zzvoqx9eabgWW(vcH#Dgdn1BvV2ID(}$<_Yqj<)LS+TD&e_qz6EOCVWaT)nWXx@oz) zkhSb`K3Se@9_A5FHoqMq_!+M?$>x#B8Y5R~lg&pX_LPnUR(V8%t4S+*P37{vGi%`K z{0K*yj5LZgt>jm2q-iyex=7O+Y&Jn(oVJJ(B{a9px%~|K)VcLpnH@Y5IPr<3WeC@+ z`DbX7=oIN!=O>%WQfokRVL385O#39T@qi;JRZ|4u)3+Mdf{^2dn^&#)a8xH%NIcsNH={}rEt7b+N|%B_ z#XF)U;Z2Z2jc0At+Z7Z&NsW@3e41w_` z$~oaMAxSVr&~xw%64Vw;#psr0osm(+FTD%nNH_etF}bWIxuA964L>t=g*)tfj%WR} zr_nvQ$tb3CQ8n`Jzg^Rx;ob_%y_Ilp)VWOu18H9jE^GtiR?{BwU!}W)G23_WMEtkI z@}IH||E1I8U$gvorm8di*Wyq1Y^Yw=UA-XYF6(yri+gI48wu;>6jw{=GO`;tf?pls z?~?0>lZ)O?c8-8Ui#YFrO>}T1rHM9TLh%uBOabL;2`E<=vBy+e&6%+_D()hro2FPo zB4#*LGp*rJX3)lN8ngj!+z_OX+LDbi9_`7-4LrJ%1mB}1xfPnJ+u+yA0=JOYc9#oX zJZ(^RA#`y=?_iei$NoXO1q(IzV7WwG$4(Kpsn(jRL$4bJ&6WRE7*9} z(a_SW`MSL)(ZJz^M?JXqs`zoqva0#I!zarXhny;&T5)GU* zxZNw;Sv6lb`Xm}A#@4G`SJnK0Zewk*7qEq{5Pntjb+=EVp(wUgFdwd(uj_ph4fX=I z(3KWOxBMg;?A0!zx z(imbvJm!e0J^M9>XV6+5E-woSaW zMfx^Th`07gpV*eSu1KHJYN^(;?BJ_9!g5nkBl0?CEwt3Vdj`3FnX#);$hn$r1f1+S zOcz&(o!oT#J89syMfw%o;K!PE&3EYkvSg!HTBTwG?YK6!*b^;5I|#J$k}4^2y@97# zIp&IAf`c7G1BDT{?tTooV`8!DvkJsJGWaL>((32;f#3=x&YEOLi)e=dB8gMu+-45q5(*fJQx95oW9MTbZRS5tUjA3+zdu;{ zb81%pX#VT2zAol=bi3EZGV|Yt>ZXnE!VNBeCA7`_S8wM(ArrOpUzArPg%oVl3dLGv zM5`_-wFDL6jdbY{S#{32p3xPBrY(G-`nvAwg|X_64UyZlZUMG7@;z~fDvR9VamVV& zm&F~3uNH*Q>LBE+H&RIVwzi}GE3#?SZQ(Z8Vk4CJlB7?KbNh4o(kJZ1cUbAOl45Jn zK6*4Q5lxASyvdV19g;jIvhxiuipJDKxtJu6Eff2hooMU9hoc(Z=I}<$9NySq4sUGK z?60X!lBdZ?9?fq0rg)cyM**vcdR;-s>7i@Y5%jVKU_(_iH`D2Y_|*w6kFZzQd3p1z znhWDcbSpf02%ze`a+g#!k7K^Jc?crYxn8+wRWs`|-TzKGztj6CD9I1=y~e8M@$nj?h5nb;x zNTeM$BJEs;gxF%`ar=WA`6l5(E~@JjzsWK?f40z%<3AWQU-SkXxlMW8A4TTT7i(Ebt`$$+|@ivlTB-&Q^2j1wppgGP*c-i zdbvnTq{{5MD6>`?dJX+h+TlI`Yr#95T0LrR{QR|WZbr?DB|A4H7j;+PF2Pj&pnA3X zE9%ke=GyAdZ_>;9aCN6F3uV=dDwEC9HV9{y#W`qjmIhK28a*}HY;kV3I5%6In-!$C z#zVMPr;+L-dpV7C4yTc(W^7$1P1kzT#;1=xlRb~*tru&(^+e^SukPHC7=?!;G66-Rt_exz~9%<3&fSiIp+vtC~Mb%#lQ+?se6A4M^f4I=B5D zXiC^qR7Zw&imjIU`B~EHho7D6O2d0BPvl7ceIjD~(}URZJQ~^nzk85QuNr za)8rghn@Aes>$y2sfJ-9X{PFfoZzkDKes9naL0X;dsfHXc`rMF@a0Nd@HFUpsKPa~ zsViLNkMzCHOHINbAr=dB2lLHro%sz{MI$~==$cGko!(2lT3zSK zJI>4HT2#F%mzl>?qi1W6US+u&Rj#Rk_SQKlO6u2cWXtl&Dwb zGXMOmmpjqR<(gEzDwi2Z23gfCYqZL8RjOW<8;JENr^w6Ux>UU?r$})^qq8TO^V2HD zrKwz{T4mMf*<6Se;lfm|QLVD~7|-THqzIR#a)oM@RikHfAyR~kQn^00%HCr3Dt%#2RoQaU8HKE3(a@aX6*H!A+wa(7p5Ujv4ygJGrMa-196 zWXfOf>*rTxvQcVQeX`LH44etNje7VIy!Bux%_aTuir0j#4%>y<_Af|9Ylq|eiw5?O zbGHFoi*W!6c4&9Xub<_)`GG^x( z{qgj}ra$hdm@Eq`}TD$`^|Y06Nm6`ztHm-BxihepW4JxN1K8g;gpdd#`kNdv;fY z-&g8{-}fK#_(PT_DgH6Ke%ZwM%OmddGxxLPyF+49dZ5G>@uJmp>49`9I|Oxl;aaJU7kXi&2=xCR9SV_C2 z2bLHPu~b<>n)*5jb<$@`nauENGTsaG38lf+vZG}_DRMHK34Sr(Be|Bk>)Z**xPZ%b zuON{5x`65|0{W0NAc|}5jOjb(5O#*HN_fxyZvK#we-C=} zBlDcwchh3-Dz?)Pn8n}sm8R@X*gLzGeH(tQr0g{SHBg{3sa8D=L@k$@u_kwq z4Sj_8I%wX=yApDB%}60$w(do&klzf+Vxf zcd%&Kpbt8=?lI@KDewZgYj!011*&8qt=X4hc)ct&499x|a=Oqm5Fr3?(h@{I>y(0@TW#BA036 zm)1}g8FA+yMYwh=LRbqRtxn%z`oaWhH|7gZZ^tx8XY}eiDFbdh=k{;$+u&n)AjrFT zK*tg6T9OHpS{1rciz(q+qK+VlhHv2T3}64|mkdeGO&+!p?vntBpw8WUeD2e}z5HBV zw3}K=si8DEt-2u)QS1o<(5c&7B5(2|np|8QIl@aTpIDJB)L%05={UM1Pz`l4Y-=e{ z$|WAHP&)`IN-%V{(Bs`16h#aIdw)AAL=x+8=T$^dD(csaW@^=T#b4X+4G&=EAq1a%D#kbZb?0v>`R>9 zxp~?6)`1n-C0ve5cGT%r%n_Pk(8Cvxd+NyM?$lGrZseX-E1yg@wg>L2Bb#efr<2`8 z2;02ufU=v(=0??1$!^9LnwO1VAPX3>xm;D#O-uGR2va$Jgxp(4HutQaM)svn@20%c zSc$p2j%==6J)P{!%xw^+WU;a?CySd`&mima*kzdp;mb(xlEnqAWn{IQ+aOFSTmiYe zjx6qBJ(H{jJtZoIrxOl<+_0F?^>xj0|#in_1+Nt^o%?PTc^@&sU2=W_-JI$^}4I~V=#FqhU zNOT$=6&##*K+J*o5%0ozOA0e^^AnwhQ3VGJKAr~$3le9^`|Kr&PQ$T+gBQP%2L~@M z(E)gaUNq5ZSXXc`r3s_teHW%&GCl*>nCLV-EI7DxabA6J=aLB-xTZv>VP?U>rZe;4 zVACaXi8bGCPIMZs799NQ%Y%bomjp6!Es0LU-hzX1<*J{d3yiy@C&s@e5~ zUH?SP`sZJbKK46iEi5ul?|>B%Tq|O4oJp6T_S)!95}7);Cnw;;HXoGHZ$`>k-T-tD zInuLyXczJRlNm<-q^>p;%-c-3<_Fk#!FbHN0ADIyE|`vP1sqg2X7mW007D$A$s3E7L&r&P!_4NNMoJih)XW~p^Af7i4wos6<* zRY$R!RBM()LW&Xn$LfQ}pVx$65PiDwAqZhg2x*JoJz{P8%-!siFZTJK9-1b-*4a7< z)19;R{F#G2lUYK}Inwi*mQ+`{yZFn|hc|8gqIa#qsLf)Op?8yuMe#SM(9^PEWBB%m zkkQh*^z^4s<|<5W-+{qYSBnv%LG7PTw~UOTKVRDKX|_LsMy7vvoi7UP`;MW&KCwGZ zsu9b78HmlJ=uoUaKFd2)siR^Dq;V_1hZyy@xmS%K2@@c4zJEiu?6GuOmL_8QE2B?Ax{<;HPg}{+=MWQT(b3Q;nlT zPkQuE7p86`{@0>oLtZ}_`Px~j_O89hYcDzqlYXs&DAwHA;%x0HaNq3R>%Q7Ed5B+C z?txy6-!go!0mywG63^Uk3UHLGWwhs4J77Gd-M~p^sFwLg%%YniSsNL3U&V6%($KHC zhv)_2*%3LoH2wSs_5JRLnS^FUM$BS(&zl?)g63b;0`_zPlxL+TtCg(+VA|h*Y{Oy4wfIx)Pw!a(4*Pl zbG60ivDCkdH6ccu%VKsBq02qz|@p=UUK|Dfsz&8zG+@^{_o zD@wb6WP`+3-199+)ea>pVE#!nce;m>6YZ`89js?M^M$*8@J8y~LQbW|+PA1m$bZ5< z{Wt3AjWS%=(;Lq@ss)%+XwC%J^zX_IeY3vns!wo&`JP~8QU>lv!0}$JZ++i> zBe2Ro^S_lY;XA_9v%yf6LGPcuA{il&kDlg@U!QG+!0GDkt-xCQ=vQWnf4=`OhJPNT zr`nMSZE|u*0g{S-igRWe@gj4-hb)~{nZ6c;r5s3{vVlMTV- zH6^L;w;uZLcfNDpp*P%N>f3X~eQxFsjnmZq7gU~JP;kw`2RLkqDfYT?&ZTe6+?`w; zO!?~v-YHDQZXGoxuQ|AudJnxZaBN1hp=8gInQy{Qe&4eX&*&RkoVq`}g<9O+z;&`jAa z{MYO??eISQ@M#zAI^8S6fwrFvyuzHrC*I)`0eAPqgWpV^KQrxa_oz&xwxyb$zP5iQ zd+boA@Xiq#aW)_O=Nas1-M$G7uig8$dp*Y6Q+(IF{`n#>Xb3+1iB+pssoJDJWNIEi z^Vx^D|NA$;U{ZYh-A@<)#7!g;zHRPy^4%Q+Mjp-~&)j`&f8ETTRO)`(KXcgi85V?p0>;Q~*qcm7se792N&9`9{ieeQ zC-F1Or-Vi{@b{l90_Wy)Dtb*r(POI&ALY2{1$u}<=I2q6W2JmPN?u=LS?T$iJ5%@1 zJ0TlgpJk)l#x^^67?@xtQ*n-81O@c9<69cn(8P$V{ZMUwS6D+?5Z0sft`TomV82PW=tc9ftu zop_X>X8oCAf{60QN${^9CkFe~GP?Rxy|$tK8*ZFA^1)*D^&Rr#aGxI7KZ9EicxBgV z^MD!VsMt(+@*fHr8;aTR`)5F?slp9N@LXkB2u(g&lii#^fp$YMjJlfnV>H7=LDE=n znPS=fpe#QO>XU;H2uAt}=YxdM2FgR?JGyzI|7^BU+T!!{mF!0h%7ZP=FTSV$ z0rK^6wlFq7`qI}u`5i~!DL?>~BebWwNZ3p77+;W_K4;s;Gvu*C!pOm6qtz3He@;#( zO)<#{L0qUJ9RW0q(O?$Rv}bAh!{&20*w3YzT<{AlNcWyeQ{p2Z<$hmvPrUSRd84MU zy>V>RjVC}U?b|b6a}nmG0yo~PltmOuCY6bjcV_a7N;Hmeqzo>HM? zL9*WLFslmtgYvfq#;zo7d20NfDbo&UV9unN=vwyZ7913z9(G>;Xq$Fy%e?uKVS&YP7&b1adqc^IADqy0p6$0x zS6}rx`t4M@y4_?IUc+|4rH%D=Jw-K28#H{GA?G~M3jA9_l3Uz+};`TDJ2 z%g{HWo;7{EksflPOky{szo`CV7&dP6h-{l-^y3ehDlWEFJeIykgQ4HVG0y6p?B{v4 zefDW;Gu$XO>)#}kk|ml?5cf!B*5vLN^*eoiay-K;+u;=-`k|6HUNM-4!&320J{ zKWWotbP-X~t#Da}$#Lph7K93-2D_( zAr<0!G_&+on&Eakere8UJ`1GO*@K9@b`~K)CNu64<>({YzuV^L(S`_8f=)|Q?uiI}gS8vgminHm72e{Wb&{(JQ_Fe<0(KF~o@eI4=;q2@H{fkWQ*{ZyXeVV!a`XuQH@{d*p69NJ_+&l&Gc zx6ZAKX@CrsC;mf?Ngg)f?e$IKjZ?R40~JJ%i(@v2&7$N1z1B`E^IM1C6&$7aXKTM~ zm>i`XgzFauhvPjYRN$d?9n@57c^Ng`4=U1IfJj_Wh`zsX5s`tfk-T#QIO1aIVMS6k1^;kBLPwN$*~ z|6P0Zh4{hGcP7N9d!4znU-~iUZ+DP?owG4{pXX^v?zIs4@$68`=gwTd>=%Y_y)PNfO=(hH5>gtlE8@{)Z#Wsd+wa3O zf-0jA2QjHvKi@IJNW9XaeA*Rca5k7$ISfi@pd-;@sTZLgE#1&AnUHNuej3||VhZu- z>K(j~r9jwO?Y5T0nbEHyN;5)M`Giz%2DA(n<#|7pbK#@X=*iefS3m(_86fKM%fal0 z^DVbdm^bYpoSfagl_+|EMVD~`nwNXAW?=e<6t+bamy4t<;G+sniq6T7Yf%3?o_PX} zaK6(dxW#AJ1z2J?{uimn>xYz}&1Lu-Gt%oV>D}&)r`J^Lx!oEgshc4(zim?v_DlNt zkOC)b*HgCF#XYnNZ)-3TSfg2?`%CRZ|Dnn3I6$md zhZ?KZ|K!C66zvrZP>(kc`V(_z-#WE2IU&v0Kj%-lJq>J8$~M*6dYGL2 zhsE!xG+nl<9fBX*4^7li%&P=GxT;A>WbbBZMWaN~nTmCPcqi>oPh8o#leQjjZ z`2Bc%4U+`Kzqhr9-<}I^*78&u+)-iu>rIB@UWejET5)xvL*fd_-EF9tc9sO+6Tvq` z>a7pzulTrlfg&oDRgBEb&s)0T;0tDMgujz6?6fvmCzt4NR3E$1SSe0)XnM}*MxLV* zwFT^*Vr;vis9yJK7f|M*Y{eSp&?5* zwC}$3h4-0%EavR{uC>oG^)*2asaz9JRao~&8@V))^5nJkAHK8u2y-=0fM}iv*cky}N_Xzorr=8fP-HL1mK^jLThO<;5 zDv5-j;;o_=AIj4eFF;tGzZ1mXG+i6&sYPX%{F^JujBj*0i&A-5v1Kia-R+81@qMJ$ zcvWr&y|UHiiO_rz!_KWqA>I)@1hTwChGZHG2N_~-OD6{RtnB|fRJ)AvS8QC-R%GSY z*1|~Pi>}_B1ns4~3mB`|lN>h_-?ko(+Qqy?5?i5Vi=o8uf62ejrj`>})K|L!FYERB z%tm&>+Qf!rY`t#<*w5u|3|{;;wEA`ysXvD>fktAvhpQRi&1TwV=JI)SOtA~#dhm%4 z(1~4hc>R*(?K1o5p2-3hd94W}=88alSu&k_nfY%hx4$o1a8TL)HN<&#?RaEPFT24-VTQxSBjg(`Nxc-?Yikc)iWy zr*|jg=da?YfTq%tpG}40r`>K8v6EI(j@y2y60d53ZE&FNtqg zZdb3`MK^=3XOLFWw=XVmM;~H$@vp5+{EO)7`pwaI7%KNk)@pQb=T}Dl^z0YwG3c(` zT-`JN9Lv)optwC94WsMI3~GPFkSBPiGK2~y`3N9FI!NX)V>SiSo}X#yGZ-J4Q36+W(|t5s$Bcf zUyO5?Q?S5~!mqGis*voTTam4^Zp1_Q7z&6+QX;afr-QgAZ!5i+Vf4on9gXBe9Le`X z@+34ig$>f=0arw|1AtYw({z&4q?Pn4ENnO*x00A<`>u!RPj>063;I3D#l#f_TD$%j zuf+`(h%;&TnhiioC05=R>xmf4E4NjyZu(xUS-Z>&A`Z4IMIIl~T(|Dp5GHbku4}f# zthh>ZdZ(3j>mu<8mCQsD&G}bf2`R-QMb1or%VOgQ;V+Xul@N|uD1!7s66z>27zjzD zD)i&8KGl`bT~XD~omVpyd?~v8Q+G!hf*a+M2Ilpae$X*BlA6I%5??!uWw21?8%VKG zeihkj6UN{Kb4m1%5Ik!t5Qv$1;7Hy7Ktt@CGb2CO-3dNnp}_%RU|6{KRw$3uagUY} zXB+36PH^;jO&5M@5fvrs3n-Bq$Um%eM)U&G#I|97Tz`B#*nnyM(fny8l$nG`GzOg% zTUNpHfN1`#LiUNEWLTKQYUI*<#9jBHFS0n)y#BJ}sJMb2SY5Ce---chYD37*mGwCM z`*7K*P_E4TA&U=IRx{zJ9rI*mr4poXGDBkC5pNr38h3Q%7>#Hoc`(#+#kWonh*G)M zR!;)j;*l@-M%SCH32Q@(KhTlLy-)IOcxo*O8@xq#c>`s77syT{}IW zK~riP!jB`96|9LvO3U1;x46d=0*PCPc7*u9SSa~DNoBjgWyVm9WV{nWo%$t|$jtnF zR(#8o&-~*b|M+6#(oK6@wrqX=%2Xd%NQOFhM^qr1l%nSlZ&4F0GR(&Q_cslD*Ir2T z2HmuqmMMFkCZ$e+U?`u|ozJOW{D5g|ojk3zrWS!*`Jisw1D2lUO{$Et^l#+73tj`{yT}2 zV(A140T8^HWqYT+Zc8OsM&>BJM#*po_el}IN_p4ZuvymJ7@4K>uT|oDO1cmc(|}vG z=W_44Z=^~tfUVQGfLB$hstT(N1EX}RU<-tuC(5G?^rx=hEbFx`K>98^fmQpc()T~S z=JqXtt51gR5E-sM-mjbZR$dy{wY6pwvmi|Lc<+8~om{Z_MTi=hilANjo9$fx@52@9 z6b&j*=iMiY$dDT*L6cY1{8ey{RwmYu{=lvO>mc=PxY5+J1&k%x?Dbar!RA+b8@}K# z7Na$K9X@pPL2)g$3KBjRKbyX4kfcZf8Ows}&2>IBQ)> z`zk80R^@PGvekW-@fFPJF{7gL$jUnhG6Hy5R8gxr-kZM(&L5n>Y=fKW=nA0*I&6Mr2Zy*Cw~WLdH2E<-~r!GF*JZ7 zbq&^$m0ulRxmly*{v4PzbNTr*QNjJCFTyl4&IW1Br>?O9ei3u0A&#wB($moiMb*Y{OL6w_RoI{>< z-U9_R&eyS2{=9Ku-kE%+`(D`Q_o3c(?WM}wrdw;${B~YLhp_kbM_-BGLfUV!<@Egg z8(x-?v{-y}6D>4W<^Q^0zcOXh`A%zJ2U-=!xGF5)rkM6ibg}J}qWt)l+D?EvGxeG_ zx`pJCx($3!oKh59wO9O9j*}pepLP_oEBFELlMk+`+$OIjx5UW?g`#M~3s81yA!J{w zBQ}^9V*a1~B9;j`6wt6H-F#3ygyx$17>q=CtSu0iD+wRds@VQ2){#{UwM9zfWa&fYmeJ>jLZcd{SCz;Gh(sCJeY zPXA8qYwud*^Q^qOim=j!p`-eRYCE{Rw99Yo>O121ZI;`r^U#_`ht4km@9X_#U7?vaSAG!eVQr5R6^mWA&2i}tXN%6-wB zz7zLQBJyy2`X1T}c_0pdq~?}7n8BlHHz{KITU1g|V2T=lV-RmFIOt1LS%oO3Q$%!L zSNu3`>Onzg&yTuwEe|UH+R3Ot)KUKrsIMVR)6PfjK$P=Tq@lfo<%w8>h|g)?dKa|s z(c7$jYurd)a*E^(#v?C9IlehY>ffOK()P8E+3bq>N55PtUBfTKox2Z{E61JY_VPW1*ZXDo1OC?Ug1^}(<-*T3_(xm9 zx8iT>kThHlf9D$f^xry8L~+ z;BU=|x$v)TH~mKg{(SgW{Pj314VOdjT!Vi!7asnWUEFs030D5b-11rcJ#cm!&iLzX z<%gup*X@G8O?`6VcYI;`ZwcRuzafLua5?-vY4GcQ7Rblyhrf+u+b%!b%FoL!pT*yr zjGs3C&b9KB)8)tSg1^o!`0HZuJzB!I;&1YqZPWYOHq-y)fIq7r{@U$?zXz=RvfT1n z{B6qkY2)uYD}P(M{GeU%cjO6aI-ULven?CBR{Y&|Mj9?he>*-m{pZ5NU$=|eF2Bag zZ@emyhfi<1f9TwTzqwZa(RBHWUGO)sce-Aue}kXg6229GkDi`}%i*t!!S~38hrfPf z+AhE8pOQzr-11raJ2KM`8GTP$`E`>5c@*t}zX`q4^*a3<{B14aTk*GUP#P|WzupEv zBo`k3#{9JH@|~@Gx7_ks{0+?bX`}D8&&>X>4EWoA(ZBECXIG``HTby(|7c72R{U-K zNg6JPzjFvF-1ZAb9um@58sNv9s|>GIrPpo_(yZ$;cwXmZI_>5EZ^&tBxE%hTH28HB1Nm6}@VD{&w#(19^7C@bXYsct zsf*y-B0sE{!WB{aU4G5R;?Ig zld)|3nhna+z_sfiy>j_q$KR!q^4Eld#71U+J2f*{=<3yh5JX*})Botm zuzbr1Bj8F$zp($_tTS|$te-%h!$ug@BEJ)#do@mdrfHtd zH=es$(w=;&YhM&%ZKjI#yWeIeTIA_8>j2&Wpdv9Tgr!V$=WPsptGW3^twOFn zEE)5iH7C-V?LIqyvvLbr>)fRc-FcbO#&~{78&~R?rHzg6Sq8e)GFCQEGB*d#W|-Q5 zdjL3QEoV73LN3dJN=Rn<`r>zNNpa3^6LfmLdGC)TpCRKj@=<%&HbR8-*AbRZl8_ue zTNT^%Q93_9)Z5V{_;5KW|qtv0pwT<#5}#k~12g=434ayZ zD@Fs$S$`w`-+ZBC9yOF1zEX!Tu@4J$UQt13xk0@ufB9OLva@>5%9r`&^D+LlO}{g` zUH*5IME3SLBjG(%W~UC*w6vtLAA5}_=O?BVs)6T425fCA#g1*N9uG0-Y;t4iZ0$FP z*;>?Y%nr$YMEKZi<L$z0p_(LjWcO+#!Ty|8ypbVzcuit zMG#%}c}eu(I5QYp%<<%XCbAmX?;6h!_E!j?F^}wFb5l}!RSiD<&IE6E_AY-qB_(k- zTx{apAYTe}PkA80<0a%Q60AP+rr|AgSm%_J0{_v6c`<4p;Hc3?zZ$tOp2}v2dG?VR zd%ACgo}xJ3@ktpQ}`|h&X@R*`3d$vjWvQEqvp}1s5LhYZDYNK&yiR~ zTa{C7Cw+Zf_{>?`&WXZv{lxS2yqBZ!4@yb9?S&hd+S(Q!AosWVdc#rY&)Zk=?kJu8 z$kaDg>fn-)cWtFQ)X1!#f;Vul`(LCP`pB$(cn2?o;+~m`t!EkkS8)i1?L~AJCjKt> zjxuc1Djmh+9LX2@Bv0E3$sHgWolI1febEVjtKWjuiK>8~wkghgw!%n_f1fhhBAMXh zpS~0Pzki#VUe;7AZ>?U>QB~_hUAGgcNk9bx35_v<#MuFpQ}c~Jj;TArQ4WqQ0p`?y zoe#^rXq$@M@)lH2P=zvZ*B%i?D3O=hZ$bX|0~yn!W1PRD$H*Jq;Rx@&=XN^3IS!l0 z6|H+l^P5wYE#}wL`jv56S^m4X;UD7Tr~VRM5d_Ft2U@rz-=Cq6`7bNqEmOW#mfeSc zzHRt5?~9*}KXv?2-_GFk+lHTQ@bh*J|J%0V2O9jC47_s>8NNFer}@@;r7l*!$Ii?5 z$}PX?J@MBrQ(mUsW;WZGQ}=CQwL!^Q^*vzl%SM}g)+3*4;0t-GH49Ixb)~T-PG4Ub z9xW}+*4Md)Z?ePZwIy#KUizYe-nqnx;RGE=PZxvlk%7lPEZC{sKP{*1`Zm35{AbFy zpP=qL7KmRV;@#ur+?(L2FYjZs5HMV%YT_${sAk$EK~m9*oW1Z`ZUKr zCK&vU4t_W7!|Cg@HtnN};p>s1r#pVPlI=3)|Gs16F=n zrhKdVeE6&OX%l{e!QZ%R_}{i&|B(jYZ`bgB+pd4pTjIA}20lyQ#`hmGaI%jlt^B%k z)ADIq{?**_v#tERO!bnB6{2umCXu>2w=gRS& zP$m|OC=jgj;kw%9_ztu+$iE_>atRrbS6Qd`ME1Qr3IE!j)N}%68{hf&^NjS54y+39 za~-Bg8uv$KTBmLu!T3YliHuwN@l8ZjHm9Nio>uqwJnqI>oQsy6p3fOQI&yGCbJJaZ zJ|LsNt*^@tI*;59{f$7ryQ9B9t^0QRYdrJ+x&F+7G=e#QJt{QIKX?>yX3d!M)k@R7o zDcx$@U8dOCc?_k!XL*UCh9IOQ%{qj9AcC|Du}IA{JKnZ@%7^P!WAiXyo+P}jZQD&VeUg&-K5t&Qa*eh}D$t{+6FZI(jfsQ; zik@IAQ;&rP@9VXaax|sCD_7XxZ%V+*huqqSn|D`+YM=KL(zd=GqsS(7k_aspp)1)h zJ9fPiDT4PNg8)eO=O~z+*pSH&jeJGwm^9SXvBg_``Nz<}+{ejCs|0=x!3z^iGRL%# z%w$#gzrPA3^H*T48n+Oi{iDrIA7<0*^#8Kye~4A6d|HiHgh;8BtqxBhAeVujw20)Q zpR|tt4TJ74w`_+1EAO^c1rOAgFM)WI`;ztUkK${`HC^3+(jL{@kCtPJIt%*>?<^La zQN^<8#eu0NI>w7E$z~j0H3+Xrl8wSAldo>f)6@;;3#kz$`diPi_X#%J(=FB*!fseE z+z|b-x9}}_z4*%71iSCn!Ei^~vHk$LS3spQnfKmAL^R$}@0;laON<-n*uu72KQOhQ zNuX!Xl|U=kH9eKu6CyIp>ur7J{FfxYC1*K($-YQ;akFz_a?woJyL-nT^@;hS^TYye z#m~PV{0}?RBRtA~Ey_CcPAXHfE;#?yD!9;9@LuvkVU^7K35@l&2v>`mQCv^&D0VNI zwOmd%m#Cq!x;U>PKhOKwQZ{#C#d~(=$;^y;(h4Sm;@hYFh=wP0XZYx3-0%IJj=`Gk z(J+DveqdSCv|s$2a4*n5O-t3z$d7N(QyeI<#qYI#Kdzj5CO=L+Pl_Ncr)C-IV4;S&cJAROJh4*kd>I5YRmvsHoxjwh#`svLwu4(Rw zL0iQe2yP(|PCYb;P)j)h~#ecg{3wK1$xcdN!x;YSpk5 zEiNEHc@DKp2-*I<970ZTgdEt|p_8kz$geS7U(R_RoPTH4O?K5O|Ka2H*O{4bkE2Lp z4a<;`KFOM&h2Db|_<;2`C*hQo@=osRk+}k~+ zXTNXYb!D@63h1(4%0CdbiZAnruRJe$J~`d!xj&f@FHkgzF3GNoTRHOsS$?E$8!hHU zSyJ@e$Q)ffabib%KZ6LtX=UmaC+cW^E~@3#i86sm{Vf!P4Tbe4b7Qo>spWAL(6iy5;(o{kB zwdBhOxVkMLmrvc;^PB;Dfcx~K?n~pR7io8F9J|mZc>&k;9B0w&?u-s6@WZl#{)XZ0 zGGU-sozov2e8_w^?(RMMljdIABlQhNeO_uQ`hhr2C-<4je8(!@vtgK44(Wy31~(=Ngf03z zL%%F~=%OY`yRJRoTME;JwY7&+$B`81)j!MyBZxhALmp@5ydncK$#edBAt!oQ&)Cs9 z+G)m)y(0COsMM1DU_OnC+QfS|m{l11LI-!42_jyGN-qkii6O~WZ33YLZQ|$PY^#VmZ{JogG6xu$b1v2mQURM&N*#=EV80s!=Q<5I zQ|~~Qe(zy^5B~WcduMvGZ*!mak(-|4YqB5r&#X@N3=<$kvSI`MxpZR~xyNa8ridxc zop$uv!q3_dP8ePsx# zEnzcWXi|5|c4u$SUuer(l?)E&ZW>g*%DP5a5u zMi!rV}vhJCz$(IEWYC6F0j|QzY zS_d)c*ZTlvWU-0wXAbKtsoTMmwU01Te;0D6aG{RE5tEv~O#7Wy{-$X;lVB@Fa(`{8 z%uBHer8&b*y>1i}Hf@`1dL$rXF_whSG%tD3Vb-wgW&)V1=O5AE>xQtiuUl?qw|DAd zUfb^gfe-s;w@;cYS7QcuF8$)w__L`~D5u&sh?0}2BU9d-$itMUbbTKoEu^qKq4SCO zL(z|@Lf+ZTccwn2jGGUBWsUWJr&#}I^Xm!;-(e7m2VfwwFRe0|-S)??)a&}4iFWLr zbx?G}1&LFQj?XLTcQkEHF+XCZZXJ72;GGuvSl?>sIoj3!uCb&1G3PY8b3(4tHibEWVrvVt5m|8j*lC$?>4}(Wul^b0W z%1><{G3;K%ZnyHLgL3pCfeb!W!j0OYF&aw@hJx7k=IHBji%+_GZ!;XHHjQ8o;i(N# zZi|~cpJ54~)1xsy`EjRDe%5-2Q&&qL7xp)O)Op3v*w~D5`2}j8X5M%FfmI20r414) z!uY@F*XAsSt2y(#_Hk5iqxPeCkWGyD+x>6m8 zCrpXimKCj2eo{PXG$XD0mts!+qa`=$p4Mka4?=av%?Kg3%Imv@4BXHz4Z0WpF_XPd z{Fjk_W2*{^RsZ*_g6JiQJ4){nmMtvs7z+mb0kY&NWhz!$twcn$8j(-+yY)bSg~NeM z#vUXtfVA{(?2CDu9aywm@)dppReJ0HuJMd8*`k9qp58flrU)JaTH<-~Z(lVxEeQH! zv&U;1rO#VV_TydUTX2jdSk7VKc%rKO-T!vbP%6H{`@8yf>d>*sV51=wVSV zX85Z55RGIsh*3dKxTEM~0j_9T;mpaq{g$t}|EHnp*M5Wb$6Lyecq>Ito+C%=Ep5QS zU|hPfz1tmJ>Z3E&_~X(fOKMEoVbyi^L(+QfhFD{9Y^A%-878WE8$bm7tG+2#Uqe4* ze+#Uas7|qqEqN1YMc~>u)>sx>Y4?6eAkm95xLUREBMjk54&l?u2c=pBG0b1jM0-#F zH7fm=+JAT^N;5ga#BYD$niYJNM(PezTmXksvRM4t!;06)R-8^Zv(VbhqSe&%+3zED zpHK!iN*5|akzDkwz2-beGV95|tdN~qd@UUqyh{~@YgGk}Lj+yR->TNa zT^HthQ~qipuB8EAaAiXxX#+=>P{%02z39Jp-e6_$g}2sBN2<)rIc4U#G8xefQWV`Dp5R~XyTE_y<2NBiiHV>|YU_Kof6kevA<+KzVc^A3g8w)*a_q&!#1%Eox zRG@fc7~WwpX)xK_ezGPD5XzIWw-BlPs8@He8|^)Y+c5xhIu~5U@h^laPTvG>TUFkG zL*6^DDa93;Gcy3Olf;iz9s8S+?OBy6TKe1NZY~jRNljs}(*h zPnTS~`C1M*Db;fDVSWho#gVLw0S>LiH%bixI|uicVCI?8(PP&H!W6sxVLwU_As9H_s{smtMW$DnP&NYNBF~5=~4P1XYjw)Sf|~U(DX^9?g~;f47_R�qSXrF@ak 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%0DYo8lsNZ{%n#QtH~-c&;d16QPKh{-%G_S+%a}t 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ℑ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 z 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

e%V{T84NzXce7 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%0DMIHCg;`HTMEPy}o3;`m8{H6Hnuh^L`^ZG* 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

9MSRXly5tp~o}6OnJ&oN6u?f7{46*4`dm5#);@ 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 z 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

VG{rj*$0hF$aVs&c7@DqZFY3xm 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 + +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1.h new file mode 100644 index 00000000..9522eec1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1.h @@ -0,0 +1,886 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include +# include +# include +# include +# include +# include + +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG /*compat*/ V_ASN1_PRIMITIVE_TAG + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_UNDEF -1 +/* ASN.1 tag values */ +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 + +/* + * NB the constants below are used internally by ASN1_INTEGER + * and ASN1_ENUMERATED to indicate the sign. They are *not* on + * the wire tag values. + */ + +# define V_ASN1_NEG 0x100 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) + +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DEFINE_STACK_OF(X509_ALGOR) + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* String is embedded and only content should be freed */ +# define ASN1_STRING_FLAG_EMBED 0x080 +/* String should be parsed in RFC 5280's time format */ +# define ASN1_STRING_FLAG_X509_TIME 0x100 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +/* + * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted + * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting + * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias + * STABLE_FLAGS_CLEAR to reflect this. + */ +# define STABLE_FLAGS_CLEAR STABLE_FLAGS_MALLOC +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DEFINE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * This flag specifies that RC2254 escaping shall be performed. + */ +#define ASN1_STRFLGS_ESC_2254 0x400 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DEFINE_STACK_OF(ASN1_INTEGER) + +DEFINE_STACK_OF(ASN1_GENERALSTRING) + +DEFINE_STACK_OF(ASN1_UTF8STRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DEFINE_STACK_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(const ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t); +void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DEFINE_STACK_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(const ASN1_STRING *x); +DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)) +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, + const unsigned char *flags, int flags_len); + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, + BIT_STRING_BITNAME *tbl); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(const ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); +int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str); +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_normalize(ASN1_TIME *s); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t); +int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b); + +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r); +int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r); + + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_STDIO +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags); +int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +const char *ASN1_tag2str(int tag); + +/* Used to load and write Netscape format cert */ + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); +void ASN1_add_stable_module(void); + +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +int ASN1_str2mask(const char *str, unsigned long *pmask); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)); +void ASN1_SCTX_free(ASN1_SCTX *p); +const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p); +const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p); +unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p); +void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data); +void *ASN1_SCTX_get_app_data(ASN1_SCTX *p); + +const BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +const ASN1_ITEM *ASN1_ITEM_lookup(const char *name); +const ASN1_ITEM *ASN1_ITEM_get(size_t i); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1_mac.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1_mac.h new file mode 100644 index 00000000..7ac1782a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1_mac.h @@ -0,0 +1,10 @@ +/* + * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#error "This file is obsolete; please update your software." diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1err.h new file mode 100644 index 00000000..faed5a55 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1err.h @@ -0,0 +1,256 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1ERR_H +# define HEADER_ASN1ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASN1_strings(void); + +/* + * ASN1 function codes. + */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIO_INIT 113 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DO_LOCK 233 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENC_SAVE 115 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_INT64 224 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_GET_UINT64 225 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EMBED_D2I 120 +# define ASN1_F_ASN1_ITEM_EMBED_NEW 121 +# define ASN1_F_ASN1_ITEM_FLAGS_I2D 118 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PRIMITIVE_NEW 119 +# define ASN1_F_ASN1_SCTX_NEW 221 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_GET_INT64 227 +# define ASN1_F_ASN1_STRING_GET_UINT64 230 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TO_BN 228 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_STRING 229 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_C2I_IBUF 226 +# define ASN1_F_C2I_UINT64_INT 101 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_DO_BUF 142 +# define ASN1_F_DO_CREATE 124 +# define ASN1_F_DO_DUMP 125 +# define ASN1_F_DO_TCREATE 222 +# define ASN1_F_I2A_ASN1_OBJECT 126 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_OBJECT 143 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_NDEF_PREFIX 127 +# define ASN1_F_NDEF_SUFFIX 136 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE2_SET_SCRYPT 231 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_PKCS5_SCRYPT_SET 232 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_STABLE_GET 138 +# define ASN1_F_STBL_MODULE_INIT 223 +# define ASN1_F_UINT32_C2I 105 +# define ASN1_F_UINT32_NEW 139 +# define ASN1_F_UINT64_C2I 112 +# define ASN1_F_UINT64_NEW 141 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_PKEY_NEW 173 + +/* + * ASN1 reason codes. + */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NEGATIVE_VALUE 226 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_PADDING 221 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_ILLEGAL_ZERO_CONTENT 222 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SCRYPT_PARAMETERS 227 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_STRING_TABLE_VALUE 218 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_INVALID_VALUE 219 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NESTED_TOO_DEEP 201 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LARGE 223 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TOO_SMALL 224 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 195 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 228 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_INTEGER_TYPE 225 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1t.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1t.h new file mode 100644 index 00000000..a450ba0d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asn1t.h @@ -0,0 +1,945 @@ +/* + * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM itname##_it = { + +# define static_ASN1_ITEM_start(itname) \ + static const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define static_ASN1_ITEM_start(itname) \ + static ASN1_ITEM_start(itname) + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) +# define static_ASN1_BROKEN_SEQUENCE_END(stname) \ + static_ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) +# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) +/* Embedded simple type */ +# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) +# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) +# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ + const char *field_name; /* Field name */ + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + int (*adb_cb)(long *psel); /* Application callback */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT (ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT) + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT (ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT) + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* Field is embedded and not a pointer */ +# define ASN1_TFLG_EMBED (0x1 << 12) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ + const char *sname; /* Structure name */ +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \ + static stname *d2i_##stname(stname **a, \ + const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \ + ASN1_ITEM_rptr(stname)); \ + } \ + static int i2d_##stname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, \ + ASN1_ITEM_rptr(stname)); \ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(INT32) +DECLARE_ASN1_ITEM(ZINT32) +DECLARE_ASN1_ITEM(UINT32) +DECLARE_ASN1_ITEM(ZUINT32) +DECLARE_ASN1_ITEM(INT64) +DECLARE_ASN1_ITEM(ZINT64) +DECLARE_ASN1_ITEM(UINT64) +DECLARE_ASN1_ITEM(ZUINT64) + +# if OPENSSL_API_COMPAT < 0x10200000L +/* + * LONG and ZLONG are strongly discouraged for use as stored data, as the + * underlying C type (long) differs in size depending on the architecture. + * They are designed with 32-bit longs in mind. + */ +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) +# endif + +DEFINE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/async.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/async.h new file mode 100644 index 00000000..7052b890 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/async.h @@ -0,0 +1,76 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifndef HEADER_ASYNC_H +# define HEADER_ASYNC_H + +#if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include to use this */ +#define OSSL_ASYNC_FD HANDLE +#define OSSL_BAD_ASYNC_FD INVALID_HANDLE_VALUE +# endif +#else +#define OSSL_ASYNC_FD int +#define OSSL_BAD_ASYNC_FD -1 +#endif +# include + + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct async_job_st ASYNC_JOB; +typedef struct async_wait_ctx_st ASYNC_WAIT_CTX; + +#define ASYNC_ERR 0 +#define ASYNC_NO_JOBS 1 +#define ASYNC_PAUSE 2 +#define ASYNC_FINISH 3 + +int ASYNC_init_thread(size_t max_size, size_t init_size); +void ASYNC_cleanup_thread(void); + +#ifdef OSSL_ASYNC_FD +ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); +void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); +int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD fd, + void *custom_data, + void (*cleanup)(ASYNC_WAIT_CTX *, const void *, + OSSL_ASYNC_FD, void *)); +int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key, + OSSL_ASYNC_FD *fd, void **custom_data); +int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd, + size_t *numfds); +int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); +#endif + +int ASYNC_is_capable(void); + +int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret, + int (*func)(void *), void *args, size_t size); +int ASYNC_pause_job(void); + +ASYNC_JOB *ASYNC_get_current_job(void); +ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job); +void ASYNC_block_pause(void); +void ASYNC_unblock_pause(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/asyncerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asyncerr.h new file mode 100644 index 00000000..91afbbb2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/asyncerr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ASYNCERR_H +# define HEADER_ASYNCERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ASYNC_strings(void); + +/* + * ASYNC function codes. + */ +# define ASYNC_F_ASYNC_CTX_NEW 100 +# define ASYNC_F_ASYNC_INIT_THREAD 101 +# define ASYNC_F_ASYNC_JOB_NEW 102 +# define ASYNC_F_ASYNC_PAUSE_JOB 103 +# define ASYNC_F_ASYNC_START_FUNC 104 +# define ASYNC_F_ASYNC_START_JOB 105 +# define ASYNC_F_ASYNC_WAIT_CTX_SET_WAIT_FD 106 + +/* + * ASYNC reason codes. + */ +# define ASYNC_R_FAILED_TO_SET_POOL 101 +# define ASYNC_R_FAILED_TO_SWAP_CONTEXT 102 +# define ASYNC_R_INIT_FAILED 105 +# define ASYNC_R_INVALID_POOL_SIZE 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/bio.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bio.h new file mode 100644 index 00000000..ae559a51 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bio.h @@ -0,0 +1,801 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* There are the classes of BIOs */ +# define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM ( 1|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_FILE ( 2|BIO_TYPE_SOURCE_SINK) + +# define BIO_TYPE_FD ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_SOCKET ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_NULL ( 6|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_SSL ( 7|BIO_TYPE_FILTER) +# define BIO_TYPE_MD ( 8|BIO_TYPE_FILTER) +# define BIO_TYPE_BUFFER ( 9|BIO_TYPE_FILTER) +# define BIO_TYPE_CIPHER (10|BIO_TYPE_FILTER) +# define BIO_TYPE_BASE64 (11|BIO_TYPE_FILTER) +# define BIO_TYPE_CONNECT (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ACCEPT (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) + +# define BIO_TYPE_NBIO_TEST (16|BIO_TYPE_FILTER)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|BIO_TYPE_FILTER) +# define BIO_TYPE_BIO (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|BIO_TYPE_FILTER) +# define BIO_TYPE_DGRAM (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ASN1 (22|BIO_TYPE_FILTER) +# define BIO_TYPE_COMP (23|BIO_TYPE_FILTER) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# endif + +#define BIO_TYPE_START 128 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_PEEK 29/* BIO_f_buffer special */ +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +/* Deliberately outside of OPENSSL_NO_SCTP - used in bss_dgram.c */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: + * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way; + * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 +# define BIO_FLAGS_NONCLEAR_RST 0x400 +# define BIO_FLAGS_IN_EOF 0x800 + +typedef union bio_addr_st BIO_ADDR; +typedef struct bio_addrinfo_st BIO_ADDRINFO; + +int BIO_get_new_index(void); +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi, + long argl, long ret); +typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp, + size_t len, int argi, + long argl, int ret, size_t *processed); +BIO_callback_fn BIO_get_callback(const BIO *b); +void BIO_set_callback(BIO *b, BIO_callback_fn callback); + +BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b); +void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback); + +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +typedef struct bio_method_st BIO_METHOD; + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef int BIO_info_cb(BIO *, int, int); +typedef BIO_info_cb bio_info_cb; /* backward compatibility */ + +DEFINE_STACK_OF(BIO) + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +/* # define BIO_C_SET_PROXY_PARAM 103 */ +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +/* # define BIO_C_GET_PROXY_PARAM 121 */ +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_C_SET_CONNECT_MODE 155 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +# ifndef OPENSSL_NO_SOCK +/* IP families we support, for BIO_s_connect() and BIO_s_accept() */ +/* Note: the underlying operating system may not support some of them */ +# define BIO_FAMILY_IPV4 4 +# define BIO_FAMILY_IPV6 6 +# define BIO_FAMILY_IPANY 256 + +/* BIO_s_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0, \ + (char *)(name)) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1, \ + (char *)(port)) +# define BIO_set_conn_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2, \ + (char *)(addr)) +# define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f) +# define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)) +# define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) +# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) +# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ + (char *)(name)) +# define BIO_set_accept_port(b,port) BIO_ctrl(b,BIO_C_SET_ACCEPT,1, \ + (char *)(port)) +# define BIO_get_accept_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)) +# define BIO_get_accept_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1)) +# define BIO_get_peer_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2)) +# define BIO_get_peer_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3)) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,3, \ + (char *)(bio)) +# define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) +# define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) + +/* Aliases kept for backward compatibility */ +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR +# define BIO_BIND_REUSEADDR_IF_UNUSED BIO_SOCK_REUSEADDR +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# endif /* OPENSSL_NO_SOCK */ + +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)(c)) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)(fp)) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)(fpp)) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)(name)) +# endif +# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)(ssl)) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)(sslp)) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)(md)) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)(pp)) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)(bm)) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0, \ + (char *)(pp)) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) +# define BIO_buffer_peek(b,s,l) BIO_ctrl(b,BIO_CTRL_PEEK,(l),(s)) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)(peer)) +# define BIO_ctrl_set_connected(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)(peer)) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef) +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +uint64_t BIO_number_read(BIO *bio); +uint64_t BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +const BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +# ifndef OPENSSL_NO_STDIO +BIO *BIO_new_fp(FILE *stream, int close_flag); +# endif +BIO *BIO_new(const BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_set_data(BIO *a, void *ptr); +void *BIO_get_data(BIO *a); +void BIO_set_init(BIO *a, int init); +int BIO_get_init(BIO *a); +void BIO_set_shutdown(BIO *a, int shut); +int BIO_get_shutdown(BIO *a); +void BIO_vfree(BIO *a); +int BIO_up_ref(BIO *a); +int BIO_read(BIO *b, void *data, int dlen); +int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int dlen); +int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); +void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +void BIO_set_next(BIO *b, BIO *next); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +void BIO_set_retry_reason(BIO *bio, int reason); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +const BIO_METHOD *BIO_s_mem(void); +const BIO_METHOD *BIO_s_secmem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +# ifndef OPENSSL_NO_SOCK +const BIO_METHOD *BIO_s_socket(void); +const BIO_METHOD *BIO_s_connect(void); +const BIO_METHOD *BIO_s_accept(void); +# endif +const BIO_METHOD *BIO_s_fd(void); +const BIO_METHOD *BIO_s_log(void); +const BIO_METHOD *BIO_s_bio(void); +const BIO_METHOD *BIO_s_null(void); +const BIO_METHOD *BIO_f_null(void); +const BIO_METHOD *BIO_f_buffer(void); +const BIO_METHOD *BIO_f_linebuffer(void); +const BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_datagram(void); +int BIO_dgram_non_fatal_error(int error); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +const BIO_METHOD *BIO_s_datagram_sctp(void); +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +# endif + +# ifndef OPENSSL_NO_SOCK +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +# endif + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_STDIO +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen); + +# ifndef OPENSSL_NO_SOCK +BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, + const void *where, size_t wherelen, unsigned short port); +void BIO_ADDR_free(BIO_ADDR *); +void BIO_ADDR_clear(BIO_ADDR *ap); +int BIO_ADDR_family(const BIO_ADDR *ap); +int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l); +unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap); +char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_path_string(const BIO_ADDR *ap); + +const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai); +const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai); +void BIO_ADDRINFO_free(BIO_ADDRINFO *bai); + +enum BIO_hostserv_priorities { + BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV +}; +int BIO_parse_hostserv(const char *hostserv, char **host, char **service, + enum BIO_hostserv_priorities hostserv_prio); +enum BIO_lookup_type { + BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER +}; +int BIO_lookup(const char *host, const char *service, + enum BIO_lookup_type lookup_type, + int family, int socktype, BIO_ADDRINFO **res); +int BIO_lookup_ex(const char *host, const char *service, + int lookup_type, int family, int socktype, int protocol, + BIO_ADDRINFO **res); +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_sock_init(void); +# if OPENSSL_API_COMPAT < 0x10100000L +# define BIO_sock_cleanup() while(0) continue +# endif +int BIO_set_tcp_ndelay(int sock, int turn_on); + +DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name)) +DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr)) +DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip)) +DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode)) +DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port)) + +union BIO_sock_info_u { + BIO_ADDR *addr; +}; +enum BIO_sock_info_type { + BIO_SOCK_INFO_ADDRESS +}; +int BIO_sock_info(int sock, + enum BIO_sock_info_type type, union BIO_sock_info_u *info); + +# define BIO_SOCK_REUSEADDR 0x01 +# define BIO_SOCK_V6_ONLY 0x02 +# define BIO_SOCK_KEEPALIVE 0x04 +# define BIO_SOCK_NONBLOCK 0x08 +# define BIO_SOCK_NODELAY 0x10 + +int BIO_socket(int domain, int socktype, int protocol, int options); +int BIO_connect(int sock, const BIO_ADDR *addr, int options); +int BIO_bind(int sock, const BIO_ADDR *addr, int options); +int BIO_listen(int sock, const BIO_ADDR *addr, int options); +int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options); +int BIO_closesocket(int sock); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); +# endif /* OPENSSL_NO_SOCK*/ + +BIO *BIO_new_fd(int fd, int close_flag); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# define ossl_bio__attr__(x) +# if defined(__GNUC__) && defined(__STDC_VERSION__) \ + && !defined(__APPLE__) + /* + * Because we support the 'z' modifier, which made its appearance in C99, + * we can't use __attribute__ with pre C99 dialects. + */ +# if __STDC_VERSION__ >= 199901L +# undef ossl_bio__attr__ +# define ossl_bio__attr__ __attribute__ +# if __GNUC__*10 + __GNUC_MINOR__ >= 44 +# define ossl_bio__printf__ __gnu_printf__ +# else +# define ossl_bio__printf__ __printf__ +# endif +# endif +# endif +int BIO_printf(BIO *bio, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 0))); +# undef ossl_bio__attr__ +# undef ossl_bio__printf__ + + +BIO_METHOD *BIO_meth_new(int type, const char *name); +void BIO_meth_free(BIO_METHOD *biom); +int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int); +int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t, + size_t *); +int BIO_meth_set_write(BIO_METHOD *biom, + int (*write) (BIO *, const char *, int)); +int BIO_meth_set_write_ex(BIO_METHOD *biom, + int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); +int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); +int BIO_meth_set_read(BIO_METHOD *biom, + int (*read) (BIO *, char *, int)); +int BIO_meth_set_read_ex(BIO_METHOD *biom, + int (*bread) (BIO *, char *, size_t, size_t *)); +int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); +int BIO_meth_set_puts(BIO_METHOD *biom, + int (*puts) (BIO *, const char *)); +int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); +int BIO_meth_set_gets(BIO_METHOD *biom, + int (*gets) (BIO *, char *, int)); +long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); +int BIO_meth_set_ctrl(BIO_METHOD *biom, + long (*ctrl) (BIO *, int, long, void *)); +int (*BIO_meth_get_create(const BIO_METHOD *bion)) (BIO *); +int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); +int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *); +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); +long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) + (BIO *, int, BIO_info_cb *); +int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl) (BIO *, int, + BIO_info_cb *)); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/bioerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bioerr.h new file mode 100644 index 00000000..46e2c96e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bioerr.h @@ -0,0 +1,124 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BIOERR_H +# define HEADER_BIOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BIO_strings(void); + +/* + * BIO function codes. + */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_ADDRINFO_WRAP 148 +# define BIO_F_ADDR_STRINGS 134 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_ACCEPT_EX 137 +# define BIO_F_BIO_ACCEPT_NEW 152 +# define BIO_F_BIO_ADDR_NEW 144 +# define BIO_F_BIO_BIND 147 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CONNECT 138 +# define BIO_F_BIO_CONNECT_NEW 153 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_NEW_INDEX 102 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_LISTEN 139 +# define BIO_F_BIO_LOOKUP 135 +# define BIO_F_BIO_LOOKUP_EX 143 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_METH_NEW 146 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_DGRAM_SCTP 145 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PARSE_HOSTSERV 136 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_READ_EX 105 +# define BIO_F_BIO_READ_INTERN 120 +# define BIO_F_BIO_SOCKET 140 +# define BIO_F_BIO_SOCKET_NBIO 142 +# define BIO_F_BIO_SOCK_INFO 141 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BIO_WRITE_EX 119 +# define BIO_F_BIO_WRITE_INTERN 128 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_NEW 149 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_DOAPR_OUTCH 150 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_LINEBUFFER_NEW 151 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_NBIOF_NEW 154 +# define BIO_F_SLG_WRITE 155 +# define BIO_F_SSL_NEW 118 + +/* + * BIO reason codes. + */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET 141 +# define BIO_R_AMBIGUOUS_HOST_OR_SERVICE 129 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_GETSOCKNAME_ERROR 132 +# define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 +# define BIO_R_GETTING_SOCKTYPE 134 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_SOCKET 135 +# define BIO_R_IN_USE 123 +# define BIO_R_LENGTH_TOO_LONG 102 +# define BIO_R_LISTEN_V6_ONLY 136 +# define BIO_R_LOOKUP_RETURNED_NOTHING 142 +# define BIO_R_MALFORMED_HOST_OR_SERVICE 130 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 +# define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_KEEPALIVE 137 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNABLE_TO_NODELAY 138 +# define BIO_R_UNABLE_TO_REUSEADDR 139 +# define BIO_R_UNAVAILABLE_IP_FAMILY 145 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNKNOWN_INFO_TYPE 140 +# define BIO_R_UNSUPPORTED_IP_FAMILY 146 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/blowfish.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/blowfish.h new file mode 100644 index 00000000..cd3e460e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/blowfish.h @@ -0,0 +1,61 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include + +# ifndef OPENSSL_NO_BF +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define BF_LONG unsigned int + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/bn.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bn.h new file mode 100644 index 00000000..8af05d00 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bn.h @@ -0,0 +1,539 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 64-bit processor with LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULONG unsigned long +# define BN_BYTES 8 +# endif + +/* + * 64-bit processor other than LP64 ABI + */ +# ifdef SIXTY_FOUR_BIT +# define BN_ULONG unsigned long long +# define BN_BYTES 8 +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_ULONG unsigned int +# define BN_BYTES 4 +# endif + +# define BN_BITS2 (BN_BYTES * 8) +# define BN_BITS (BN_BITS2 * 2) +# define BN_TBIT ((BN_ULONG)1 << (BN_BITS2 - 1)) + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 +# define BN_FLG_SECURE 0x08 + +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +# define BN_FLG_FREE 0x8000 /* used for debugging */ +# endif + +void BN_set_flags(BIGNUM *b, int n); +int BN_get_flags(const BIGNUM *b, int n); + +/* Values for |top| in BN_rand() */ +#define BN_RAND_TOP_ANY -1 +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +/* Values for |bottom| in BN_rand() */ +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot be used in parallel!). Also only for *read only* use. The + * value |dest| should be a newly allocated BIGNUM obtained via BN_new() that + * has not been otherwise initialised or used. + */ +void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags); + +/* Wrapper function to make using BN_GENCB easier */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); + +BN_GENCB *BN_GENCB_new(void); +void BN_GENCB_free(BN_GENCB *cb); + +/* Populate a BN_GENCB structure with an "old"-style callback */ +void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *), + void *cb_arg); + +/* Populate a BN_GENCB structure with a "new"-style callback */ +void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *), + void *cb_arg); + +void *BN_GENCB_get_arg(BN_GENCB *cb); + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations + * that will be done for checking that a random number is probably prime. The + * error rate for accepting a composite number as prime depends on the size of + * the prime |b|. The error rates used are for calculating an RSA key with 2 primes, + * and so the level is what you would expect for a key of double the size of the + * prime. + * + * This table is generated using the algorithm of FIPS PUB 186-4 + * Digital Signature Standard (DSS), section F.1, page 117. + * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) + * + * The following magma script was used to generate the output: + * securitybits:=125; + * k:=1024; + * for t:=1 to 65 do + * for M:=3 to Floor(2*Sqrt(k-1)-1) do + * S:=0; + * // Sum over m + * for m:=3 to M do + * s:=0; + * // Sum over j + * for j:=2 to m do + * s+:=(RealField(32)!2)^-(j+(k-1)/j); + * end for; + * S+:=2^(m-(m-1)*t)*s; + * end for; + * A:=2^(k-2-M*t); + * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; + * pkt:=2.00743*Log(2)*k*2^-k*(A+B); + * seclevel:=Floor(-Log(2,pkt)); + * if seclevel ge securitybits then + * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; + * break; + * end if; + * end for; + * if seclevel ge securitybits then break; end if; + * end for; + * + * It can be run online at: + * http://magma.maths.usyd.edu.au/calc + * + * And will output: + * k: 1024, security: 129 bits (t: 6, M: 23) + * + * k is the number of bits of the prime, securitybits is the level we want to + * reach. + * + * prime length | RSA key size | # MR tests | security level + * -------------+--------------|------------+--------------- + * (b) >= 6394 | >= 12788 | 3 | 256 bit + * (b) >= 3747 | >= 7494 | 3 | 192 bit + * (b) >= 1345 | >= 2690 | 4 | 128 bit + * (b) >= 1080 | >= 2160 | 5 | 128 bit + * (b) >= 852 | >= 1704 | 5 | 112 bit + * (b) >= 476 | >= 952 | 5 | 80 bit + * (b) >= 400 | >= 800 | 6 | 80 bit + * (b) >= 347 | >= 694 | 7 | 80 bit + * (b) >= 308 | >= 616 | 8 | 80 bit + * (b) >= 55 | >= 110 | 27 | 64 bit + * (b) >= 6 | >= 12 | 34 | 64 bit + */ + +# define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ + (b) >= 1345 ? 4 : \ + (b) >= 476 ? 5 : \ + (b) >= 400 ? 6 : \ + (b) >= 347 ? 7 : \ + (b) >= 308 ? 8 : \ + (b) >= 55 ? 27 : \ + /* b >= 6 */ 34) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_zero(const BIGNUM *a); +int BN_is_one(const BIGNUM *a); +int BN_is_word(const BIGNUM *a, const BN_ULONG w); +int BN_is_odd(const BIGNUM *a); + +# define BN_one(a) (BN_set_word((a),1)) + +void BN_zero_ex(BIGNUM *a); + +# if OPENSSL_API_COMPAT >= 0x00908000L +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +BN_CTX *BN_CTX_secure_new(void); +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG l); +int BN_security_bits(int L, int N); +BIGNUM *BN_new(void); +BIGNUM *BN_secure_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param b pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +int BN_is_negative(const BIGNUM *b); + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_STDIO +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +int BN_print(BIO *bio, const BIGNUM *a); +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +DEPRECATEDIN_0_9_8(BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, + const BIGNUM *rem, + void (*callback) (int, int, + void *), + void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg)) +DEPRECATEDIN_0_9_8(int + BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg, + int do_trial_division)) + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); + +int BN_BLINDING_is_current_thread(BN_BLINDING *b); +void BN_BLINDING_set_current_thread(BN_BLINDING *b); +int BN_BLINDING_lock(BN_BLINDING *b); +int BN_BLINDING_unlock(BN_BLINDING *b); + +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +DEPRECATEDIN_0_9_8(void BN_set_params(int mul, int high, int low, int mont)) +DEPRECATEDIN_0_9_8(int BN_get_params(int which)) /* 0, mul, 1 high, 2 low, 3 + * mont */ + +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a, + const BIGNUM *field, BN_CTX *ctx); + +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, + const BIGNUM *priv, const unsigned char *message, + size_t message_len, BN_CTX *ctx); + +/* Primes from RFC 2409 */ +BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define get_rfc2409_prime_768 BN_get_rfc2409_prime_768 +# define get_rfc2409_prime_1024 BN_get_rfc2409_prime_1024 +# define get_rfc3526_prime_1536 BN_get_rfc3526_prime_1536 +# define get_rfc3526_prime_2048 BN_get_rfc3526_prime_2048 +# define get_rfc3526_prime_3072 BN_get_rfc3526_prime_3072 +# define get_rfc3526_prime_4096 BN_get_rfc3526_prime_4096 +# define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144 +# define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192 +# endif + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/bnerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bnerr.h new file mode 100644 index 00000000..9f3c7cfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/bnerr.h @@ -0,0 +1,100 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BNERR_H +# define HEADER_BNERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BN_strings(void); + +/* + * BN function codes. + */ +# define BN_F_BNRAND 127 +# define BN_F_BNRAND_RANGE 138 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_COMPUTE_WNAF 142 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GENCB_NEW 143 +# define BN_F_BN_GENERATE_DSA_NONCE 140 +# define BN_F_BN_GENERATE_PRIME_EX 141 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MONT_CTX_NEW 149 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_POOL_GET 147 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RECP_CTX_NEW 150 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_SET_WORDS 144 +# define BN_F_BN_STACK_PUSH 148 +# define BN_F_BN_USUB 115 + +/* + * BN reason codes. + */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_PRIVATE_KEY_TOO_LARGE 117 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffer.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffer.h new file mode 100644 index 00000000..d2765766 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffer.h @@ -0,0 +1,58 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include +# ifndef HEADER_CRYPTO_H +# include +# endif +# include + + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include + +/* + * These names are outdated as of OpenSSL 1.1; a future release + * will move them to be deprecated. + */ +# define BUF_strdup(s) OPENSSL_strdup(s) +# define BUF_strndup(s, size) OPENSSL_strndup(s, size) +# define BUF_memdup(data, size) OPENSSL_memdup(data, size) +# define BUF_strlcpy(dst, src, size) OPENSSL_strlcpy(dst, src, size) +# define BUF_strlcat(dst, src, size) OPENSSL_strlcat(dst, src, size) +# define BUF_strnlen(str, maxlen) OPENSSL_strnlen(str, maxlen) + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ + unsigned long flags; +}; + +# define BUF_MEM_FLAG_SECURE 0x01 + +BUF_MEM *BUF_MEM_new(void); +BUF_MEM *BUF_MEM_new_ex(unsigned long flags); +void BUF_MEM_free(BUF_MEM *a); +size_t BUF_MEM_grow(BUF_MEM *str, size_t len); +size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffererr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffererr.h new file mode 100644 index 00000000..04f6ff7a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/buffererr.h @@ -0,0 +1,34 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BUFERR_H +# define HEADER_BUFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_BUF_strings(void); + +/* + * BUF function codes. + */ +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 + +/* + * BUF reason codes. + */ + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/camellia.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/camellia.h new file mode 100644 index 00000000..151f3c13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/camellia.h @@ -0,0 +1,83 @@ +/* + * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include + +# ifndef OPENSSL_NO_CAMELLIA +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cast.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cast.h new file mode 100644 index 00000000..2cc89ae0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cast.h @@ -0,0 +1,53 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +# include + +# ifndef OPENSSL_NO_CAST +# ifdef __cplusplus +extern "C" { +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmac.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmac.h new file mode 100644 index 00000000..3535a9ab --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmac.h @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +# ifndef OPENSSL_NO_CMAC + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cms.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cms.h new file mode 100644 index 00000000..c7627968 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cms.h @@ -0,0 +1,339 @@ +/* + * Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include + +# ifndef OPENSSL_NO_CMS +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DEFINE_STACK_OF(CMS_SignerInfo) +DEFINE_STACK_OF(CMS_RecipientEncryptedKey) +DEFINE_STACK_OF(CMS_RecipientInfo) +DEFINE_STACK_OF(CMS_RevocationInfoChoice) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 +# define CMS_ASCIICRLF 0x80000 + +const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + const unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* Backward compatibility for spelling errors. */ +# define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \ + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmserr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmserr.h new file mode 100644 index 00000000..7dbc13dc --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cmserr.h @@ -0,0 +1,202 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CMSERR_H +# define HEADER_CMSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CMS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CMS_strings(void); + +/* + * CMS function codes. + */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT 179 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_ENV_ASN1_CTRL 171 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SD_ASN1_CTRL 170 +# define CMS_F_CMS_SET1_IAS 176 +# define CMS_F_CMS_SET1_KEYID 177 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_SI_CHECK_ATTRIBUTES 183 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 +# define CMS_F_KEK_UNWRAP_KEY 180 + +/* + * CMS reason codes. + */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_ATTRIBUTE_ERROR 161 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_AGREEMENT 181 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/comp.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/comp.h new file mode 100644 index 00000000..d814d3cf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/comp.h @@ -0,0 +1,53 @@ +/* + * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include + +# ifndef OPENSSL_NO_COMP +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx); +int COMP_CTX_get_type(const COMP_CTX* comp); +int COMP_get_type(const COMP_METHOD *meth); +const char *COMP_get_name(const COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); + +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); + +COMP_METHOD *COMP_zlib(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +#define COMP_zlib_cleanup() while(0) continue +#endif + +# ifdef HEADER_BIO_H +# ifdef ZLIB +const BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/comperr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/comperr.h new file mode 100644 index 00000000..90231e9a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/comperr.h @@ -0,0 +1,44 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_COMPERR_H +# define HEADER_COMPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_COMP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_COMP_strings(void); + +/* + * COMP function codes. + */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 +# define COMP_F_COMP_CTX_NEW 103 + +/* + * COMP reason codes. + */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf.h new file mode 100644 index 00000000..7336cd2f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf.h @@ -0,0 +1,168 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DEFINE_STACK_OF(CONF_VALUE) +DEFINE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DEFINE_STACK_OF(CONF_MODULE) +DEFINE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_STDIO +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +#ifndef OPENSSL_NO_STDIO +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +#endif +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name)) + +#if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_no_config() \ + OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL) +#endif + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_STDIO +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +#ifndef OPENSSL_NO_STDIO +int NCONF_dump_fp(const CONF *conf, FILE *out); +#endif +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +#if OPENSSL_API_COMPAT < 0x10100000L +# define CONF_modules_free() while(0) continue +#endif +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf_api.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf_api.h new file mode 100644 index 00000000..a0275ad7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conf_api.h @@ -0,0 +1,40 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/conferr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conferr.h new file mode 100644 index 00000000..32b92291 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/conferr.h @@ -0,0 +1,76 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CONFERR_H +# define HEADER_CONFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CONF_strings(void); + +/* + * CONF function codes. + */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_GET_NEXT_FILE 107 +# define CONF_F_MODULE_ADD 122 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_PROCESS_INCLUDE 116 +# define CONF_F_SSL_MODULE_INIT 123 +# define CONF_F_STR_COPY 101 + +/* + * CONF reason codes. + */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_NUMBER_TOO_LARGE 121 +# define CONF_R_RECURSIVE_DIRECTORY_INCLUDE 111 +# define CONF_R_SSL_COMMAND_SECTION_EMPTY 117 +# define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND 118 +# define CONF_R_SSL_SECTION_EMPTY 119 +# define CONF_R_SSL_SECTION_NOT_FOUND 120 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/crypto.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/crypto.h new file mode 100644 index 00000000..7d0b5262 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/crypto.h @@ -0,0 +1,445 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include +# include + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif + +# include +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSLeay OpenSSL_version_num +# define SSLeay_version OpenSSL_version +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION OPENSSL_VERSION +# define SSLEAY_CFLAGS OPENSSL_CFLAGS +# define SSLEAY_BUILT_ON OPENSSL_BUILT_ON +# define SSLEAY_PLATFORM OPENSSL_PLATFORM +# define SSLEAY_DIR OPENSSL_DIR + +/* + * Old type for allocating dynamic locks. No longer used. Use the new thread + * API instead. + */ +typedef struct { + int dummy; +} CRYPTO_dynlock; + +# endif /* OPENSSL_API_COMPAT */ + +typedef void CRYPTO_RWLOCK; + +CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); +int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); +void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); + +int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); + +/* + * The following can be used to detect memory leaks in the library. If + * used, it turns on malloc checking + */ +# define CRYPTO_MEM_CHECK_OFF 0x0 /* Control only */ +# define CRYPTO_MEM_CHECK_ON 0x1 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3 /* Control only */ + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; +DEFINE_STACK_OF(void) + +/* + * Per class, we have a STACK of function pointers. + */ +# define CRYPTO_EX_INDEX_SSL 0 +# define CRYPTO_EX_INDEX_SSL_CTX 1 +# define CRYPTO_EX_INDEX_SSL_SESSION 2 +# define CRYPTO_EX_INDEX_X509 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_DH 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_EC_KEY 8 +# define CRYPTO_EX_INDEX_RSA 9 +# define CRYPTO_EX_INDEX_ENGINE 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_BIO 12 +# define CRYPTO_EX_INDEX_APP 13 +# define CRYPTO_EX_INDEX_UI_METHOD 14 +# define CRYPTO_EX_INDEX_DRBG 15 +# define CRYPTO_EX_INDEX__COUNT 16 + +/* No longer needed, so this is a no-op */ +#define OPENSSL_malloc_init() while(0) continue + +int CRYPTO_mem_ctrl(int mode); + +# define OPENSSL_malloc(num) \ + CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_zalloc(num) \ + CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_realloc(addr, num) \ + CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_realloc(addr, old_num, num) \ + CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_free(addr, num) \ + CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_free(addr) \ + CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_memdup(str, s) \ + CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strdup(str) \ + CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strndup(str, n) \ + CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_malloc(num) \ + CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_zalloc(num) \ + CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_free(addr) \ + CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_clear_free(addr, num) \ + CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_actual_size(ptr) \ + CRYPTO_secure_actual_size(ptr) + +size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz); +size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz); +size_t OPENSSL_strnlen(const char *str, size_t maxlen); +char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); +unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); +int OPENSSL_hexchar2int(unsigned char c); + +# define OPENSSL_MALLOC_MAX_NELEMS(type) (((1U<<(sizeof(int)*8-1))-1)/sizeof(type)) + +unsigned long OpenSSL_version_num(void); +const char *OpenSSL_version(int type); +# define OPENSSL_VERSION 0 +# define OPENSSL_CFLAGS 1 +# define OPENSSL_BUILT_ON 2 +# define OPENSSL_PLATFORM 3 +# define OPENSSL_DIR 4 +# define OPENSSL_ENGINES_DIR 5 + +int OPENSSL_issetugid(void); + +typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* No longer use an index. */ +int CRYPTO_free_ex_index(int class_index, int idx); + +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + const CRYPTO_EX_DATA *from); + +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); + +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +# define CRYPTO_cleanup_all_ex_data() while(0) continue + +/* + * The old locking functions have been removed completely without compatibility + * macros. This is because the old functions either could not properly report + * errors, or the returned error values were not clearly documented. + * Replacing the locking functions with no-ops would cause race condition + * issues in the affected applications. It is far better for them to fail at + * compile time. + * On the other hand, the locking callbacks are no longer used. Consequently, + * the callback management functions can be safely replaced with no-op macros. + */ +# define CRYPTO_num_locks() (1) +# define CRYPTO_set_locking_callback(func) +# define CRYPTO_get_locking_callback() (NULL) +# define CRYPTO_set_add_lock_callback(func) +# define CRYPTO_get_add_lock_callback() (NULL) + +/* + * These defines where used in combination with the old locking callbacks, + * they are not called anymore, but old code that's not called might still + * use them. + */ +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +/* This structure is no longer used */ +typedef struct crypto_threadid_st { + int dummy; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +# define CRYPTO_THREADID_set_numeric(id, val) +# define CRYPTO_THREADID_set_pointer(id, ptr) +# define CRYPTO_THREADID_set_callback(threadid_func) (0) +# define CRYPTO_THREADID_get_callback() (NULL) +# define CRYPTO_THREADID_current(id) +# define CRYPTO_THREADID_cmp(a, b) (-1) +# define CRYPTO_THREADID_cpy(dest, src) +# define CRYPTO_THREADID_hash(id) (0UL) + +# if OPENSSL_API_COMPAT < 0x10000000L +# define CRYPTO_set_id_callback(func) +# define CRYPTO_get_id_callback() (NULL) +# define CRYPTO_thread_id() (0UL) +# endif /* OPENSSL_API_COMPAT < 0x10000000L */ + +# define CRYPTO_set_dynlock_create_callback(dyn_create_function) +# define CRYPTO_set_dynlock_lock_callback(dyn_lock_function) +# define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function) +# define CRYPTO_get_dynlock_create_callback() (NULL) +# define CRYPTO_get_dynlock_lock_callback() (NULL) +# define CRYPTO_get_dynlock_destroy_callback() (NULL) +# endif /* OPENSSL_API_COMPAT < 0x10100000L */ + +int CRYPTO_set_mem_functions( + void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, int), + void (*f) (void *, const char *, int)); +int CRYPTO_set_mem_debug(int flag); +void CRYPTO_get_mem_functions( + void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, int), + void (**f) (void *, const char *, int)); + +void *CRYPTO_malloc(size_t num, const char *file, int line); +void *CRYPTO_zalloc(size_t num, const char *file, int line); +void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line); +void CRYPTO_free(void *ptr, const char *file, int line); +void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line); +void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line); +void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, + const char *file, int line); + +int CRYPTO_secure_malloc_init(size_t sz, int minsize); +int CRYPTO_secure_malloc_done(void); +void *CRYPTO_secure_malloc(size_t num, const char *file, int line); +void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); +void CRYPTO_secure_free(void *ptr, const char *file, int line); +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); +int CRYPTO_secure_allocated(const void *ptr); +int CRYPTO_secure_malloc_initialized(void); +size_t CRYPTO_secure_actual_size(void *ptr); +size_t CRYPTO_secure_used(void); + +void OPENSSL_cleanse(void *ptr, size_t len); + +# ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_mem_debug_push(info) \ + CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_mem_debug_pop() \ + CRYPTO_mem_debug_pop() +int CRYPTO_mem_debug_push(const char *info, const char *file, int line); +int CRYPTO_mem_debug_pop(void); +void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount); + +/*- + * Debugging functions (enabled by CRYPTO_set_mem_debug(1)) + * The flag argument has the following significance: + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag, + const char *file, int line); +void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line); + +int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +int CRYPTO_mem_leaks_fp(FILE *); +# endif +int CRYPTO_mem_leaks(BIO *bio); +# endif + +/* die if we have to */ +ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line); +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l)) +# endif +# define OPENSSL_assert(e) \ + (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1)) + +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); +# ifdef OPENSSL_SYS_UNIX +void OPENSSL_fork_prepare(void); +void OPENSSL_fork_parent(void); +void OPENSSL_fork_child(void); +# endif + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to); + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len); + +/* Standard initialisation options */ +# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L +# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L +# define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L +# define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L +# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0x00000010L +# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0x00000020L +# define OPENSSL_INIT_LOAD_CONFIG 0x00000040L +# define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000080L +# define OPENSSL_INIT_ASYNC 0x00000100L +# define OPENSSL_INIT_ENGINE_RDRAND 0x00000200L +# define OPENSSL_INIT_ENGINE_DYNAMIC 0x00000400L +# define OPENSSL_INIT_ENGINE_OPENSSL 0x00000800L +# define OPENSSL_INIT_ENGINE_CRYPTODEV 0x00001000L +# define OPENSSL_INIT_ENGINE_CAPI 0x00002000L +# define OPENSSL_INIT_ENGINE_PADLOCK 0x00004000L +# define OPENSSL_INIT_ENGINE_AFALG 0x00008000L +/* OPENSSL_INIT_ZLIB 0x00010000L */ +# define OPENSSL_INIT_ATFORK 0x00020000L +/* OPENSSL_INIT_BASE_ONLY 0x00040000L */ +# define OPENSSL_INIT_NO_ATEXIT 0x00080000L +/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */ +/* Max OPENSSL_INIT flag value is 0x80000000 */ + +/* openssl and dasync not counted as builtin */ +# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \ + (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \ + | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \ + OPENSSL_INIT_ENGINE_PADLOCK) + + +/* Library initialisation functions */ +void OPENSSL_cleanup(void); +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_atexit(void (*handler)(void)); +void OPENSSL_thread_stop(void); + +/* Low-level control of initialization */ +OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); +# ifndef OPENSSL_NO_STDIO +int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, + const char *config_filename); +void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, + unsigned long flags); +int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, + const char *config_appname); +# endif +void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); + +# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +# if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include in order to use this */ +typedef DWORD CRYPTO_THREAD_LOCAL; +typedef DWORD CRYPTO_THREAD_ID; + +typedef LONG CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif +# else +# include +typedef pthread_once_t CRYPTO_ONCE; +typedef pthread_key_t CRYPTO_THREAD_LOCAL; +typedef pthread_t CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif +# endif + +# if !defined(CRYPTO_ONCE_STATIC_INIT) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif + +int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + +int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); +void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); +int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); +int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); + +CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); +int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cryptoerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cryptoerr.h new file mode 100644 index 00000000..3db5a4ee --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cryptoerr.h @@ -0,0 +1,57 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CRYPTOERR_H +# define HEADER_CRYPTOERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CRYPTO_strings(void); + +/* + * CRYPTO function codes. + */ +# define CRYPTO_F_CMAC_CTX_NEW 120 +# define CRYPTO_F_CRYPTO_DUP_EX_DATA 110 +# define CRYPTO_F_CRYPTO_FREE_EX_DATA 111 +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_MEMDUP 115 +# define CRYPTO_F_CRYPTO_NEW_EX_DATA 112 +# define CRYPTO_F_CRYPTO_OCB128_COPY_CTX 121 +# define CRYPTO_F_CRYPTO_OCB128_INIT 122 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_GET_AND_LOCK 113 +# define CRYPTO_F_OPENSSL_ATEXIT 114 +# define CRYPTO_F_OPENSSL_BUF2HEXSTR 117 +# define CRYPTO_F_OPENSSL_FOPEN 119 +# define CRYPTO_F_OPENSSL_HEXSTR2BUF 118 +# define CRYPTO_F_OPENSSL_INIT_CRYPTO 116 +# define CRYPTO_F_OPENSSL_LH_NEW 126 +# define CRYPTO_F_OPENSSL_SK_DEEP_COPY 127 +# define CRYPTO_F_OPENSSL_SK_DUP 128 +# define CRYPTO_F_PKEY_HMAC_INIT 123 +# define CRYPTO_F_PKEY_POLY1305_INIT 124 +# define CRYPTO_F_PKEY_SIPHASH_INIT 125 +# define CRYPTO_F_SK_RESERVE 129 + +/* + * CRYPTO reason codes. + */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 +# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ct.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ct.h new file mode 100644 index 00000000..ebdba34d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ct.h @@ -0,0 +1,474 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CT_H +# define HEADER_CT_H + +# include + +# ifndef OPENSSL_NO_CT +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + +/* Minimum RSA key size, from RFC6962 */ +# define SCT_MIN_RSA_BITS 2048 + +/* All hashes are SHA256 in v1 of Certificate Transparency */ +# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH + +typedef enum { + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1 +} ct_log_entry_type_t; + +typedef enum { + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0 +} sct_version_t; + +typedef enum { + SCT_SOURCE_UNKNOWN, + SCT_SOURCE_TLS_EXTENSION, + SCT_SOURCE_X509V3_EXTENSION, + SCT_SOURCE_OCSP_STAPLED_RESPONSE +} sct_source_t; + +typedef enum { + SCT_VALIDATION_STATUS_NOT_SET, + SCT_VALIDATION_STATUS_UNKNOWN_LOG, + SCT_VALIDATION_STATUS_VALID, + SCT_VALIDATION_STATUS_INVALID, + SCT_VALIDATION_STATUS_UNVERIFIED, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION +} sct_validation_status_t; + +DEFINE_STACK_OF(SCT) +DEFINE_STACK_OF(CTLOG) + +/****************************************** + * CT policy evaluation context functions * + ******************************************/ + +/* + * Creates a new, empty policy evaluation context. + * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished + * with the CT_POLICY_EVAL_CTX. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); + +/* Deletes a policy evaluation context and anything it owns. */ +void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); + +/* Gets the peer certificate that the SCTs are for */ +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the certificate associated with the received SCTs. + * Increments the reference count of cert. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); + +/* Gets the issuer of the aforementioned certificate */ +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the issuer of the certificate associated with the received SCTs. + * Increments the reference count of issuer. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); + +/* Gets the CT logs that are trusted sources of SCTs */ +const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); + +/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */ +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store); + +/* + * Gets the time, in milliseconds since the Unix epoch, that will be used as the + * current time when checking whether an SCT was issued in the future. + * Such SCTs will fail validation, as required by RFC6962. + */ +uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch. + * If an SCT's timestamp is after this time, it will be interpreted as having + * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs + * whose timestamp is in the future", so an SCT will not validate in this case. + */ +void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); + +/***************** + * SCT functions * + *****************/ + +/* + * Creates a new, blank SCT. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new(void); + +/* + * Creates a new SCT from some base64-encoded strings. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new_from_base64(unsigned char version, + const char *logid_base64, + ct_log_entry_type_t entry_type, + uint64_t timestamp, + const char *extensions_base64, + const char *signature_base64); + +/* + * Frees the SCT and the underlying data structures. + */ +void SCT_free(SCT *sct); + +/* + * Free a stack of SCTs, and the underlying SCTs themselves. + * Intended to be compatible with X509V3_EXT_FREE. + */ +void SCT_LIST_free(STACK_OF(SCT) *a); + +/* + * Returns the version of the SCT. + */ +sct_version_t SCT_get_version(const SCT *sct); + +/* + * Set the version of an SCT. + * Returns 1 on success, 0 if the version is unrecognized. + */ +__owur int SCT_set_version(SCT *sct, sct_version_t version); + +/* + * Returns the log entry type of the SCT. + */ +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct); + +/* + * Set the log entry type of an SCT. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type); + +/* + * Gets the ID of the log that an SCT came from. + * Ownership of the log ID remains with the SCT. + * Returns the length of the log ID. + */ +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id); + +/* + * Set the log ID of an SCT to point directly to the *log_id specified. + * The SCT takes ownership of the specified pointer. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len); + +/* + * Set the log ID of an SCT. + * This makes a copy of the log_id. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, + size_t log_id_len); + +/* + * Returns the timestamp for the SCT (epoch time in milliseconds). + */ +uint64_t SCT_get_timestamp(const SCT *sct); + +/* + * Set the timestamp of an SCT (epoch time in milliseconds). + */ +void SCT_set_timestamp(SCT *sct, uint64_t timestamp); + +/* + * Return the NID for the signature used by the SCT. + * For CT v1, this will be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset). + */ +int SCT_get_signature_nid(const SCT *sct); + +/* + * Set the signature type of an SCT + * For CT v1, this should be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_signature_nid(SCT *sct, int nid); + +/* + * Set *ext to point to the extension data for the SCT. ext must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext); + +/* + * Set the extensions of an SCT to point directly to the *ext specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len); + +/* + * Set the extensions of an SCT. + * This takes a copy of the ext. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext, + size_t ext_len); + +/* + * Set *sig to point to the signature for the SCT. sig must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig); + +/* + * Set the signature of an SCT to point directly to the *sig specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len); + +/* + * Set the signature of an SCT to be a copy of the *sig specified. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig, + size_t sig_len); + +/* + * The origin of this SCT, e.g. TLS extension, OCSP response, etc. + */ +sct_source_t SCT_get_source(const SCT *sct); + +/* + * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_source(SCT *sct, sct_source_t source); + +/* + * Returns a text string describing the validation status of |sct|. + */ +const char *SCT_validation_status_string(const SCT *sct); + +/* + * Pretty-prints an |sct| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came + * from, so that the log name can be printed. + */ +void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs); + +/* + * Pretty-prints an |sct_list| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * SCTs will be delimited by |separator|. + * If |logs| is not NULL, it will be used to lookup the CT log that each SCT + * came from, so that the log names can be printed. + */ +void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *logs); + +/* + * Gets the last result of validating this SCT. + * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET. + */ +sct_validation_status_t SCT_get_validation_status(const SCT *sct); + +/* + * Validates the given SCT with the provided context. + * Sets the "validation_status" field of the SCT. + * Returns 1 if the SCT is valid and the signature verifies. + * Returns 0 if the SCT is invalid or could not be verified. + * Returns -1 if an error occurs. + */ +__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); + +/* + * Validates the given list of SCTs with the provided context. + * Sets the "validation_status" field of each SCT. + * Returns 1 if there are no invalid SCTs and all signatures verify. + * Returns 0 if at least one SCT is invalid or could not be verified. + * Returns a negative integer if an error occurs. + */ +__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts, + CT_POLICY_EVAL_CTX *ctx); + + +/********************************* + * SCT parsing and serialisation * + *********************************/ + +/* + * Serialize (to TLS format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just return the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Convert TLS format SCT list to a stack of SCTs. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + size_t len); + +/* + * Serialize (to DER format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just returns the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Parses an SCT list in DER format and returns it. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + long len); + +/* + * Serialize (to TLS format) an |sct| and write it to |out|. + * If |out| is null, no SCT will be output but the length will still be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format SCT. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the TLS-format SCT will be written + * to it. + * The length of the SCT in TLS format will be returned. + */ +__owur int i2o_SCT(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT in TLS format and returns it. + * If |psct| is not null, it will end up pointing to the parsed SCT. If it + * already points to a non-null pointer, the pointer will be free'd. + * |in| should be a pointer to a string containing the TLS-format SCT. + * |in| will be advanced to the end of the SCT if parsing succeeds. + * |len| should be the length of the SCT in |in|. + * Returns NULL if an error occurs. + * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len' + * fields will be populated (with |in| and |len| respectively). + */ +SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); + +/******************** + * CT log functions * + ********************/ + +/* + * Creates a new CT log instance with the given |public_key| and |name|. + * Takes ownership of |public_key| but copies |name|. + * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); + +/* + * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER + * in |pkey_base64|. The |name| is a string to help users identify this log. + * Returns 1 on success, 0 on failure. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +int CTLOG_new_from_base64(CTLOG ** ct_log, + const char *pkey_base64, const char *name); + +/* + * Deletes a CT log instance and its fields. + */ +void CTLOG_free(CTLOG *log); + +/* Gets the name of the CT log */ +const char *CTLOG_get0_name(const CTLOG *log); +/* Gets the ID of the CT log */ +void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, + size_t *log_id_len); +/* Gets the public key of the CT log */ +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); + +/************************** + * CT log store functions * + **************************/ + +/* + * Creates a new CT log store. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new(void); + +/* + * Deletes a CT log store and all of the CT log instances held within. + */ +void CTLOG_STORE_free(CTLOG_STORE *store); + +/* + * Finds a CT log in the store based on its log ID. + * Returns the CT log, or NULL if no match is found. + */ +const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, + const uint8_t *log_id, + size_t log_id_len); + +/* + * Loads a CT log list into a |store| from a |file|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file); + +/* + * Loads the default CT log list into a |store|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/cterr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cterr.h new file mode 100644 index 00000000..feb7bc56 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/cterr.h @@ -0,0 +1,80 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_CTERR_H +# define HEADER_CTERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_CT + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_CT_strings(void); + +/* + * CT function codes. + */ +# define CT_F_CTLOG_NEW 117 +# define CT_F_CTLOG_NEW_FROM_BASE64 118 +# define CT_F_CTLOG_NEW_FROM_CONF 119 +# define CT_F_CTLOG_STORE_LOAD_CTX_NEW 122 +# define CT_F_CTLOG_STORE_LOAD_FILE 123 +# define CT_F_CTLOG_STORE_LOAD_LOG 130 +# define CT_F_CTLOG_STORE_NEW 131 +# define CT_F_CT_BASE64_DECODE 124 +# define CT_F_CT_POLICY_EVAL_CTX_NEW 133 +# define CT_F_CT_V1_LOG_ID_FROM_PKEY 125 +# define CT_F_I2O_SCT 107 +# define CT_F_I2O_SCT_LIST 108 +# define CT_F_I2O_SCT_SIGNATURE 109 +# define CT_F_O2I_SCT 110 +# define CT_F_O2I_SCT_LIST 111 +# define CT_F_O2I_SCT_SIGNATURE 112 +# define CT_F_SCT_CTX_NEW 126 +# define CT_F_SCT_CTX_VERIFY 128 +# define CT_F_SCT_NEW 100 +# define CT_F_SCT_NEW_FROM_BASE64 127 +# define CT_F_SCT_SET0_LOG_ID 101 +# define CT_F_SCT_SET1_EXTENSIONS 114 +# define CT_F_SCT_SET1_LOG_ID 115 +# define CT_F_SCT_SET1_SIGNATURE 116 +# define CT_F_SCT_SET_LOG_ENTRY_TYPE 102 +# define CT_F_SCT_SET_SIGNATURE_NID 103 +# define CT_F_SCT_SET_VERSION 104 + +/* + * CT reason codes. + */ +# define CT_R_BASE64_DECODE_ERROR 108 +# define CT_R_INVALID_LOG_ID_LENGTH 100 +# define CT_R_LOG_CONF_INVALID 109 +# define CT_R_LOG_CONF_INVALID_KEY 110 +# define CT_R_LOG_CONF_MISSING_DESCRIPTION 111 +# define CT_R_LOG_CONF_MISSING_KEY 112 +# define CT_R_LOG_KEY_INVALID 113 +# define CT_R_SCT_FUTURE_TIMESTAMP 116 +# define CT_R_SCT_INVALID 104 +# define CT_R_SCT_INVALID_SIGNATURE 107 +# define CT_R_SCT_LIST_INVALID 105 +# define CT_R_SCT_LOG_ID_MISMATCH 114 +# define CT_R_SCT_NOT_SET 106 +# define CT_R_SCT_UNSUPPORTED_VERSION 115 +# define CT_R_UNRECOGNIZED_SIGNATURE_NID 101 +# define CT_R_UNSUPPORTED_ENTRY_TYPE 102 +# define CT_R_UNSUPPORTED_VERSION 103 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/des.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/des.h new file mode 100644 index 00000000..be4abbdf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/des.h @@ -0,0 +1,174 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include + +# ifndef OPENSSL_NO_DES +# ifdef __cplusplus +extern "C" { +# endif +# include + +typedef unsigned int DES_LONG; + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +# define DES_fixup_key_parity DES_set_odd_parity + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/dh.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dh.h new file mode 100644 index 00000000..3527540c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dh.h @@ -0,0 +1,340 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include + +# ifndef OPENSSL_NO_DH +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + +# define DH_FLAG_CACHE_MONT_P 0x01 + +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +DECLARE_ASN1_ITEM(DHparams) + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 +# define DH_CHECK_Q_NOT_PRIME 0x10 +# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_PUBKEY_INVALID 0x04 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_bits(const DH *dh); +int DH_size(const DH *dh); +int DH_security_bits(const DH *dh); +#define DH_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, l, p, newf, dupf, freef) +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check_params_ex(const DH *dh); +int DH_check_ex(const DH *dh); +int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key); +int DH_check_params(const DH *dh, int *ret); +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); +int i2d_DHxparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_STDIO +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +int DHparams_print(BIO *bp, const DH *x); + +/* RFC 5114 parameters */ +DH *DH_get_1024_160(void); +DH *DH_get_2048_224(void); +DH *DH_get_2048_256(void); + +/* Named parameters, currently RFC7919 */ +DH *DH_new_by_nid(int nid); +int DH_get_nid(const DH *dh); + +# ifndef OPENSSL_NO_CMS +/* RFC2631 KDF */ +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif + +void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DH_get0_p(const DH *dh); +const BIGNUM *DH_get0_q(const DH *dh); +const BIGNUM *DH_get0_g(const DH *dh); +const BIGNUM *DH_get0_priv_key(const DH *dh); +const BIGNUM *DH_get0_pub_key(const DH *dh); +void DH_clear_flags(DH *dh, int flags); +int DH_test_flags(const DH *dh, int flags); +void DH_set_flags(DH *dh, int flags); +ENGINE *DH_get0_engine(DH *d); +long DH_get_length(const DH *dh); +int DH_set_length(DH *dh, long length); + +DH_METHOD *DH_meth_new(const char *name, int flags); +void DH_meth_free(DH_METHOD *dhm); +DH_METHOD *DH_meth_dup(const DH_METHOD *dhm); +const char *DH_meth_get0_name(const DH_METHOD *dhm); +int DH_meth_set1_name(DH_METHOD *dhm, const char *name); +int DH_meth_get_flags(const DH_METHOD *dhm); +int DH_meth_set_flags(DH_METHOD *dhm, int flags); +void *DH_meth_get0_app_data(const DH_METHOD *dhm); +int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data); +int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *)); +int (*DH_meth_get_compute_key(const DH_METHOD *dhm)) + (unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_meth_set_compute_key(DH_METHOD *dhm, + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh)); +int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm)) + (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DH_meth_set_bn_mod_exp(DH_METHOD *dhm, + int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *); +int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *)); +int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *); +int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *)); +int (*DH_meth_get_generate_params(const DH_METHOD *dhm)) + (DH *, int, int, BN_GENCB *); +int DH_meth_set_generate_params(DH_METHOD *dhm, + int (*generate_params) (DH *, int, int, BN_GENCB *)); + + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, \ + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_DH_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_dh_pad(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_PAD, pad, NULL) + +# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)) + +# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(poid)) + +# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)(plen)) + +# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(p)) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) +# define EVP_PKEY_CTRL_DH_NID (EVP_PKEY_ALG_CTRL + 15) +# define EVP_PKEY_CTRL_DH_PAD (EVP_PKEY_ALG_CTRL + 16) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# ifndef OPENSSL_NO_CMS +# define EVP_PKEY_DH_KDF_X9_42 2 +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/dherr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dherr.h new file mode 100644 index 00000000..916b3bed --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dherr.h @@ -0,0 +1,88 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DHERR_H +# define HEADER_DHERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DH + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DH_strings(void); + +/* + * DH function codes. + */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_CHECK_EX 121 +# define DH_F_DH_CHECK_PARAMS_EX 122 +# define DH_F_DH_CHECK_PUB_KEY_EX 123 +# define DH_F_DH_CMS_DECRYPT 114 +# define DH_F_DH_CMS_SET_PEERKEY 115 +# define DH_F_DH_CMS_SET_SHARED_INFO 116 +# define DH_F_DH_METH_DUP 117 +# define DH_F_DH_METH_NEW 118 +# define DH_F_DH_METH_SET1_NAME 119 +# define DH_F_DH_NEW_BY_NID 104 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PKEY_PUBLIC_CHECK 124 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_PKEY_DH_CTRL_STR 120 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_INIT 125 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* + * DH reason codes. + */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_CHECK_INVALID_J_VALUE 115 +# define DH_R_CHECK_INVALID_Q_VALUE 116 +# define DH_R_CHECK_PUBKEY_INVALID 122 +# define DH_R_CHECK_PUBKEY_TOO_LARGE 123 +# define DH_R_CHECK_PUBKEY_TOO_SMALL 124 +# define DH_R_CHECK_P_NOT_PRIME 117 +# define DH_R_CHECK_P_NOT_SAFE_PRIME 118 +# define DH_R_CHECK_Q_NOT_PRIME 119 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PARAMETER_NAME 110 +# define DH_R_INVALID_PARAMETER_NID 114 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KDF_PARAMETER_ERROR 112 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_MISSING_PUBKEY 125 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NOT_SUITABLE_GENERATOR 120 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 +# define DH_R_PEER_KEY_ERROR 111 +# define DH_R_SHARED_INFO_ERROR 113 +# define DH_R_UNABLE_TO_CHECK_GENERATOR 121 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsa.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsa.h new file mode 100644 index 00000000..6d8a18a4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsa.h @@ -0,0 +1,244 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include + +# ifndef OPENSSL_NO_DSA +# ifdef __cplusplus +extern "C" { +# endif +# include +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + +# define DSA_FLAG_CACHE_MONT_P 0x01 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x00 +# endif + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 +# define DSA_FLAG_FIPS_CHECKED 0x0800 + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st DSA_SIG; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); +const DSA_METHOD *DSA_get_method(DSA *d); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); +int DSA_bits(const DSA *d); +int DSA_security_bits(const DSA *d); + /* next 4 return -1 on error */ +DEPRECATEDIN_1_2_0(int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)) +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +#define DSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, l, p, newf, dupf, freef) +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(DSA *DSA_generate_parameters(int bits, + unsigned char *seed, + int seed_len, + int *counter_ret, + unsigned long *h_ret, void + (*callback) (int, int, + void *), + void *cb_arg)) + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# ifndef OPENSSL_NO_STDIO +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 64 +/* + * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only + * have one value here we set the number of checks to 64 which is the 128 bit + * security level that is the highest level and valid for creating a 3072 bit + * DSA key. + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL) +# define EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); +const BIGNUM *DSA_get0_p(const DSA *d); +const BIGNUM *DSA_get0_q(const DSA *d); +const BIGNUM *DSA_get0_g(const DSA *d); +const BIGNUM *DSA_get0_pub_key(const DSA *d); +const BIGNUM *DSA_get0_priv_key(const DSA *d); +void DSA_clear_flags(DSA *d, int flags); +int DSA_test_flags(const DSA *d, int flags); +void DSA_set_flags(DSA *d, int flags); +ENGINE *DSA_get0_engine(DSA *d); + +DSA_METHOD *DSA_meth_new(const char *name, int flags); +void DSA_meth_free(DSA_METHOD *dsam); +DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam); +const char *DSA_meth_get0_name(const DSA_METHOD *dsam); +int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name); +int DSA_meth_get_flags(const DSA_METHOD *dsam); +int DSA_meth_set_flags(DSA_METHOD *dsam, int flags); +void *DSA_meth_get0_app_data(const DSA_METHOD *dsam); +int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data); +DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA *); +int DSA_meth_set_sign(DSA_METHOD *dsam, + DSA_SIG *(*sign) (const unsigned char *, int, DSA *)); +int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam)) + (DSA *, BN_CTX *, BIGNUM **, BIGNUM **); +int DSA_meth_set_sign_setup(DSA_METHOD *dsam, + int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **)); +int (*DSA_meth_get_verify(const DSA_METHOD *dsam)) + (const unsigned char *, int, DSA_SIG *, DSA *); +int DSA_meth_set_verify(DSA_METHOD *dsam, + int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *)); +int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_mod_exp(DSA_METHOD *dsam, + int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *, + BN_MONT_CTX *)); +int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam)) + (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *, BN_MONT_CTX *); +int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam, + int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *, BN_MONT_CTX *)); +int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *); +int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *)); +int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *)); +int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam)) + (DSA *, int, const unsigned char *, int, int *, unsigned long *, + BN_GENCB *); +int DSA_meth_set_paramgen(DSA_METHOD *dsam, + int (*paramgen) (DSA *, int, const unsigned char *, int, int *, + unsigned long *, BN_GENCB *)); +int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *); +int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *)); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsaerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsaerr.h new file mode 100644 index 00000000..495a1ac8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dsaerr.h @@ -0,0 +1,72 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSAERR_H +# define HEADER_DSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_DSA + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_DSA_strings(void); + +/* + * DSA function codes. + */ +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_BUILTIN_PARAMGEN 125 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_METH_DUP 127 +# define DSA_F_DSA_METH_NEW 128 +# define DSA_F_DSA_METH_SET1_NAME 129 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 102 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_CTRL_STR 104 +# define DSA_F_PKEY_DSA_KEYGEN 121 + +/* + * DSA reason codes. + */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MISSING_PRIVATE_KEY 111 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 +# define DSA_R_Q_NOT_PRIME 113 +# define DSA_R_SEED_LEN_SMALL 110 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/dtls1.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dtls1.h new file mode 100644 index 00000000..d55ca9c3 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/dtls1.h @@ -0,0 +1,55 @@ +/* + * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS1_2_VERSION 0xFEFD +# define DTLS_MIN_VERSION DTLS1_VERSION +# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +/* Special value for method supporting multiple versions */ +# define DTLS_ANY_VERSION 0x1FFFF + +/* lengths of messages */ +/* + * Actually the max cookie length in DTLS is 255. But we can't change this now + * due to compatibility concerns. + */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# define DTLS1_AL_HEADER_LENGTH 2 + +/* Timeout multipliers */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/e_os2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/e_os2.h new file mode 100644 index 00000000..97a776cd --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/e_os2.h @@ -0,0 +1,300 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYS_MSDOS) +# undef OPENSSL_SYS_UNIX +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +/* + * UEFI lives here because it might be built with a Microsoft toolchain and + * we need to avoid the false positive match on Windows. + */ +# if defined(OPENSSL_SYS_UEFI) +# undef OPENSSL_SYS_UNIX +# elif defined(OPENSSL_SYS_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN__) || defined(OPENSSL_SYS_CYGWIN) +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYS_WIN32) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN32) +# define OPENSSL_SYS_WIN32 +# endif +# endif +# if defined(_WIN64) || defined(OPENSSL_SYS_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYS_WINNT) +# undef OPENSSL_SYS_UNIX +# endif +# if defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYS_VMS) +# if !defined(OPENSSL_SYS_VMS) +# undef OPENSSL_SYS_UNIX +# endif +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) && !defined(OPENSSL_SYS_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# if defined(_AIX) && !defined(OPENSSL_SYS_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) && !defined(OPENSSL_SYS_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * OPENSSL_EXTERN is normally used to declare a symbol with possible extra + * attributes to handle its presence in a shared library. + * OPENSSL_EXPORT is used to define a symbol with extra possible attributes + * to make it visible in a shared library. + * Care needs to be taken when a header file is used both to declare and + * define symbols. Basically, for any library that exports some global + * variables, the following code must be present in the header file that + * declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT and OPENSSL_EXTERN + * have some generally sensible values. + */ + +# if defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_EXTERN extern __declspec(dllimport) +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_EXTERN extern +# endif + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# ifdef _WIN32 +# ifdef _WIN64 +# define ossl_ssize_t __int64 +# define OSSL_SSIZE_MAX _I64_MAX +# else +# define ossl_ssize_t int +# define OSSL_SSIZE_MAX INT_MAX +# endif +# endif + +# if defined(OPENSSL_SYS_UEFI) && !defined(ossl_ssize_t) +# define ossl_ssize_t INTN +# define OSSL_SSIZE_MAX MAX_INTN +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# if defined(SSIZE_MAX) +# define OSSL_SSIZE_MAX SSIZE_MAX +# elif defined(_POSIX_SSIZE_MAX) +# define OSSL_SSIZE_MAX _POSIX_SSIZE_MAX +# else +# define OSSL_SSIZE_MAX ((ssize_t)(SIZE_MAX>>1)) +# endif +# endif + +# ifdef DEBUG_UNUSED +# define __owur __attribute__((__warn_unused_result__)) +# else +# define __owur +# endif + +/* Standard integer types */ +# if defined(OPENSSL_SYS_UEFI) +typedef INT8 int8_t; +typedef UINT8 uint8_t; +typedef INT16 int16_t; +typedef UINT16 uint16_t; +typedef INT32 int32_t; +typedef UINT32 uint32_t; +typedef INT64 int64_t; +typedef UINT64 uint64_t; +# elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + defined(__osf__) || defined(__sgi) || defined(__hpux) || \ + defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__) +# include +# elif defined(_MSC_VER) && _MSC_VER<=1500 +/* + * minimally required typdefs for systems not supporting inttypes.h or + * stdint.h: currently just older VC++ + */ +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +# else +# include +# endif + +/* ossl_inline: portable inline definition usable in public headers */ +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* just use inline */ +# define ossl_inline inline +# elif defined(__GNUC__) && __GNUC__>=2 +# define ossl_inline __inline__ +# elif defined(_MSC_VER) + /* + * Visual Studio: inline is available in C++ only, however + * __inline is available for C, see + * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + */ +# define ossl_inline __inline +# else +# define ossl_inline +# endif +# else +# define ossl_inline inline +# endif + +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define ossl_noreturn _Noreturn +# elif defined(__GNUC__) && __GNUC__ >= 2 +# define ossl_noreturn __attribute__((noreturn)) +# else +# define ossl_noreturn +# endif + +/* ossl_unused: portable unused attribute for use in public headers */ +# if defined(__GNUC__) +# define ossl_unused __attribute__((unused)) +# else +# define ossl_unused +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ebcdic.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ebcdic.h new file mode 100644 index 00000000..aa012855 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ebcdic.h @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ec.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ec.h new file mode 100644 index 00000000..5af9ebdc --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ec.h @@ -0,0 +1,1479 @@ +/* + * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include + +# ifndef OPENSSL_NO_EC +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_point_st EC_POINT; +typedef struct ecpk_parameters_st ECPKPARAMETERS; +typedef struct ec_parameters_st ECPARAMETERS; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and its order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used montgomery data (possibly NULL). +*/ +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the order of an EC_GROUP + * \param group EC_GROUP object + * \return the group order + */ +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +/** Gets the number of bits of the order of an EC_GROUP + * \param group EC_GROUP object + * \return number of bits of group order. + */ +int EC_GROUP_order_bits(const EC_GROUP *group); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx unused + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Gets the cofactor of an EC_GROUP + * \param group EC_GROUP object + * \return the group cofactor + */ +const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameters of a ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameters of the ec curve defined by y^2 = x^3 + a*x + b (for GFp) + * or y^2 + x*y = x^3 + a*x^2 + b (for GF2m) + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *ctx); + +/** Sets the parameters of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of an ec curve. Synonym for EC_GROUP_set_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx)) + +/** Gets the parameters of an ec curve. Synonym for EC_GROUP_get_curve + * \param group EC_GROUP object + * \param p BIGNUM with the prime number (GFp) or the polynomial + * defining the underlying field (GF2m) + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, + BN_CTX *ctx)) +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if the groups are equal, 1 if not, or -1 on error + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif + +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/** Creates a new EC_GROUP object from an ECPARAMETERS object + * \param params pointer to the ECPARAMETERS object + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params); + +/** Creates an ECPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPARAMETERS object or NULL + * \return pointer to the new ECPARAMETERS object or NULL + * if an error occurred. + */ +ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, + ECPARAMETERS *params); + +/** Creates a new EC_GROUP object from an ECPKPARAMETERS object + * \param params pointer to an existing ECPKPARAMETERS object, or NULL + * \return newly created EC_GROUP object with specified curve, or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params); + +/** Creates an ECPKPARAMETERS object for the given EC_GROUP object. + * \param group pointer to the EC_GROUP object + * \param params pointer to an existing ECPKPARAMETERS object or NULL + * \return pointer to the new ECPKPARAMETERS object or NULL + * if an error occurred. + */ +ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, + ECPKPARAMETERS *params); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r is not zero, + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of an EC_POINT. + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *p, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, + BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_set_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx)) + +/** Gets the affine coordinates of an EC_POINT. A synonym of + * EC_POINT_get_affine_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, + BIGNUM *x, + BIGNUM *y, + BN_CTX *ctx)) + +/** Sets the x9.62 compressed coordinates of a EC_POINT. A synonym of + * EC_POINT_set_compressed_coordinates + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +DEPRECATEDIN_1_2_0(int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, + const BIGNUM *x, + int y_bit, + BN_CTX *ctx)) +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Encodes an EC_POINT object to an allocated octet string + * \param group underlying EC_GROUP object + * \param point EC_POINT object + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if the point is on the curve, 0 if not, or -1 on error + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 if the points are not equal, 0 if they are, or -1 on error + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number further summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +DECLARE_ASN1_ITEM(ECPKPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPKPARAMETERS) +DECLARE_ASN1_ITEM(ECPARAMETERS) +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_EXPLICIT_CURVE 0x000 +# define OPENSSL_EC_NAMED_CURVE 0x001 + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# ifndef OPENSSL_NO_STDIO +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 +# define EC_FLAG_COFACTOR_ECDH 0x1000 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the ENGINE object of a EC_KEY object + * \param eckey EC_KEY object + * \return the ENGINE object (possibly NULL). + */ +ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); + +#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef) +int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg); +void *EC_KEY_get_ex_data(const EC_KEY *key, int idx); + +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Indicates if an EC_KEY can be used for signing. + * \param eckey the EC_KEY object + * \return 1 if can can sign and 0 otherwise. + */ +int EC_KEY_can_sign(const EC_KEY *eckey); + +/** Sets a public key from affine coordinates performing + * necessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/** Encodes an EC_KEY public key to an allocated octet string + * \param key key to encode + * \param form point conversion form + * \param pbuf returns pointer to allocated buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, + unsigned char **pbuf, BN_CTX *ctx); + +/** Decodes a EC_KEY public key from a octet string + * \param key key to decode + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len, + BN_CTX *ctx); + +/** Decodes an EC_KEY private key from an octet string + * \param key key to decode + * \param buf memory buffer with the encoded private key + * \param len length of the encoded key + * \return 1 on success and 0 if an error occurred + */ + +int EC_KEY_oct2priv(EC_KEY *key, const unsigned char *buf, size_t len); + +/** Encodes a EC_KEY private key to an octet string + * \param key key to encode + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ + +size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len); + +/** Encodes an EC_KEY private key to an allocated octet string + * \param eckey key to encode + * \param pbuf returns pointer to allocated buffer + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec parameters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out); + +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# ifndef OPENSSL_NO_STDIO +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +const EC_KEY_METHOD *EC_KEY_OpenSSL(void); +const EC_KEY_METHOD *EC_KEY_get_default_method(void); +void EC_KEY_set_default_method(const EC_KEY_METHOD *meth); +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key); +int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth); +EC_KEY *EC_KEY_new_method(ENGINE *engine); + +/** The old name for ecdh_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + const EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +typedef struct ECDSA_SIG_st ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or a negative value + * on error + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Accessor for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param pr pointer to BIGNUM pointer for r (may be NULL) + * \param ps pointer to BIGNUM pointer for s (may be NULL) + */ +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); + +/** Accessor for r field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_r(const ECDSA_SIG *sig); + +/** Accessor for s field of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + */ +const BIGNUM *ECDSA_SIG_get0_s(const ECDSA_SIG *sig); + +/** Setter for r and s fields of ECDSA_SIG + * \param sig pointer to ECDSA_SIG structure + * \param r pointer to BIGNUM for r (may be NULL) + * \param s pointer to BIGNUM for s (may be NULL) + */ +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optional), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/********************************************************************/ +/* EC_KEY_METHOD constructors, destructors, writers and accessors */ +/********************************************************************/ + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth); +void EC_KEY_METHOD_free(EC_KEY_METHOD *meth); +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth, + int (*keygen)(EC_KEY *key)); + +void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth, + int (*ckey)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth, + int (*verify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (*verify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth, + int (**pinit)(EC_KEY *key), + void (**pfinish)(EC_KEY *key), + int (**pcopy)(EC_KEY *dest, const EC_KEY *src), + int (**pset_group)(EC_KEY *key, + const EC_GROUP *grp), + int (**pset_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (**pset_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth, + int (**pkeygen)(EC_KEY *key)); + +void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth, + int (**pck)(unsigned char **psec, + size_t *pseclen, + const EC_POINT *pub_key, + const EC_KEY *ecdh)); + +void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth, + int (**psign)(int type, const unsigned char *dgst, + int dlen, unsigned char *sig, + unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey), + int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(**psign_sig)(const unsigned char *dgst, + int dgst_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + +void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth, + int (**pverify)(int type, const unsigned + char *dgst, int dgst_len, + const unsigned char *sigbuf, + int sig_len, EC_KEY *eckey), + int (**pverify_sig)(const unsigned char *dgst, + int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \ + (void *)(plen)) + +# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p)) + +# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p)) + +/* SM2 will skip the operation check so no need to pass operation here */ +# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id(ctx, id) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) + +# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) +/* KDF types */ +# define EVP_PKEY_ECDH_KDF_NONE 1 +# define EVP_PKEY_ECDH_KDF_X9_63 2 +/** The old name for EVP_PKEY_ECDH_KDF_X9_63 + * The ECDH KDF specification has been mistakingly attributed to ANSI X9.62, + * it is actually specified in ANSI X9.63. + * This identifier is retained for backwards compatibility + */ +# define EVP_PKEY_ECDH_KDF_X9_62 EVP_PKEY_ECDH_KDF_X9_63 + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdh.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdh.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdh.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdsa.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdsa.h new file mode 100644 index 00000000..681f3d5e --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecdsa.h @@ -0,0 +1,10 @@ +/* + * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecerr.h new file mode 100644 index 00000000..f7b91834 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ecerr.h @@ -0,0 +1,275 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ECERR_H +# define HEADER_ECERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_EC + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EC_strings(void); + +/* + * EC function codes. + */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECDH_CMS_DECRYPT 238 +# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 +# define EC_F_ECDH_COMPUTE_KEY 246 +# define EC_F_ECDH_SIMPLE_COMPUTE_KEY 257 +# define EC_F_ECDSA_DO_SIGN_EX 251 +# define EC_F_ECDSA_DO_VERIFY 252 +# define EC_F_ECDSA_SIGN_EX 254 +# define EC_F_ECDSA_SIGN_SETUP 248 +# define EC_F_ECDSA_SIG_NEW 265 +# define EC_F_ECDSA_VERIFY 253 +# define EC_F_ECD_ITEM_VERIFY 270 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NISTZ256_GET_AFFINE 240 +# define EC_F_ECP_NISTZ256_INV_MOD_ORD 275 +# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +# define EC_F_ECP_NISTZ256_POINTS_MUL 241 +# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +# define EC_F_ECX_KEY_OP 266 +# define EC_F_ECX_PRIV_ENCODE 267 +# define EC_F_ECX_PUB_ENCODE 268 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_FIELD_INV 296 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_LADDER_POST 285 +# define EC_F_EC_GF2M_SIMPLE_LADDER_PRE 288 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINTS_MUL 289 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_INV 297 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES 287 +# define EC_F_EC_GFP_SIMPLE_FIELD_INV 298 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET_CURVE 291 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ECPARAMETERS 261 +# define EC_F_EC_GROUP_GET_ECPKPARAMETERS 262 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS 263 +# define EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS 264 +# define EC_F_EC_GROUP_SET_CURVE 292 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_GROUP_SET_SEED 286 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_NEW_METHOD 245 +# define EC_F_EC_KEY_OCT2PRIV 255 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_PRIV2BUF 279 +# define EC_F_EC_KEY_PRIV2OCT 256 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_KEY_SIMPLE_CHECK_KEY 258 +# define EC_F_EC_KEY_SIMPLE_OCT2PRIV 259 +# define EC_F_EC_KEY_SIMPLE_PRIV2OCT 260 +# define EC_F_EC_PKEY_CHECK 273 +# define EC_F_EC_PKEY_PARAM_CHECK 274 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINTS_MUL 290 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_BN2POINT 280 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES 293 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2BUF 281 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES 294 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES 295 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_SCALAR_MUL_LADDER 284 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_OSSL_ECDH_COMPUTE_KEY 247 +# define EC_F_OSSL_ECDSA_SIGN_SIG 249 +# define EC_F_OSSL_ECDSA_VERIFY_SIG 250 +# define EC_F_PKEY_ECD_CTRL 271 +# define EC_F_PKEY_ECD_DIGESTSIGN 272 +# define EC_F_PKEY_ECD_DIGESTSIGN25519 276 +# define EC_F_PKEY_ECD_DIGESTSIGN448 277 +# define EC_F_PKEY_ECX_DERIVE 269 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_INIT 282 +# define EC_F_PKEY_EC_KDF_DERIVE 283 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 +# define EC_F_VALIDATE_ECX_DERIVE 278 + +/* + * EC reason codes. + */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_BAD_SIGNATURE 156 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_CANNOT_INVERT 165 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 +# define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST 151 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_KEY 116 +# define EC_R_INVALID_OUTPUT_LENGTH 161 +# define EC_R_INVALID_PEER_KEY 133 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KDF_PARAMETER_ERROR 148 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_LADDER_POST_FAILURE 136 +# define EC_R_LADDER_PRE_FAILURE 153 +# define EC_R_LADDER_STEP_FAILURE 162 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NEED_NEW_SETUP_VALUES 157 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_NO_PRIVATE_VALUE 154 +# define EC_R_OPERATION_NOT_SUPPORTED 152 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PEER_KEY_ERROR 149 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_ARITHMETIC_FAILURE 155 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_COORDINATES_BLIND_FAILURE 163 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_RANDOM_NUMBER_GENERATION_FAILED 158 +# define EC_R_SHARED_INFO_ERROR 150 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_COFACTOR 164 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/engine.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/engine.h new file mode 100644 index 00000000..0780f0fb --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/engine.h @@ -0,0 +1,751 @@ +/* + * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include + +# ifndef OPENSSL_NO_ENGINE +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# include +# include +# include +# include +# include +# endif +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +# define ENGINE_METHOD_EC (unsigned int)0x0800 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ENGINE_load_openssl() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_OPENSSL, NULL) +# define ENGINE_load_dynamic() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_DYNAMIC, NULL) +# ifndef OPENSSL_NO_STATIC_ENGINE +# define ENGINE_load_padlock() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_PADLOCK, NULL) +# define ENGINE_load_capi() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CAPI, NULL) +# define ENGINE_load_afalg() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_AFALG, NULL) +# endif +# define ENGINE_load_cryptodev() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL) +# define ENGINE_load_rdrand() \ + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL) +#endif +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_EC(ENGINE *e); +void ENGINE_unregister_EC(ENGINE *e); +void ENGINE_register_all_EC(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parameterised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +#define ENGINE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, l, p, newf, dupf, freef) +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* + * This function previously cleaned up anything that needs it. Auto-deinit will + * now take care of it so it is no longer required to call this function. + */ +# define ENGINE_cleanup() while(0) continue +#endif + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_EC(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_EC(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00030000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00030000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_fn) (size_t, const char *, int); +typedef void *(*dyn_MEM_realloc_fn) (void *, size_t, const char *, int); +typedef void (*dyn_MEM_free_fn) (void *, const char *, int); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_fn malloc_fn; + dyn_MEM_realloc_fn realloc_fn; + dyn_MEM_free_fn free_fn; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependent code) can simplify a bit?? + */ +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + dynamic_MEM_fns mem_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if (v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if (ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \ + fns->mem_fns.realloc_fn, \ + fns->mem_fns.free_fn); \ + skip_cbs: \ + if (!fn(e, id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) +DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void)) +# endif + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/engineerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/engineerr.h new file mode 100644 index 00000000..05e84bd2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/engineerr.h @@ -0,0 +1,111 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENGINEERR_H +# define HEADER_ENGINEERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_ENGINE + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_ENGINE_strings(void); + +/* + * ENGINE function codes. + */ +# define ENGINE_F_DIGEST_UPDATE 198 +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_FIRST 195 +# define ENGINE_F_ENGINE_GET_LAST 196 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR 197 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CLEANUP_ITEM 199 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_OSSL_HMAC_INIT 200 + +/* + * ENGINE reason codes. + */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/err.h new file mode 100644 index 00000000..b49f8812 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/err.h @@ -0,0 +1,274 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# include +# endif + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 +# define ERR_FLAG_CLEAR 0x02 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_OSSL_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +/* # define ERR_LIB_JPAKE 49 */ +# define ERR_LIB_CT 50 +# define ERR_LIB_ASYNC 51 +# define ERR_LIB_KDF 52 +# define ERR_LIB_SM2 53 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,(f),(r),OPENSSL_FILE,OPENSSL_LINE) + +# define ERR_PACK(l,f,r) ( \ + (((unsigned int)(l) & 0x0FF) << 24L) | \ + (((unsigned int)(f) & 0xFFF) << 12L) | \ + (((unsigned int)(r) & 0xFFF) ) ) +# define ERR_GET_LIB(l) (int)(((l) >> 24L) & 0x0FFL) +# define ERR_GET_FUNC(l) (int)(((l) >> 12L) & 0xFFFL) +# define ERR_GET_REASON(l) (int)( (l) & 0xFFFL) +# define ERR_FATAL_ERROR(l) (int)( (l) & ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 +# define SYS_F_GETADDRINFO 12 +# define SYS_F_GETNAMEINFO 13 +# define SYS_F_SETSOCKOPT 14 +# define SYS_F_GETSOCKOPT 15 +# define SYS_F_GETSOCKNAME 16 +# define SYS_F_GETHOSTBYNAME 17 +# define SYS_F_FFLUSH 18 +# define SYS_F_OPEN 19 +# define SYS_F_CLOSE 20 +# define SYS_F_IOCTL 21 +# define SYS_F_STAT 22 +# define SYS_F_FCNTL 23 +# define SYS_F_FSTAT 24 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_OSSL_STORE_LIB ERR_LIB_OSSL_STORE/* 44 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) +# define ERR_R_INIT_FAIL (6|ERR_R_FATAL) +# define ERR_R_PASSED_INVALID_ARGUMENT (7) +# define ERR_R_OPERATION_FAIL (8|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +DEFINE_LHASH_OF(ERR_STRING_DATA); + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +void ERR_print_errors_fp(FILE *fp); +# endif +void ERR_print_errors(BIO *bp); +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +int ERR_load_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_strings_const(const ERR_STRING_DATA *str); +int ERR_unload_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_ERR_strings(void); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define ERR_load_crypto_strings() \ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# define ERR_free_strings() while(0) continue +#endif + +DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *)) +DEPRECATEDIN_1_0_0(void ERR_remove_state(unsigned long pid)) +ERR_STATE *ERR_get_state(void); + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); +int ERR_clear_last_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/evp.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/evp.h new file mode 100644 index 00000000..a411f3f2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/evp.h @@ -0,0 +1,1666 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# include +# include +# include +# include +# include + +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_RSA_PSS NID_rsassaPss +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_DHX NID_dhpublicnumber +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_SM2 NID_sm2 +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac +# define EVP_PKEY_SCRYPT NID_id_scrypt +# define EVP_PKEY_TLS1_PRF NID_tls1_prf +# define EVP_PKEY_HKDF NID_hkdf +# define EVP_PKEY_POLY1305 NID_poly1305 +# define EVP_PKEY_SIPHASH NID_siphash +# define EVP_PKEY_X25519 NID_X25519 +# define EVP_PKEY_ED25519 NID_ED25519 +# define EVP_PKEY_X448 NID_X448 +# define EVP_PKEY_ED448 NID_ED448 + +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type); +EVP_MD *EVP_MD_meth_dup(const EVP_MD *md); +void EVP_MD_meth_free(EVP_MD *md); + +int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize); +int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize); +int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize); +int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags); +int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx, + const void *data, + size_t count)); +int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx, + unsigned char *md)); +int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to, + const EVP_MD_CTX *from)); +int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx)); +int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2)); + +int EVP_MD_meth_get_input_blocksize(const EVP_MD *md); +int EVP_MD_meth_get_result_size(const EVP_MD *md); +int EVP_MD_meth_get_app_datasize(const EVP_MD *md); +unsigned long EVP_MD_meth_get_flags(const EVP_MD *md); +int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx, + const void *data, + size_t count); +int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx, + unsigned char *md); +int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to, + const EVP_MD_CTX *from); +int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx); +int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, + int p1, void *p2); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* digest is extensible-output function, XOF */ +# define EVP_MD_FLAG_XOF 0x0002 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 +# define EVP_MD_CTRL_XOF_LEN 0x3 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# endif /* !EVP_MD */ + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_reset */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ +/* + * Some functions such as EVP_DigestSign only finalise copies of internal + * contexts so additional data can be included after the finalisation call. + * This is inefficient if this functionality is not required: it is disabled + * if the following flag is set. + */ +# define EVP_MD_CTX_FLAG_FINALISE 0x0200 +/* NOTE: 0x0400 is reserved for internal usage */ + +EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); +EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); +void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); + +int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); +int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); +int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); +int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc)); +int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher) (EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl)); +int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup) (EVP_CIPHER_CTX *)); +int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); +int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl) (EVP_CIPHER_CTX *, int type, + int arg, void *ptr)); + +int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc); +int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl); +int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); +int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); +int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + int type, int arg, + void *ptr); + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_WRAP_MODE 0x10002 +# define EVP_CIPH_OCB_MODE 0x10003 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Don't use standard iv length function */ +# define EVP_CIPH_CUSTOM_IV_LENGTH 0x800 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 +/* Cipher can handle pipeline operations */ +# define EVP_CIPH_FLAG_PIPELINE 0X800000 + +/* + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. + */ + +# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_AEAD_SET_IVLEN 0x9 +# define EVP_CTRL_AEAD_GET_TAG 0x10 +# define EVP_CTRL_AEAD_SET_TAG 0x11 +# define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +# define EVP_CTRL_CCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 +# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a +# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b +# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c + +# define EVP_CTRL_SSL3_MASTER_SECRET 0x1d + +/* EVP_CTRL_SET_SBOX takes the char * specifying S-boxes */ +# define EVP_CTRL_SET_SBOX 0x1e +/* + * EVP_CTRL_SBOX_USED takes a 'size_t' and 'char *', pointing at a + * pre-allocated buffer with specified size + */ +# define EVP_CTRL_SBOX_USED 0x1f +/* EVP_CTRL_KEY_MESH takes 'size_t' number of bytes to mesh the key after, + * 0 switches meshing off + */ +# define EVP_CTRL_KEY_MESH 0x20 +/* EVP_CTRL_BLOCK_PADDING_MODE takes the padding mode */ +# define EVP_CTRL_BLOCK_PADDING_MODE 0x21 + +/* Set the output buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS 0x22 +/* Set the input buffers to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_BUFS 0x23 +/* Set the input buffer lengths to use for a pipelined operation */ +# define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 + +# define EVP_CTRL_GET_IVLEN 0x25 + +/* Padding modes */ +#define EVP_PADDING_PKCS7 1 +#define EVP_PADDING_ISO7816_4 2 +#define EVP_PADDING_ANSI923 3 +#define EVP_PADDING_ISO10126 4 +#define EVP_PADDING_ZERO 5 + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +typedef struct { + unsigned char *out; + const unsigned char *inp; + size_t len; + unsigned int interleave; +} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +/* CCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_CCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 +/* Total length of CCM IV length for TLS */ +# define EVP_CCM_TLS_IV_LEN 12 +/* Length of tag for TLS */ +# define EVP_CCM_TLS_TAG_LEN 16 +/* Length of CCM8 tag for TLS */ +# define EVP_CCM8_TLS_TAG_LEN 8 + +/* Length of tag for TLS */ +# define EVP_CHACHAPOLY_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif +# ifndef OPENSSL_NO_SIPHASH +# define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),EVP_PKEY_SIPHASH,\ + (char *)(shkey)) +# endif + +# ifndef OPENSSL_NO_POLY1305 +# define EVP_PKEY_assign_POLY1305(pkey,polykey) EVP_PKEY_assign((pkey),EVP_PKEY_POLY1305,\ + (char *)(polykey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx, + const void *data, size_t count); +void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx, + int (*update) (EVP_MD_CTX *ctx, + const void *data, size_t count)); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) +EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx); +void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); +void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx); + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); +const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); +unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx); +void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_flags(c) EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(c)) +# endif +# define EVP_CIPHER_CTX_mode(c) EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(c)) + +# define EVP_ENCODE_LENGTH(l) ((((l)+2)/3*4)+((l)/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) (((l)+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)(md)) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)(mdp)) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0, \ + (char *)(mdcp)) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0, \ + (char *)(c_pp)) + +/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, + const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +EVP_MD_CTX *EVP_MD_CTX_new(void); +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +# define EVP_MD_CTX_create() EVP_MD_CTX_new() +# define EVP_MD_CTX_init(ctx) EVP_MD_CTX_reset((ctx)) +# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx)) +__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +__owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); +__owur int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, + size_t cnt); +__owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, + const EVP_MD *type, ENGINE *impl); + +__owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +__owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +__owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, + unsigned int *s); +__owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, + size_t len); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +__owur int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, + const unsigned char *data, int datal, int count, + unsigned char *key, unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); +/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl); + +__owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv); +/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, + const unsigned char *iv, int enc); +__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); +__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, + int *outl); + +__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +__owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, + size_t tbslen); + +__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +__owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, + size_t siglen, const unsigned char *tbs, + size_t tbslen); + +/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen); + +__owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); +__owur int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen); + +# ifndef OPENSSL_NO_RSA +__owur int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, + const unsigned char *iv, EVP_PKEY *priv); +__owur int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +__owur int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +__owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +# endif + +EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void); +void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx); +int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx); +int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx); +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define EVP_CIPHER_CTX_init(c) EVP_CIPHER_CTX_reset(c) +# define EVP_CIPHER_CTX_cleanup(c) EVP_CIPHER_CTX_reset(c) +# endif +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +const BIO_METHOD *BIO_f_md(void); +const BIO_METHOD *BIO_f_base64(void); +const BIO_METHOD *BIO_f_cipher(void); +const BIO_METHOD *BIO_f_reliable(void); +__owur int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +const EVP_MD *EVP_md5_sha1(void); +# endif +# ifndef OPENSSL_NO_BLAKE2 +const EVP_MD *EVP_blake2b512(void); +const EVP_MD *EVP_blake2s256(void); +# endif +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +const EVP_MD *EVP_sha512_224(void); +const EVP_MD *EVP_sha512_256(void); +const EVP_MD *EVP_sha3_224(void); +const EVP_MD *EVP_sha3_256(void); +const EVP_MD *EVP_sha3_384(void); +const EVP_MD *EVP_sha3_512(void); +const EVP_MD *EVP_shake128(void); +const EVP_MD *EVP_shake256(void); +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RMD160 +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +# ifndef OPENSSL_NO_SM3 +const EVP_MD *EVP_sm3(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +const EVP_CIPHER *EVP_des_ede3_wrap(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_128_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_128_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_192_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_192_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +const EVP_CIPHER *EVP_aes_256_wrap_pad(void); +# ifndef OPENSSL_NO_OCB +const EVP_CIPHER *EVP_aes_256_ocb(void); +# endif +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); +# ifndef OPENSSL_NO_ARIA +const EVP_CIPHER *EVP_aria_128_ecb(void); +const EVP_CIPHER *EVP_aria_128_cbc(void); +const EVP_CIPHER *EVP_aria_128_cfb1(void); +const EVP_CIPHER *EVP_aria_128_cfb8(void); +const EVP_CIPHER *EVP_aria_128_cfb128(void); +# define EVP_aria_128_cfb EVP_aria_128_cfb128 +const EVP_CIPHER *EVP_aria_128_ctr(void); +const EVP_CIPHER *EVP_aria_128_ofb(void); +const EVP_CIPHER *EVP_aria_128_gcm(void); +const EVP_CIPHER *EVP_aria_128_ccm(void); +const EVP_CIPHER *EVP_aria_192_ecb(void); +const EVP_CIPHER *EVP_aria_192_cbc(void); +const EVP_CIPHER *EVP_aria_192_cfb1(void); +const EVP_CIPHER *EVP_aria_192_cfb8(void); +const EVP_CIPHER *EVP_aria_192_cfb128(void); +# define EVP_aria_192_cfb EVP_aria_192_cfb128 +const EVP_CIPHER *EVP_aria_192_ctr(void); +const EVP_CIPHER *EVP_aria_192_ofb(void); +const EVP_CIPHER *EVP_aria_192_gcm(void); +const EVP_CIPHER *EVP_aria_192_ccm(void); +const EVP_CIPHER *EVP_aria_256_ecb(void); +const EVP_CIPHER *EVP_aria_256_cbc(void); +const EVP_CIPHER *EVP_aria_256_cfb1(void); +const EVP_CIPHER *EVP_aria_256_cfb8(void); +const EVP_CIPHER *EVP_aria_256_cfb128(void); +# define EVP_aria_256_cfb EVP_aria_256_cfb128 +const EVP_CIPHER *EVP_aria_256_ctr(void); +const EVP_CIPHER *EVP_aria_256_ofb(void); +const EVP_CIPHER *EVP_aria_256_gcm(void); +const EVP_CIPHER *EVP_aria_256_ccm(void); +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_128_ctr(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ctr(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ctr(void); +# endif +# ifndef OPENSSL_NO_CHACHA +const EVP_CIPHER *EVP_chacha20(void); +# ifndef OPENSSL_NO_POLY1305 +const EVP_CIPHER *EVP_chacha20_poly1305(void); +# endif +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +# ifndef OPENSSL_NO_SM4 +const EVP_CIPHER *EVP_sm4_ecb(void); +const EVP_CIPHER *EVP_sm4_cbc(void); +const EVP_CIPHER *EVP_sm4_cfb128(void); +# define EVP_sm4_cfb EVP_sm4_cfb128 +const EVP_CIPHER *EVP_sm4_ofb(void); +const EVP_CIPHER *EVP_sm4_ctr(void); +# endif + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OPENSSL_add_all_algorithms_conf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS \ + | OPENSSL_INIT_LOAD_CONFIG, NULL) +# define OPENSSL_add_all_algorithms_noconf() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() OPENSSL_add_all_algorithms_noconf() +# endif + +# define OpenSSL_add_all_ciphers() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL) +# define OpenSSL_add_all_digests() \ + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) + +# define EVP_cleanup() while(0) continue +# endif + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(const EVP_PKEY *pkey); +int EVP_PKEY_security_bits(const EVP_PKEY *pkey); +int EVP_PKEY_size(const EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); +# ifndef OPENSSL_NO_ENGINE +int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e); +ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); +# endif +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(const EVP_PKEY *pkey); +const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len); +# ifndef OPENSSL_NO_POLY1305 +const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len); +# endif +# ifndef OPENSSL_NO_SIPHASH +const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len); +# endif + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +int EVP_PKEY_up_ref(EVP_PKEY *pkey); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const unsigned char *pt, size_t ptlen); +size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_SCRYPT +int EVP_PBE_scrypt(const char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, + unsigned char *key, size_t keylen); + +int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de); +#endif + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 +/* Is a PKCS#5 v2.0 KDF */ +# define EVP_PBE_TYPE_KDF 0x2 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); +int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 +# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + const PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)); + +void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth, + int (*siginf_set) (X509_SIG_INFO *siginf, + const X509_ALGOR *alg, + const ASN1_STRING *sig)); + +void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_pub_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_param_check) (const EVP_PKEY *pk)); + +void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_priv_key) (EVP_PKEY *pk, + const unsigned char + *priv, + size_t len)); +void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*set_pub_key) (EVP_PKEY *pk, + const unsigned char *pub, + size_t len)); +void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_priv_key) (const EVP_PKEY *pk, + unsigned char *priv, + size_t *len)); +void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth, + int (*get_pub_key) (const EVP_PKEY *pk, + unsigned char *pub, + size_t *len)); + +void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_security_bits) (const EVP_PKEY + *pk)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key)) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_CTRL_GET_MD 13 + +# define EVP_PKEY_CTRL_SET_DIGEST_SIZE 14 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth); +size_t EVP_PKEY_meth_get_count(void); +const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); +int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, uint64_t value); + +int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str); +int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex); + +int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, + const unsigned char *priv, + size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, + const unsigned char *pub, + size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len); + +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx); +int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth, + int (*digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth, + int (*digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth, + int (*digest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth, + int (**digestsign) (EVP_MD_CTX *ctx, + unsigned char *sig, + size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth, + int (**digestverify) (EVP_MD_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth, + int (**pdigest_custom) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx)); +void EVP_add_alg_module(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/evperr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/evperr.h new file mode 100644 index 00000000..d2b26ea5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/evperr.h @@ -0,0 +1,205 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_EVPERR_H +# define HEADER_EVPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_EVP_strings(void); + +/* + * EVP function codes. + */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_INIT_KEY 207 +# define EVP_F_AES_GCM_CTRL 196 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_OCB_CIPHER 169 +# define EVP_F_AES_T4_INIT_KEY 178 +# define EVP_F_AES_T4_XTS_INIT_KEY 208 +# define EVP_F_AES_WRAP_CIPHER 170 +# define EVP_F_AES_XTS_INIT_KEY 209 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_ARIA_CCM_INIT_KEY 175 +# define EVP_F_ARIA_GCM_CTRL 197 +# define EVP_F_ARIA_GCM_INIT_KEY 176 +# define EVP_F_ARIA_INIT_KEY 185 +# define EVP_F_B64_NEW 198 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CHACHA20_POLY1305_CTRL 182 +# define EVP_F_CMLL_T4_INIT_KEY 179 +# define EVP_F_DES_EDE3_WRAP_CIPHER 171 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_ENC_NEW 199 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_ASN1_TO_PARAM 204 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_CIPHER_PARAM_TO_ASN1 205 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DECRYPTUPDATE 166 +# define EVP_F_EVP_DIGESTFINALXOF 174 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_ENCRYPTUPDATE 167 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PBE_SCRYPT 181 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKEY2PKCS8 113 +# define EVP_F_EVP_PKEY_ASN1_ADD0 188 +# define EVP_F_EVP_PKEY_CHECK 186 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_CTX_MD 168 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET0_DH 119 +# define EVP_F_EVP_PKEY_GET0_DSA 120 +# define EVP_F_EVP_PKEY_GET0_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET0_HMAC 183 +# define EVP_F_EVP_PKEY_GET0_POLY1305 184 +# define EVP_F_EVP_PKEY_GET0_RSA 121 +# define EVP_F_EVP_PKEY_GET0_SIPHASH 172 +# define EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY 202 +# define EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY 203 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_METH_ADD0 194 +# define EVP_F_EVP_PKEY_METH_NEW 195 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_NEW_CMAC_KEY 193 +# define EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY 191 +# define EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY 192 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_PARAM_CHECK 189 +# define EVP_F_EVP_PKEY_PUBLIC_CHECK 190 +# define EVP_F_EVP_PKEY_SET1_ENGINE 187 +# define EVP_F_EVP_PKEY_SET_ALIAS_TYPE 206 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_OK_NEW 200 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN 180 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 +# define EVP_F_R_32_12_16_INIT_KEY 242 +# define EVP_F_S390X_AES_GCM_CTRL 201 +# define EVP_F_UPDATE 173 + +/* + * EVP reason codes. + */ +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ARIA_KEY_SETUP_FAILED 176 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 195 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_COPY_ERROR 173 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EXPECTING_AN_HMAC_KEY 174 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_EXPECTING_A_POLY1305_KEY 164 +# define EVP_R_EXPECTING_A_SIPHASH_KEY 175 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_GET_RAW_KEY_FAILED 182 +# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_IV_LENGTH 194 +# define EVP_R_INVALID_KEY 163 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_KEY_SETUP_FAILED 180 +# define EVP_R_MEMORY_LIMIT_EXCEEDED 172 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NOT_XOF_OR_INVALID_LENGTH 178 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_ONLY_ONESHOT_SUPPORTED 177 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PARTIALLY_OVERLAPPING 162 +# define EVP_R_PBKDF2_ERROR 181 +# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_XTS_DUPLICATED_KEYS 183 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/hmac.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/hmac.h new file mode 100644 index 00000000..458efc1d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/hmac.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include + +# include + +# if OPENSSL_API_COMPAT < 0x10200000L +# define HMAC_MAX_MD_CBLOCK 128 /* Deprecated */ +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +size_t HMAC_size(const HMAC_CTX *e); +HMAC_CTX *HMAC_CTX_new(void); +int HMAC_CTX_reset(HMAC_CTX *ctx); +void HMAC_CTX_free(HMAC_CTX *ctx); + +DEPRECATEDIN_1_1_0(__owur int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md)) + +/*__owur*/ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +/*__owur*/ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, + size_t len); +/*__owur*/ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, + unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +__owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); +const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/idea.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/idea.h new file mode 100644 index 00000000..4334f3ea --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/idea.h @@ -0,0 +1,64 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include + +# ifndef OPENSSL_NO_IDEA +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int IDEA_INT; + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *IDEA_options(void); +void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void IDEA_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define idea_options IDEA_options +# define idea_ecb_encrypt IDEA_ecb_encrypt +# define idea_set_encrypt_key IDEA_set_encrypt_key +# define idea_set_decrypt_key IDEA_set_decrypt_key +# define idea_cbc_encrypt IDEA_cbc_encrypt +# define idea_cfb64_encrypt IDEA_cfb64_encrypt +# define idea_ofb64_encrypt IDEA_ofb64_encrypt +# define idea_encrypt IDEA_encrypt +# endif + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdf.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdf.h new file mode 100644 index 00000000..5abd4c37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdf.h @@ -0,0 +1,97 @@ +/* + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDF_H +# define HEADER_KDF_H + +# include +#ifdef __cplusplus +extern "C" { +#endif + +# define EVP_PKEY_CTRL_TLS_MD (EVP_PKEY_ALG_CTRL) +# define EVP_PKEY_CTRL_TLS_SECRET (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_TLS_SEED (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_HKDF_SALT (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_HKDF_INFO (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_PASS (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_SCRYPT_SALT (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_SCRYPT_N (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_SCRYPT_R (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_SCRYPT_P (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES (EVP_PKEY_ALG_CTRL + 13) + +# define EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 0 +# define EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 1 +# define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 2 + +# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)(sec)) + +# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)(seed)) + +# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) + +# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) + +# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL) + +# define EVP_PKEY_CTX_set1_pbe_pass(pctx, pass, passlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_PASS, passlen, (void *)(pass)) + +# define EVP_PKEY_CTX_set1_scrypt_salt(pctx, salt, saltlen) \ + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_SALT, saltlen, (void *)(salt)) + +# define EVP_PKEY_CTX_set_scrypt_N(pctx, n) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_N, n) + +# define EVP_PKEY_CTX_set_scrypt_r(pctx, r) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_R, r) + +# define EVP_PKEY_CTX_set_scrypt_p(pctx, p) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_P, p) + +# define EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, maxmem_bytes) \ + EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdferr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdferr.h new file mode 100644 index 00000000..3f51bd02 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/kdferr.h @@ -0,0 +1,55 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_KDFERR_H +# define HEADER_KDFERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_KDF_strings(void); + +/* + * KDF function codes. + */ +# define KDF_F_PKEY_HKDF_CTRL_STR 103 +# define KDF_F_PKEY_HKDF_DERIVE 102 +# define KDF_F_PKEY_HKDF_INIT 108 +# define KDF_F_PKEY_SCRYPT_CTRL_STR 104 +# define KDF_F_PKEY_SCRYPT_CTRL_UINT64 105 +# define KDF_F_PKEY_SCRYPT_DERIVE 109 +# define KDF_F_PKEY_SCRYPT_INIT 106 +# define KDF_F_PKEY_SCRYPT_SET_MEMBUF 107 +# define KDF_F_PKEY_TLS1_PRF_CTRL_STR 100 +# define KDF_F_PKEY_TLS1_PRF_DERIVE 101 +# define KDF_F_PKEY_TLS1_PRF_INIT 110 +# define KDF_F_TLS1_PRF_ALG 111 + +/* + * KDF reason codes. + */ +# define KDF_R_INVALID_DIGEST 100 +# define KDF_R_MISSING_ITERATION_COUNT 109 +# define KDF_R_MISSING_KEY 104 +# define KDF_R_MISSING_MESSAGE_DIGEST 105 +# define KDF_R_MISSING_PARAMETER 101 +# define KDF_R_MISSING_PASS 110 +# define KDF_R_MISSING_SALT 111 +# define KDF_R_MISSING_SECRET 107 +# define KDF_R_MISSING_SEED 106 +# define KDF_R_UNKNOWN_PARAMETER_TYPE 103 +# define KDF_R_VALUE_ERROR 108 +# define KDF_R_VALUE_MISSING 102 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/lhash.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/lhash.h new file mode 100644 index 00000000..2e42d727 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/lhash.h @@ -0,0 +1,241 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st OPENSSL_LH_NODE; +typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); +typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); +typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); +typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); +typedef struct lhash_st OPENSSL_LHASH; + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + + +# define LH_LOAD_MULT 256 + +int OPENSSL_LH_error(OPENSSL_LHASH *lh); +OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); +void OPENSSL_LH_free(OPENSSL_LHASH *lh); +void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); +void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); +void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); +void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); +void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); +unsigned long OPENSSL_LH_strhash(const char *c); +unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); +unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); +void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); + +# ifndef OPENSSL_NO_STDIO +void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); +void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); +# endif +void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); +void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _LHASH OPENSSL_LHASH +# define LHASH_NODE OPENSSL_LH_NODE +# define lh_error OPENSSL_LH_error +# define lh_new OPENSSL_LH_new +# define lh_free OPENSSL_LH_free +# define lh_insert OPENSSL_LH_insert +# define lh_delete OPENSSL_LH_delete +# define lh_retrieve OPENSSL_LH_retrieve +# define lh_doall OPENSSL_LH_doall +# define lh_doall_arg OPENSSL_LH_doall_arg +# define lh_strhash OPENSSL_LH_strhash +# define lh_num_items OPENSSL_LH_num_items +# ifndef OPENSSL_NO_STDIO +# define lh_stats OPENSSL_LH_stats +# define lh_node_stats OPENSSL_LH_node_stats +# define lh_node_usage_stats OPENSSL_LH_node_usage_stats +# endif +# define lh_stats_bio OPENSSL_LH_stats_bio +# define lh_node_stats_bio OPENSSL_LH_node_stats_bio +# define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DEFINE_LHASH_OF(type) \ + LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ + static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ + int (*cfn)(const type *, const type *)) \ + { \ + return (LHASH_OF(type) *) \ + OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ + } \ + static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ + { \ + OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ + { \ + return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ + { \ + return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ + } \ + static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ + { \ + OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ + } \ + static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ + { \ + return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ + } \ + static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ + { \ + OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ + } \ + static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ + void (*doall)(type *)) \ + { \ + OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ + } \ + LHASH_OF(type) + +#define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ + int_implement_lhash_doall(type, argtype, const type) + +#define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ + int_implement_lhash_doall(type, argtype, type) + +#define int_implement_lhash_doall(type, argtype, cbargtype) \ + static ossl_unused ossl_inline void \ + lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ + void (*fn)(cbargtype *, argtype *), \ + argtype *arg) \ + { \ + OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ + } \ + LHASH_OF(type) + +DEFINE_LHASH_OF(OPENSSL_STRING); +# ifdef _MSC_VER +/* + * push and pop this warning: + * warning C4090: 'function': different 'const' qualifiers + */ +# pragma warning (push) +# pragma warning (disable: 4090) +# endif + +DEFINE_LHASH_OF(OPENSSL_CSTRING); + +# ifdef _MSC_VER +# pragma warning (pop) +# endif + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_LH_new +# pragma weak OPENSSL_LH_free +# pragma weak OPENSSL_LH_insert +# pragma weak OPENSSL_LH_delete +# pragma weak OPENSSL_LH_retrieve +# pragma weak OPENSSL_LH_error +# pragma weak OPENSSL_LH_num_items +# pragma weak OPENSSL_LH_node_stats_bio +# pragma weak OPENSSL_LH_node_usage_stats_bio +# pragma weak OPENSSL_LH_stats_bio +# pragma weak OPENSSL_LH_get_down_load +# pragma weak OPENSSL_LH_set_down_load +# pragma weak OPENSSL_LH_doall +# pragma weak OPENSSL_LH_doall_arg +# endif /* __SUNPRO_C */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/md2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md2.h new file mode 100644 index 00000000..7faf8e3d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md2.h @@ -0,0 +1,44 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD2_H +# define HEADER_MD2_H + +# include + +# ifndef OPENSSL_NO_MD2 +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned char MD2_INT; + +# define MD2_DIGEST_LENGTH 16 +# define MD2_BLOCK 16 + +typedef struct MD2state_st { + unsigned int num; + unsigned char data[MD2_BLOCK]; + MD2_INT cksm[MD2_BLOCK]; + MD2_INT state[MD2_BLOCK]; +} MD2_CTX; + +const char *MD2_options(void); +int MD2_Init(MD2_CTX *c); +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); +int MD2_Final(unsigned char *md, MD2_CTX *c); +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/md4.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md4.h new file mode 100644 index 00000000..940e29db --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md4.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include + +# ifndef OPENSSL_NO_MD4 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD4_LONG unsigned int + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/md5.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md5.h new file mode 100644 index 00000000..2deb7721 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/md5.h @@ -0,0 +1,50 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include + +# ifndef OPENSSL_NO_MD5 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define MD5_LONG unsigned int + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/mdc2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/mdc2.h new file mode 100644 index 00000000..aabd2bfa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/mdc2.h @@ -0,0 +1,42 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include + +#ifndef OPENSSL_NO_MDC2 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/modes.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/modes.h new file mode 100644 index 00000000..d544f98d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/modes.h @@ -0,0 +1,208 @@ +/* + * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_MODES_H +# define HEADER_MODES_H + +# include + +# ifdef __cplusplus +extern "C" { +# endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); +size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); +size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, + unsigned char *out, const unsigned char *in, + size_t inlen, block128_f block); + +# ifndef OPENSSL_NO_OCB +typedef struct ocb128_context OCB128_CONTEXT; + +typedef void (*ocb128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + size_t start_block_num, + unsigned char offset_i[16], + const unsigned char L_[][16], + unsigned char checksum[16]); + +OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, + block128_f encrypt, block128_f decrypt, + ocb128_f stream); +int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, + void *keyenc, void *keydec); +int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv, + size_t len, size_t taglen); +int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, const unsigned char *in, + unsigned char *out, size_t len); +int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx); +# endif /* OPENSSL_NO_OCB */ + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/obj_mac.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/obj_mac.h new file mode 100644 index 00000000..483fc050 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/obj_mac.h @@ -0,0 +1,5198 @@ +/* + * WARNING: do not edit! + * Generated by crypto/objects/objects.pl + * + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_x509ExtAdmission "x509ExtAdmission" +#define LN_x509ExtAdmission "Professional Information or basis for Admission" +#define NID_x509ExtAdmission 1093 +#define OBJ_x509ExtAdmission OBJ_identified_organization,36L,8L,3L,3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_ieee "ieee" +#define NID_ieee 1170 +#define OBJ_ieee OBJ_identified_organization,111L + +#define SN_ieee_siswg "ieee-siswg" +#define LN_ieee_siswg "IEEE Security in Storage Working Group" +#define NID_ieee_siswg 1171 +#define OBJ_ieee_siswg OBJ_ieee,2L,1619L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_ISO_CN "ISO-CN" +#define LN_ISO_CN "ISO CN Member Body" +#define NID_ISO_CN 1140 +#define OBJ_ISO_CN OBJ_member_body,156L + +#define SN_oscca "oscca" +#define NID_oscca 1141 +#define OBJ_oscca OBJ_ISO_CN,10197L + +#define SN_sm_scheme "sm-scheme" +#define NID_sm_scheme 1142 +#define OBJ_sm_scheme OBJ_oscca,1L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_sha512_224WithRSAEncryption "RSA-SHA512/224" +#define LN_sha512_224WithRSAEncryption "sha512-224WithRSAEncryption" +#define NID_sha512_224WithRSAEncryption 1145 +#define OBJ_sha512_224WithRSAEncryption OBJ_pkcs1,15L + +#define SN_sha512_256WithRSAEncryption "RSA-SHA512/256" +#define LN_sha512_256WithRSAEncryption "sha512-256WithRSAEncryption" +#define NID_sha512_256WithRSAEncryption 1146 +#define OBJ_sha512_256WithRSAEncryption OBJ_pkcs1,16L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_smime_ct_contentCollection "id-smime-ct-contentCollection" +#define NID_id_smime_ct_contentCollection 1058 +#define OBJ_id_smime_ct_contentCollection OBJ_id_smime_ct,19L + +#define SN_id_smime_ct_authEnvelopedData "id-smime-ct-authEnvelopedData" +#define NID_id_smime_ct_authEnvelopedData 1059 +#define OBJ_id_smime_ct_authEnvelopedData OBJ_id_smime_ct,23L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_ct_xml "id-ct-xml" +#define NID_id_ct_xml 1060 +#define OBJ_id_ct_xml OBJ_id_smime_ct,28L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" +#define NID_id_smime_aa_signingCertificateV2 1086 +#define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define SN_sm2 "SM2" +#define LN_sm2 "sm2" +#define NID_sm2 1172 +#define OBJ_sm2 OBJ_sm_scheme,301L + +#define SN_sm3 "SM3" +#define LN_sm3 "sm3" +#define NID_sm3 1143 +#define OBJ_sm3 OBJ_sm_scheme,401L + +#define SN_sm3WithRSAEncryption "RSA-SM3" +#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" +#define NID_sm3WithRSAEncryption 1144 +#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define LN_hmacWithSHA512_224 "hmacWithSHA512-224" +#define NID_hmacWithSHA512_224 1193 +#define OBJ_hmacWithSHA512_224 OBJ_rsadsi,2L,12L + +#define LN_hmacWithSHA512_256 "hmacWithSHA512-256" +#define NID_hmacWithSHA512_256 1194 +#define OBJ_hmacWithSHA512_256 OBJ_rsadsi,2L,13L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcard Login" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft User Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_tlsfeature "tlsfeature" +#define LN_tlsfeature "TLS Feature" +#define NID_tlsfeature 1020 +#define OBJ_tlsfeature OBJ_id_pe,24L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_ipsec_IKE "ipsecIKE" +#define LN_ipsec_IKE "ipsec Internet Key Exchange" +#define NID_ipsec_IKE 1022 +#define OBJ_ipsec_IKE OBJ_id_kp,17L + +#define SN_capwapAC "capwapAC" +#define LN_capwapAC "Ctrl/provision WAP Access" +#define NID_capwapAC 1023 +#define OBJ_capwapAC OBJ_id_kp,18L + +#define SN_capwapWTP "capwapWTP" +#define LN_capwapWTP "Ctrl/Provision WAP Termination" +#define NID_capwapWTP 1024 +#define OBJ_capwapWTP OBJ_id_kp,19L + +#define SN_sshClient "secureShellClient" +#define LN_sshClient "SSH Client" +#define NID_sshClient 1025 +#define OBJ_sshClient OBJ_id_kp,21L + +#define SN_sshServer "secureShellServer" +#define LN_sshServer "SSH Server" +#define NID_sshServer 1026 +#define OBJ_sshServer OBJ_id_kp,22L + +#define SN_sendRouter "sendRouter" +#define LN_sendRouter "Send Router" +#define NID_sendRouter 1027 +#define OBJ_sendRouter OBJ_id_kp,23L + +#define SN_sendProxiedRouter "sendProxiedRouter" +#define LN_sendProxiedRouter "Send Proxied Router" +#define NID_sendProxiedRouter 1028 +#define OBJ_sendProxiedRouter OBJ_id_kp,24L + +#define SN_sendOwner "sendOwner" +#define LN_sendOwner "Send Owner" +#define NID_sendOwner 1029 +#define OBJ_sendOwner OBJ_id_kp,25L + +#define SN_sendProxiedOwner "sendProxiedOwner" +#define LN_sendProxiedOwner "Send Proxied Owner" +#define NID_sendProxiedOwner 1030 +#define OBJ_sendProxiedOwner OBJ_id_kp,26L + +#define SN_cmcCA "cmcCA" +#define LN_cmcCA "CMC Certificate Authority" +#define NID_cmcCA 1131 +#define OBJ_cmcCA OBJ_id_kp,27L + +#define SN_cmcRA "cmcRA" +#define LN_cmcRA "CMC Registration Authority" +#define NID_cmcRA 1132 +#define OBJ_cmcRA OBJ_id_kp,28L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_blake2b512 "BLAKE2b512" +#define LN_blake2b512 "blake2b512" +#define NID_blake2b512 1056 +#define OBJ_blake2b512 1L,3L,6L,1L,4L,1L,1722L,12L,2L,1L,16L + +#define SN_blake2s256 "BLAKE2s256" +#define LN_blake2s256 "blake2s256" +#define NID_blake2s256 1057 +#define OBJ_blake2s256 1L,3L,6L,1L,4L,1L,1722L,12L,2L,2L,8L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define LN_organizationIdentifier "organizationIdentifier" +#define NID_organizationIdentifier 1089 +#define OBJ_organizationIdentifier OBJ_X509,97L + +#define SN_countryCode3c "c3" +#define LN_countryCode3c "countryCode3c" +#define NID_countryCode3c 1090 +#define OBJ_countryCode3c OBJ_X509,98L + +#define SN_countryCode3n "n3" +#define LN_countryCode3n "countryCode3n" +#define NID_countryCode3n 1091 +#define OBJ_countryCode3n OBJ_X509,99L + +#define LN_dnsName "dnsName" +#define NID_dnsName 1092 +#define OBJ_dnsName OBJ_X509,100L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 +#define OBJ_aes_128_xts OBJ_ieee_siswg,0L,1L,1L + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 +#define OBJ_aes_256_xts OBJ_ieee_siswg,0L,1L,2L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_ocb "AES-128-OCB" +#define LN_aes_128_ocb "aes-128-ocb" +#define NID_aes_128_ocb 958 + +#define SN_aes_192_ocb "AES-192-OCB" +#define LN_aes_192_ocb "aes-192-ocb" +#define NID_aes_192_ocb 959 + +#define SN_aes_256_ocb "AES-256-OCB" +#define LN_aes_256_ocb "aes-256-ocb" +#define NID_aes_256_ocb 960 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define SN_sha512_224 "SHA512-224" +#define LN_sha512_224 "sha512-224" +#define NID_sha512_224 1094 +#define OBJ_sha512_224 OBJ_nist_hashalgs,5L + +#define SN_sha512_256 "SHA512-256" +#define LN_sha512_256 "sha512-256" +#define NID_sha512_256 1095 +#define OBJ_sha512_256 OBJ_nist_hashalgs,6L + +#define SN_sha3_224 "SHA3-224" +#define LN_sha3_224 "sha3-224" +#define NID_sha3_224 1096 +#define OBJ_sha3_224 OBJ_nist_hashalgs,7L + +#define SN_sha3_256 "SHA3-256" +#define LN_sha3_256 "sha3-256" +#define NID_sha3_256 1097 +#define OBJ_sha3_256 OBJ_nist_hashalgs,8L + +#define SN_sha3_384 "SHA3-384" +#define LN_sha3_384 "sha3-384" +#define NID_sha3_384 1098 +#define OBJ_sha3_384 OBJ_nist_hashalgs,9L + +#define SN_sha3_512 "SHA3-512" +#define LN_sha3_512 "sha3-512" +#define NID_sha3_512 1099 +#define OBJ_sha3_512 OBJ_nist_hashalgs,10L + +#define SN_shake128 "SHAKE128" +#define LN_shake128 "shake128" +#define NID_shake128 1100 +#define OBJ_shake128 OBJ_nist_hashalgs,11L + +#define SN_shake256 "SHAKE256" +#define LN_shake256 "shake256" +#define NID_shake256 1101 +#define OBJ_shake256 OBJ_nist_hashalgs,12L + +#define SN_hmac_sha3_224 "id-hmacWithSHA3-224" +#define LN_hmac_sha3_224 "hmac-sha3-224" +#define NID_hmac_sha3_224 1102 +#define OBJ_hmac_sha3_224 OBJ_nist_hashalgs,13L + +#define SN_hmac_sha3_256 "id-hmacWithSHA3-256" +#define LN_hmac_sha3_256 "hmac-sha3-256" +#define NID_hmac_sha3_256 1103 +#define OBJ_hmac_sha3_256 OBJ_nist_hashalgs,14L + +#define SN_hmac_sha3_384 "id-hmacWithSHA3-384" +#define LN_hmac_sha3_384 "hmac-sha3-384" +#define NID_hmac_sha3_384 1104 +#define OBJ_hmac_sha3_384 OBJ_nist_hashalgs,15L + +#define SN_hmac_sha3_512 "id-hmacWithSHA3-512" +#define LN_hmac_sha3_512 "hmac-sha3-512" +#define NID_hmac_sha3_512 1105 +#define OBJ_hmac_sha3_512 OBJ_nist_hashalgs,16L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define OBJ_sigAlgs OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA384 "id-dsa-with-sha384" +#define LN_dsa_with_SHA384 "dsa_with_SHA384" +#define NID_dsa_with_SHA384 1106 +#define OBJ_dsa_with_SHA384 OBJ_sigAlgs,3L + +#define SN_dsa_with_SHA512 "id-dsa-with-sha512" +#define LN_dsa_with_SHA512 "dsa_with_SHA512" +#define NID_dsa_with_SHA512 1107 +#define OBJ_dsa_with_SHA512 OBJ_sigAlgs,4L + +#define SN_dsa_with_SHA3_224 "id-dsa-with-sha3-224" +#define LN_dsa_with_SHA3_224 "dsa_with_SHA3-224" +#define NID_dsa_with_SHA3_224 1108 +#define OBJ_dsa_with_SHA3_224 OBJ_sigAlgs,5L + +#define SN_dsa_with_SHA3_256 "id-dsa-with-sha3-256" +#define LN_dsa_with_SHA3_256 "dsa_with_SHA3-256" +#define NID_dsa_with_SHA3_256 1109 +#define OBJ_dsa_with_SHA3_256 OBJ_sigAlgs,6L + +#define SN_dsa_with_SHA3_384 "id-dsa-with-sha3-384" +#define LN_dsa_with_SHA3_384 "dsa_with_SHA3-384" +#define NID_dsa_with_SHA3_384 1110 +#define OBJ_dsa_with_SHA3_384 OBJ_sigAlgs,7L + +#define SN_dsa_with_SHA3_512 "id-dsa-with-sha3-512" +#define LN_dsa_with_SHA3_512 "dsa_with_SHA3-512" +#define NID_dsa_with_SHA3_512 1111 +#define OBJ_dsa_with_SHA3_512 OBJ_sigAlgs,8L + +#define SN_ecdsa_with_SHA3_224 "id-ecdsa-with-sha3-224" +#define LN_ecdsa_with_SHA3_224 "ecdsa_with_SHA3-224" +#define NID_ecdsa_with_SHA3_224 1112 +#define OBJ_ecdsa_with_SHA3_224 OBJ_sigAlgs,9L + +#define SN_ecdsa_with_SHA3_256 "id-ecdsa-with-sha3-256" +#define LN_ecdsa_with_SHA3_256 "ecdsa_with_SHA3-256" +#define NID_ecdsa_with_SHA3_256 1113 +#define OBJ_ecdsa_with_SHA3_256 OBJ_sigAlgs,10L + +#define SN_ecdsa_with_SHA3_384 "id-ecdsa-with-sha3-384" +#define LN_ecdsa_with_SHA3_384 "ecdsa_with_SHA3-384" +#define NID_ecdsa_with_SHA3_384 1114 +#define OBJ_ecdsa_with_SHA3_384 OBJ_sigAlgs,11L + +#define SN_ecdsa_with_SHA3_512 "id-ecdsa-with-sha3-512" +#define LN_ecdsa_with_SHA3_512 "ecdsa_with_SHA3-512" +#define NID_ecdsa_with_SHA3_512 1115 +#define OBJ_ecdsa_with_SHA3_512 OBJ_sigAlgs,12L + +#define SN_RSA_SHA3_224 "id-rsassa-pkcs1-v1_5-with-sha3-224" +#define LN_RSA_SHA3_224 "RSA-SHA3-224" +#define NID_RSA_SHA3_224 1116 +#define OBJ_RSA_SHA3_224 OBJ_sigAlgs,13L + +#define SN_RSA_SHA3_256 "id-rsassa-pkcs1-v1_5-with-sha3-256" +#define LN_RSA_SHA3_256 "RSA-SHA3-256" +#define NID_RSA_SHA3_256 1117 +#define OBJ_RSA_SHA3_256 OBJ_sigAlgs,14L + +#define SN_RSA_SHA3_384 "id-rsassa-pkcs1-v1_5-with-sha3-384" +#define LN_RSA_SHA3_384 "RSA-SHA3-384" +#define NID_RSA_SHA3_384 1118 +#define OBJ_RSA_SHA3_384 OBJ_sigAlgs,15L + +#define SN_RSA_SHA3_512 "id-rsassa-pkcs1-v1_5-with-sha3-512" +#define LN_RSA_SHA3_512 "RSA-SHA3-512" +#define NID_RSA_SHA3_512 1119 +#define OBJ_RSA_SHA3_512 OBJ_sigAlgs,16L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define SN_uniqueIdentifier "uid" +#define LN_uniqueIdentifier "uniqueIdentifier" +#define NID_uniqueIdentifier 102 +#define OBJ_uniqueIdentifier OBJ_pilotAttributeType,44L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_tc26 "id-tc26" +#define NID_id_tc26 974 +#define OBJ_id_tc26 OBJ_member_body,643L,7L,1L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_gost89_cnt_12 "gost89-cnt-12" +#define NID_gost89_cnt_12 975 + +#define SN_gost89_cbc "gost89-cbc" +#define NID_gost89_cbc 1009 + +#define SN_gost89_ecb "gost89-ecb" +#define NID_gost89_ecb 1010 + +#define SN_gost89_ctr "gost89-ctr" +#define NID_gost89_ctr 1011 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_gost_mac_12 "gost-mac-12" +#define NID_gost_mac_12 976 + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_id_tc26_algorithms "id-tc26-algorithms" +#define NID_id_tc26_algorithms 977 +#define OBJ_id_tc26_algorithms OBJ_id_tc26,1L + +#define SN_id_tc26_sign "id-tc26-sign" +#define NID_id_tc26_sign 978 +#define OBJ_id_tc26_sign OBJ_id_tc26_algorithms,1L + +#define SN_id_GostR3410_2012_256 "gost2012_256" +#define LN_id_GostR3410_2012_256 "GOST R 34.10-2012 with 256 bit modulus" +#define NID_id_GostR3410_2012_256 979 +#define OBJ_id_GostR3410_2012_256 OBJ_id_tc26_sign,1L + +#define SN_id_GostR3410_2012_512 "gost2012_512" +#define LN_id_GostR3410_2012_512 "GOST R 34.10-2012 with 512 bit modulus" +#define NID_id_GostR3410_2012_512 980 +#define OBJ_id_GostR3410_2012_512 OBJ_id_tc26_sign,2L + +#define SN_id_tc26_digest "id-tc26-digest" +#define NID_id_tc26_digest 981 +#define OBJ_id_tc26_digest OBJ_id_tc26_algorithms,2L + +#define SN_id_GostR3411_2012_256 "md_gost12_256" +#define LN_id_GostR3411_2012_256 "GOST R 34.11-2012 with 256 bit hash" +#define NID_id_GostR3411_2012_256 982 +#define OBJ_id_GostR3411_2012_256 OBJ_id_tc26_digest,2L + +#define SN_id_GostR3411_2012_512 "md_gost12_512" +#define LN_id_GostR3411_2012_512 "GOST R 34.11-2012 with 512 bit hash" +#define NID_id_GostR3411_2012_512 983 +#define OBJ_id_GostR3411_2012_512 OBJ_id_tc26_digest,3L + +#define SN_id_tc26_signwithdigest "id-tc26-signwithdigest" +#define NID_id_tc26_signwithdigest 984 +#define OBJ_id_tc26_signwithdigest OBJ_id_tc26_algorithms,3L + +#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" +#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_256 985 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_id_tc26_signwithdigest,2L + +#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" +#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" +#define NID_id_tc26_signwithdigest_gost3410_2012_512 986 +#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_id_tc26_signwithdigest,3L + +#define SN_id_tc26_mac "id-tc26-mac" +#define NID_id_tc26_mac 987 +#define OBJ_id_tc26_mac OBJ_id_tc26_algorithms,4L + +#define SN_id_tc26_hmac_gost_3411_2012_256 "id-tc26-hmac-gost-3411-2012-256" +#define LN_id_tc26_hmac_gost_3411_2012_256 "HMAC GOST 34.11-2012 256 bit" +#define NID_id_tc26_hmac_gost_3411_2012_256 988 +#define OBJ_id_tc26_hmac_gost_3411_2012_256 OBJ_id_tc26_mac,1L + +#define SN_id_tc26_hmac_gost_3411_2012_512 "id-tc26-hmac-gost-3411-2012-512" +#define LN_id_tc26_hmac_gost_3411_2012_512 "HMAC GOST 34.11-2012 512 bit" +#define NID_id_tc26_hmac_gost_3411_2012_512 989 +#define OBJ_id_tc26_hmac_gost_3411_2012_512 OBJ_id_tc26_mac,2L + +#define SN_id_tc26_cipher "id-tc26-cipher" +#define NID_id_tc26_cipher 990 +#define OBJ_id_tc26_cipher OBJ_id_tc26_algorithms,5L + +#define SN_id_tc26_cipher_gostr3412_2015_magma "id-tc26-cipher-gostr3412-2015-magma" +#define NID_id_tc26_cipher_gostr3412_2015_magma 1173 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma OBJ_id_tc26_cipher,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm "id-tc26-cipher-gostr3412-2015-magma-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm 1174 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_magma,1L + +#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-magma-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac 1175 +#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_magma,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik "id-tc26-cipher-gostr3412-2015-kuznyechik" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik 1176 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik OBJ_id_tc26_cipher,2L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm 1177 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac "id-tc26-cipher-gostr3412-2015-kuznyechik-ctracpkm-omac" +#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac 1178 +#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,2L + +#define SN_id_tc26_agreement "id-tc26-agreement" +#define NID_id_tc26_agreement 991 +#define OBJ_id_tc26_agreement OBJ_id_tc26_algorithms,6L + +#define SN_id_tc26_agreement_gost_3410_2012_256 "id-tc26-agreement-gost-3410-2012-256" +#define NID_id_tc26_agreement_gost_3410_2012_256 992 +#define OBJ_id_tc26_agreement_gost_3410_2012_256 OBJ_id_tc26_agreement,1L + +#define SN_id_tc26_agreement_gost_3410_2012_512 "id-tc26-agreement-gost-3410-2012-512" +#define NID_id_tc26_agreement_gost_3410_2012_512 993 +#define OBJ_id_tc26_agreement_gost_3410_2012_512 OBJ_id_tc26_agreement,2L + +#define SN_id_tc26_wrap "id-tc26-wrap" +#define NID_id_tc26_wrap 1179 +#define OBJ_id_tc26_wrap OBJ_id_tc26_algorithms,7L + +#define SN_id_tc26_wrap_gostr3412_2015_magma "id-tc26-wrap-gostr3412-2015-magma" +#define NID_id_tc26_wrap_gostr3412_2015_magma 1180 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma OBJ_id_tc26_wrap,1L + +#define SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 "id-tc26-wrap-gostr3412-2015-magma-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 1181 +#define OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_magma,1L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik "id-tc26-wrap-gostr3412-2015-kuznyechik" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik 1182 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik OBJ_id_tc26_wrap,2L + +#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15" +#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1183 +#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik,1L + +#define SN_id_tc26_constants "id-tc26-constants" +#define NID_id_tc26_constants 994 +#define OBJ_id_tc26_constants OBJ_id_tc26,2L + +#define SN_id_tc26_sign_constants "id-tc26-sign-constants" +#define NID_id_tc26_sign_constants 995 +#define OBJ_id_tc26_sign_constants OBJ_id_tc26_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_constants "id-tc26-gost-3410-2012-256-constants" +#define NID_id_tc26_gost_3410_2012_256_constants 1147 +#define OBJ_id_tc26_gost_3410_2012_256_constants OBJ_id_tc26_sign_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetA "id-tc26-gost-3410-2012-256-paramSetA" +#define LN_id_tc26_gost_3410_2012_256_paramSetA "GOST R 34.10-2012 (256 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_256_paramSetA 1148 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetA OBJ_id_tc26_gost_3410_2012_256_constants,1L + +#define SN_id_tc26_gost_3410_2012_256_paramSetB "id-tc26-gost-3410-2012-256-paramSetB" +#define LN_id_tc26_gost_3410_2012_256_paramSetB "GOST R 34.10-2012 (256 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_256_paramSetB 1184 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetB OBJ_id_tc26_gost_3410_2012_256_constants,2L + +#define SN_id_tc26_gost_3410_2012_256_paramSetC "id-tc26-gost-3410-2012-256-paramSetC" +#define LN_id_tc26_gost_3410_2012_256_paramSetC "GOST R 34.10-2012 (256 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_256_paramSetC 1185 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetC OBJ_id_tc26_gost_3410_2012_256_constants,3L + +#define SN_id_tc26_gost_3410_2012_256_paramSetD "id-tc26-gost-3410-2012-256-paramSetD" +#define LN_id_tc26_gost_3410_2012_256_paramSetD "GOST R 34.10-2012 (256 bit) ParamSet D" +#define NID_id_tc26_gost_3410_2012_256_paramSetD 1186 +#define OBJ_id_tc26_gost_3410_2012_256_paramSetD OBJ_id_tc26_gost_3410_2012_256_constants,4L + +#define SN_id_tc26_gost_3410_2012_512_constants "id-tc26-gost-3410-2012-512-constants" +#define NID_id_tc26_gost_3410_2012_512_constants 996 +#define OBJ_id_tc26_gost_3410_2012_512_constants OBJ_id_tc26_sign_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetTest "id-tc26-gost-3410-2012-512-paramSetTest" +#define LN_id_tc26_gost_3410_2012_512_paramSetTest "GOST R 34.10-2012 (512 bit) testing parameter set" +#define NID_id_tc26_gost_3410_2012_512_paramSetTest 997 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetTest OBJ_id_tc26_gost_3410_2012_512_constants,0L + +#define SN_id_tc26_gost_3410_2012_512_paramSetA "id-tc26-gost-3410-2012-512-paramSetA" +#define LN_id_tc26_gost_3410_2012_512_paramSetA "GOST R 34.10-2012 (512 bit) ParamSet A" +#define NID_id_tc26_gost_3410_2012_512_paramSetA 998 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetA OBJ_id_tc26_gost_3410_2012_512_constants,1L + +#define SN_id_tc26_gost_3410_2012_512_paramSetB "id-tc26-gost-3410-2012-512-paramSetB" +#define LN_id_tc26_gost_3410_2012_512_paramSetB "GOST R 34.10-2012 (512 bit) ParamSet B" +#define NID_id_tc26_gost_3410_2012_512_paramSetB 999 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetB OBJ_id_tc26_gost_3410_2012_512_constants,2L + +#define SN_id_tc26_gost_3410_2012_512_paramSetC "id-tc26-gost-3410-2012-512-paramSetC" +#define LN_id_tc26_gost_3410_2012_512_paramSetC "GOST R 34.10-2012 (512 bit) ParamSet C" +#define NID_id_tc26_gost_3410_2012_512_paramSetC 1149 +#define OBJ_id_tc26_gost_3410_2012_512_paramSetC OBJ_id_tc26_gost_3410_2012_512_constants,3L + +#define SN_id_tc26_digest_constants "id-tc26-digest-constants" +#define NID_id_tc26_digest_constants 1000 +#define OBJ_id_tc26_digest_constants OBJ_id_tc26_constants,2L + +#define SN_id_tc26_cipher_constants "id-tc26-cipher-constants" +#define NID_id_tc26_cipher_constants 1001 +#define OBJ_id_tc26_cipher_constants OBJ_id_tc26_constants,5L + +#define SN_id_tc26_gost_28147_constants "id-tc26-gost-28147-constants" +#define NID_id_tc26_gost_28147_constants 1002 +#define OBJ_id_tc26_gost_28147_constants OBJ_id_tc26_cipher_constants,1L + +#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" +#define LN_id_tc26_gost_28147_param_Z "GOST 28147-89 TC26 parameter set" +#define NID_id_tc26_gost_28147_param_Z 1003 +#define OBJ_id_tc26_gost_28147_param_Z OBJ_id_tc26_gost_28147_constants,1L + +#define SN_INN "INN" +#define LN_INN "INN" +#define NID_INN 1004 +#define OBJ_INN OBJ_member_body,643L,3L,131L,1L,1L + +#define SN_OGRN "OGRN" +#define LN_OGRN "OGRN" +#define NID_OGRN 1005 +#define OBJ_OGRN OBJ_member_body,643L,100L,1L + +#define SN_SNILS "SNILS" +#define LN_SNILS "SNILS" +#define NID_SNILS 1006 +#define OBJ_SNILS OBJ_member_body,643L,100L,3L + +#define SN_subjectSignTool "subjectSignTool" +#define LN_subjectSignTool "Signing Tool of Subject" +#define NID_subjectSignTool 1007 +#define OBJ_subjectSignTool OBJ_member_body,643L,100L,111L + +#define SN_issuerSignTool "issuerSignTool" +#define LN_issuerSignTool "Signing Tool of Issuer" +#define NID_issuerSignTool 1008 +#define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L + +#define SN_grasshopper_ecb "grasshopper-ecb" +#define NID_grasshopper_ecb 1012 + +#define SN_grasshopper_ctr "grasshopper-ctr" +#define NID_grasshopper_ctr 1013 + +#define SN_grasshopper_ofb "grasshopper-ofb" +#define NID_grasshopper_ofb 1014 + +#define SN_grasshopper_cbc "grasshopper-cbc" +#define NID_grasshopper_cbc 1015 + +#define SN_grasshopper_cfb "grasshopper-cfb" +#define NID_grasshopper_cfb 1016 + +#define SN_grasshopper_mac "grasshopper-mac" +#define NID_grasshopper_mac 1017 + +#define SN_magma_ecb "magma-ecb" +#define NID_magma_ecb 1187 + +#define SN_magma_ctr "magma-ctr" +#define NID_magma_ctr 1188 + +#define SN_magma_ofb "magma-ofb" +#define NID_magma_ofb 1189 + +#define SN_magma_cbc "magma-cbc" +#define NID_magma_cbc 1190 + +#define SN_magma_cfb "magma-cfb" +#define NID_magma_cfb 1191 + +#define SN_magma_mac "magma-mac" +#define NID_magma_mac 1192 + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_128_gcm "CAMELLIA-128-GCM" +#define LN_camellia_128_gcm "camellia-128-gcm" +#define NID_camellia_128_gcm 961 +#define OBJ_camellia_128_gcm OBJ_camellia,6L + +#define SN_camellia_128_ccm "CAMELLIA-128-CCM" +#define LN_camellia_128_ccm "camellia-128-ccm" +#define NID_camellia_128_ccm 962 +#define OBJ_camellia_128_ccm OBJ_camellia,7L + +#define SN_camellia_128_ctr "CAMELLIA-128-CTR" +#define LN_camellia_128_ctr "camellia-128-ctr" +#define NID_camellia_128_ctr 963 +#define OBJ_camellia_128_ctr OBJ_camellia,9L + +#define SN_camellia_128_cmac "CAMELLIA-128-CMAC" +#define LN_camellia_128_cmac "camellia-128-cmac" +#define NID_camellia_128_cmac 964 +#define OBJ_camellia_128_cmac OBJ_camellia,10L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_192_gcm "CAMELLIA-192-GCM" +#define LN_camellia_192_gcm "camellia-192-gcm" +#define NID_camellia_192_gcm 965 +#define OBJ_camellia_192_gcm OBJ_camellia,26L + +#define SN_camellia_192_ccm "CAMELLIA-192-CCM" +#define LN_camellia_192_ccm "camellia-192-ccm" +#define NID_camellia_192_ccm 966 +#define OBJ_camellia_192_ccm OBJ_camellia,27L + +#define SN_camellia_192_ctr "CAMELLIA-192-CTR" +#define LN_camellia_192_ctr "camellia-192-ctr" +#define NID_camellia_192_ctr 967 +#define OBJ_camellia_192_ctr OBJ_camellia,29L + +#define SN_camellia_192_cmac "CAMELLIA-192-CMAC" +#define LN_camellia_192_cmac "camellia-192-cmac" +#define NID_camellia_192_cmac 968 +#define OBJ_camellia_192_cmac OBJ_camellia,30L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_256_gcm "CAMELLIA-256-GCM" +#define LN_camellia_256_gcm "camellia-256-gcm" +#define NID_camellia_256_gcm 969 +#define OBJ_camellia_256_gcm OBJ_camellia,46L + +#define SN_camellia_256_ccm "CAMELLIA-256-CCM" +#define LN_camellia_256_ccm "camellia-256-ccm" +#define NID_camellia_256_ccm 970 +#define OBJ_camellia_256_ccm OBJ_camellia,47L + +#define SN_camellia_256_ctr "CAMELLIA-256-CTR" +#define LN_camellia_256_ctr "camellia-256-ctr" +#define NID_camellia_256_ctr 971 +#define OBJ_camellia_256_ctr OBJ_camellia,49L + +#define SN_camellia_256_cmac "CAMELLIA-256-CMAC" +#define LN_camellia_256_cmac "camellia-256-cmac" +#define NID_camellia_256_cmac 972 +#define OBJ_camellia_256_cmac OBJ_camellia,50L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define OBJ_aria 1L,2L,410L,200046L,1L,1L + +#define SN_aria_128_ecb "ARIA-128-ECB" +#define LN_aria_128_ecb "aria-128-ecb" +#define NID_aria_128_ecb 1065 +#define OBJ_aria_128_ecb OBJ_aria,1L + +#define SN_aria_128_cbc "ARIA-128-CBC" +#define LN_aria_128_cbc "aria-128-cbc" +#define NID_aria_128_cbc 1066 +#define OBJ_aria_128_cbc OBJ_aria,2L + +#define SN_aria_128_cfb128 "ARIA-128-CFB" +#define LN_aria_128_cfb128 "aria-128-cfb" +#define NID_aria_128_cfb128 1067 +#define OBJ_aria_128_cfb128 OBJ_aria,3L + +#define SN_aria_128_ofb128 "ARIA-128-OFB" +#define LN_aria_128_ofb128 "aria-128-ofb" +#define NID_aria_128_ofb128 1068 +#define OBJ_aria_128_ofb128 OBJ_aria,4L + +#define SN_aria_128_ctr "ARIA-128-CTR" +#define LN_aria_128_ctr "aria-128-ctr" +#define NID_aria_128_ctr 1069 +#define OBJ_aria_128_ctr OBJ_aria,5L + +#define SN_aria_192_ecb "ARIA-192-ECB" +#define LN_aria_192_ecb "aria-192-ecb" +#define NID_aria_192_ecb 1070 +#define OBJ_aria_192_ecb OBJ_aria,6L + +#define SN_aria_192_cbc "ARIA-192-CBC" +#define LN_aria_192_cbc "aria-192-cbc" +#define NID_aria_192_cbc 1071 +#define OBJ_aria_192_cbc OBJ_aria,7L + +#define SN_aria_192_cfb128 "ARIA-192-CFB" +#define LN_aria_192_cfb128 "aria-192-cfb" +#define NID_aria_192_cfb128 1072 +#define OBJ_aria_192_cfb128 OBJ_aria,8L + +#define SN_aria_192_ofb128 "ARIA-192-OFB" +#define LN_aria_192_ofb128 "aria-192-ofb" +#define NID_aria_192_ofb128 1073 +#define OBJ_aria_192_ofb128 OBJ_aria,9L + +#define SN_aria_192_ctr "ARIA-192-CTR" +#define LN_aria_192_ctr "aria-192-ctr" +#define NID_aria_192_ctr 1074 +#define OBJ_aria_192_ctr OBJ_aria,10L + +#define SN_aria_256_ecb "ARIA-256-ECB" +#define LN_aria_256_ecb "aria-256-ecb" +#define NID_aria_256_ecb 1075 +#define OBJ_aria_256_ecb OBJ_aria,11L + +#define SN_aria_256_cbc "ARIA-256-CBC" +#define LN_aria_256_cbc "aria-256-cbc" +#define NID_aria_256_cbc 1076 +#define OBJ_aria_256_cbc OBJ_aria,12L + +#define SN_aria_256_cfb128 "ARIA-256-CFB" +#define LN_aria_256_cfb128 "aria-256-cfb" +#define NID_aria_256_cfb128 1077 +#define OBJ_aria_256_cfb128 OBJ_aria,13L + +#define SN_aria_256_ofb128 "ARIA-256-OFB" +#define LN_aria_256_ofb128 "aria-256-ofb" +#define NID_aria_256_ofb128 1078 +#define OBJ_aria_256_ofb128 OBJ_aria,14L + +#define SN_aria_256_ctr "ARIA-256-CTR" +#define LN_aria_256_ctr "aria-256-ctr" +#define NID_aria_256_ctr 1079 +#define OBJ_aria_256_ctr OBJ_aria,15L + +#define SN_aria_128_cfb1 "ARIA-128-CFB1" +#define LN_aria_128_cfb1 "aria-128-cfb1" +#define NID_aria_128_cfb1 1080 + +#define SN_aria_192_cfb1 "ARIA-192-CFB1" +#define LN_aria_192_cfb1 "aria-192-cfb1" +#define NID_aria_192_cfb1 1081 + +#define SN_aria_256_cfb1 "ARIA-256-CFB1" +#define LN_aria_256_cfb1 "aria-256-cfb1" +#define NID_aria_256_cfb1 1082 + +#define SN_aria_128_cfb8 "ARIA-128-CFB8" +#define LN_aria_128_cfb8 "aria-128-cfb8" +#define NID_aria_128_cfb8 1083 + +#define SN_aria_192_cfb8 "ARIA-192-CFB8" +#define LN_aria_192_cfb8 "aria-192-cfb8" +#define NID_aria_192_cfb8 1084 + +#define SN_aria_256_cfb8 "ARIA-256-CFB8" +#define LN_aria_256_cfb8 "aria-256-cfb8" +#define NID_aria_256_cfb8 1085 + +#define SN_aria_128_ccm "ARIA-128-CCM" +#define LN_aria_128_ccm "aria-128-ccm" +#define NID_aria_128_ccm 1120 +#define OBJ_aria_128_ccm OBJ_aria,37L + +#define SN_aria_192_ccm "ARIA-192-CCM" +#define LN_aria_192_ccm "aria-192-ccm" +#define NID_aria_192_ccm 1121 +#define OBJ_aria_192_ccm OBJ_aria,38L + +#define SN_aria_256_ccm "ARIA-256-CCM" +#define LN_aria_256_ccm "aria-256-ccm" +#define NID_aria_256_ccm 1122 +#define OBJ_aria_256_ccm OBJ_aria,39L + +#define SN_aria_128_gcm "ARIA-128-GCM" +#define LN_aria_128_gcm "aria-128-gcm" +#define NID_aria_128_gcm 1123 +#define OBJ_aria_128_gcm OBJ_aria,34L + +#define SN_aria_192_gcm "ARIA-192-GCM" +#define LN_aria_192_gcm "aria-192-gcm" +#define NID_aria_192_gcm 1124 +#define OBJ_aria_192_gcm OBJ_aria,35L + +#define SN_aria_256_gcm "ARIA-256-GCM" +#define LN_aria_256_gcm "aria-256-gcm" +#define NID_aria_256_gcm 1125 +#define OBJ_aria_256_gcm OBJ_aria,36L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_sm4_ecb "SM4-ECB" +#define LN_sm4_ecb "sm4-ecb" +#define NID_sm4_ecb 1133 +#define OBJ_sm4_ecb OBJ_sm_scheme,104L,1L + +#define SN_sm4_cbc "SM4-CBC" +#define LN_sm4_cbc "sm4-cbc" +#define NID_sm4_cbc 1134 +#define OBJ_sm4_cbc OBJ_sm_scheme,104L,2L + +#define SN_sm4_ofb128 "SM4-OFB" +#define LN_sm4_ofb128 "sm4-ofb" +#define NID_sm4_ofb128 1135 +#define OBJ_sm4_ofb128 OBJ_sm_scheme,104L,3L + +#define SN_sm4_cfb128 "SM4-CFB" +#define LN_sm4_cfb128 "sm4-cfb" +#define NID_sm4_cfb128 1137 +#define OBJ_sm4_cfb128 OBJ_sm_scheme,104L,4L + +#define SN_sm4_cfb1 "SM4-CFB1" +#define LN_sm4_cfb1 "sm4-cfb1" +#define NID_sm4_cfb1 1136 +#define OBJ_sm4_cfb1 OBJ_sm_scheme,104L,5L + +#define SN_sm4_cfb8 "SM4-CFB8" +#define LN_sm4_cfb8 "sm4-cfb8" +#define NID_sm4_cfb8 1138 +#define OBJ_sm4_cfb8 OBJ_sm_scheme,104L,6L + +#define SN_sm4_ctr "SM4-CTR" +#define LN_sm4_ctr "sm4-ctr" +#define NID_sm4_ctr 1139 +#define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" +#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" +#define NID_aes_128_cbc_hmac_sha256 948 + +#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" +#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" +#define NID_aes_192_cbc_hmac_sha256 949 + +#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" +#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" +#define NID_aes_256_cbc_hmac_sha256 950 + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 1018 + +#define SN_chacha20 "ChaCha20" +#define LN_chacha20 "chacha20" +#define NID_chacha20 1019 + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 951 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 952 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 953 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 954 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_jurisdictionLocalityName "jurisdictionL" +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 955 +#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L + +#define SN_jurisdictionStateOrProvinceName "jurisdictionST" +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 956 +#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L + +#define SN_jurisdictionCountryName "jurisdictionC" +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 957 +#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L + +#define SN_id_scrypt "id-scrypt" +#define LN_id_scrypt "scrypt" +#define NID_id_scrypt 973 +#define OBJ_id_scrypt 1L,3L,6L,1L,4L,1L,11591L,4L,11L + +#define SN_tls1_prf "TLS1-PRF" +#define LN_tls1_prf "tls1-prf" +#define NID_tls1_prf 1021 + +#define SN_hkdf "HKDF" +#define LN_hkdf "hkdf" +#define NID_hkdf 1036 + +#define SN_id_pkinit "id-pkinit" +#define NID_id_pkinit 1031 +#define OBJ_id_pkinit 1L,3L,6L,1L,5L,2L,3L + +#define SN_pkInitClientAuth "pkInitClientAuth" +#define LN_pkInitClientAuth "PKINIT Client Auth" +#define NID_pkInitClientAuth 1032 +#define OBJ_pkInitClientAuth OBJ_id_pkinit,4L + +#define SN_pkInitKDC "pkInitKDC" +#define LN_pkInitKDC "Signing KDC Response" +#define NID_pkInitKDC 1033 +#define OBJ_pkInitKDC OBJ_id_pkinit,5L + +#define SN_X25519 "X25519" +#define NID_X25519 1034 +#define OBJ_X25519 1L,3L,101L,110L + +#define SN_X448 "X448" +#define NID_X448 1035 +#define OBJ_X448 1L,3L,101L,111L + +#define SN_ED25519 "ED25519" +#define NID_ED25519 1087 +#define OBJ_ED25519 1L,3L,101L,112L + +#define SN_ED448 "ED448" +#define NID_ED448 1088 +#define OBJ_ED448 1L,3L,101L,113L + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 1037 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 1038 + +#define SN_kx_dhe "KxDHE" +#define LN_kx_dhe "kx-dhe" +#define NID_kx_dhe 1039 + +#define SN_kx_ecdhe_psk "KxECDHE-PSK" +#define LN_kx_ecdhe_psk "kx-ecdhe-psk" +#define NID_kx_ecdhe_psk 1040 + +#define SN_kx_dhe_psk "KxDHE-PSK" +#define LN_kx_dhe_psk "kx-dhe-psk" +#define NID_kx_dhe_psk 1041 + +#define SN_kx_rsa_psk "KxRSA_PSK" +#define LN_kx_rsa_psk "kx-rsa-psk" +#define NID_kx_rsa_psk 1042 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 1043 + +#define SN_kx_srp "KxSRP" +#define LN_kx_srp "kx-srp" +#define NID_kx_srp 1044 + +#define SN_kx_gost "KxGOST" +#define LN_kx_gost "kx-gost" +#define NID_kx_gost 1045 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 1063 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 1046 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 1047 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 1048 + +#define SN_auth_dss "AuthDSS" +#define LN_auth_dss "auth-dss" +#define NID_auth_dss 1049 + +#define SN_auth_gost01 "AuthGOST01" +#define LN_auth_gost01 "auth-gost01" +#define NID_auth_gost01 1050 + +#define SN_auth_gost12 "AuthGOST12" +#define LN_auth_gost12 "auth-gost12" +#define NID_auth_gost12 1051 + +#define SN_auth_srp "AuthSRP" +#define LN_auth_srp "auth-srp" +#define NID_auth_srp 1052 + +#define SN_auth_null "AuthNULL" +#define LN_auth_null "auth-null" +#define NID_auth_null 1053 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 1064 + +#define SN_poly1305 "Poly1305" +#define LN_poly1305 "poly1305" +#define NID_poly1305 1061 + +#define SN_siphash "SipHash" +#define LN_siphash "siphash" +#define NID_siphash 1062 + +#define SN_ffdhe2048 "ffdhe2048" +#define NID_ffdhe2048 1126 + +#define SN_ffdhe3072 "ffdhe3072" +#define NID_ffdhe3072 1127 + +#define SN_ffdhe4096 "ffdhe4096" +#define NID_ffdhe4096 1128 + +#define SN_ffdhe6144 "ffdhe6144" +#define NID_ffdhe6144 1129 + +#define SN_ffdhe8192 "ffdhe8192" +#define NID_ffdhe8192 1130 + +#define SN_ISO_UA "ISO-UA" +#define NID_ISO_UA 1150 +#define OBJ_ISO_UA OBJ_member_body,804L + +#define SN_ua_pki "ua-pki" +#define NID_ua_pki 1151 +#define OBJ_ua_pki OBJ_ISO_UA,2L,1L,1L,1L + +#define SN_dstu28147 "dstu28147" +#define LN_dstu28147 "DSTU Gost 28147-2009" +#define NID_dstu28147 1152 +#define OBJ_dstu28147 OBJ_ua_pki,1L,1L,1L + +#define SN_dstu28147_ofb "dstu28147-ofb" +#define LN_dstu28147_ofb "DSTU Gost 28147-2009 OFB mode" +#define NID_dstu28147_ofb 1153 +#define OBJ_dstu28147_ofb OBJ_dstu28147,2L + +#define SN_dstu28147_cfb "dstu28147-cfb" +#define LN_dstu28147_cfb "DSTU Gost 28147-2009 CFB mode" +#define NID_dstu28147_cfb 1154 +#define OBJ_dstu28147_cfb OBJ_dstu28147,3L + +#define SN_dstu28147_wrap "dstu28147-wrap" +#define LN_dstu28147_wrap "DSTU Gost 28147-2009 key wrap" +#define NID_dstu28147_wrap 1155 +#define OBJ_dstu28147_wrap OBJ_dstu28147,5L + +#define SN_hmacWithDstu34311 "hmacWithDstu34311" +#define LN_hmacWithDstu34311 "HMAC DSTU Gost 34311-95" +#define NID_hmacWithDstu34311 1156 +#define OBJ_hmacWithDstu34311 OBJ_ua_pki,1L,1L,2L + +#define SN_dstu34311 "dstu34311" +#define LN_dstu34311 "DSTU Gost 34311-95" +#define NID_dstu34311 1157 +#define OBJ_dstu34311 OBJ_ua_pki,1L,2L,1L + +#define SN_dstu4145le "dstu4145le" +#define LN_dstu4145le "DSTU 4145-2002 little endian" +#define NID_dstu4145le 1158 +#define OBJ_dstu4145le OBJ_ua_pki,1L,3L,1L,1L + +#define SN_dstu4145be "dstu4145be" +#define LN_dstu4145be "DSTU 4145-2002 big endian" +#define NID_dstu4145be 1159 +#define OBJ_dstu4145be OBJ_dstu4145le,1L,1L + +#define SN_uacurve0 "uacurve0" +#define LN_uacurve0 "DSTU curve 0" +#define NID_uacurve0 1160 +#define OBJ_uacurve0 OBJ_dstu4145le,2L,0L + +#define SN_uacurve1 "uacurve1" +#define LN_uacurve1 "DSTU curve 1" +#define NID_uacurve1 1161 +#define OBJ_uacurve1 OBJ_dstu4145le,2L,1L + +#define SN_uacurve2 "uacurve2" +#define LN_uacurve2 "DSTU curve 2" +#define NID_uacurve2 1162 +#define OBJ_uacurve2 OBJ_dstu4145le,2L,2L + +#define SN_uacurve3 "uacurve3" +#define LN_uacurve3 "DSTU curve 3" +#define NID_uacurve3 1163 +#define OBJ_uacurve3 OBJ_dstu4145le,2L,3L + +#define SN_uacurve4 "uacurve4" +#define LN_uacurve4 "DSTU curve 4" +#define NID_uacurve4 1164 +#define OBJ_uacurve4 OBJ_dstu4145le,2L,4L + +#define SN_uacurve5 "uacurve5" +#define LN_uacurve5 "DSTU curve 5" +#define NID_uacurve5 1165 +#define OBJ_uacurve5 OBJ_dstu4145le,2L,5L + +#define SN_uacurve6 "uacurve6" +#define LN_uacurve6 "DSTU curve 6" +#define NID_uacurve6 1166 +#define OBJ_uacurve6 OBJ_dstu4145le,2L,6L + +#define SN_uacurve7 "uacurve7" +#define LN_uacurve7 "DSTU curve 7" +#define NID_uacurve7 1167 +#define OBJ_uacurve7 OBJ_dstu4145le,2L,7L + +#define SN_uacurve8 "uacurve8" +#define LN_uacurve8 "DSTU curve 8" +#define NID_uacurve8 1168 +#define OBJ_uacurve8 OBJ_dstu4145le,2L,8L + +#define SN_uacurve9 "uacurve9" +#define LN_uacurve9 "DSTU curve 9" +#define NID_uacurve9 1169 +#define OBJ_uacurve9 OBJ_dstu4145le,2L,9L diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/objects.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/objects.h new file mode 100644 index 00000000..5e8b5762 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/objects.h @@ -0,0 +1,175 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# include +# include +# include +# include + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignment discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, declare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +#if OPENSSL_API_COMPAT < 0x10100000L +# define OBJ_cleanup() while(0) continue +#endif +int OBJ_create_objects(BIO *in); + +size_t OBJ_length(const ASN1_OBJECT *obj); +const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/objectserr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/objectserr.h new file mode 100644 index 00000000..02e166f1 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/objectserr.h @@ -0,0 +1,42 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OBJERR_H +# define HEADER_OBJERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OBJ_strings(void); + +/* + * OBJ function codes. + */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_ADD_SIGID 107 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 +# define OBJ_F_OBJ_TXT2OBJ 108 + +/* + * OBJ reason codes. + */ +# define OBJ_R_OID_EXISTS 102 +# define OBJ_R_UNKNOWN_NID 101 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsp.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsp.h new file mode 100644 index 00000000..4d759a49 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsp.h @@ -0,0 +1,352 @@ +/* + * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +#include + +/* + * These definitions are outside the OPENSSL_NO_OCSP guard because although for + * historical reasons they have OCSP_* names, they can actually be used + * independently of OCSP. E.g. see RFC5280 + */ +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + + +# ifndef OPENSSL_NO_OCSP + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +typedef struct ocsp_cert_id_st OCSP_CERTID; + +DEFINE_STACK_OF(OCSP_CERTID) + +typedef struct ocsp_one_request_st OCSP_ONEREQ; + +DEFINE_STACK_OF(OCSP_ONEREQ) + +typedef struct ocsp_req_info_st OCSP_REQINFO; +typedef struct ocsp_signature_st OCSP_SIGNATURE; +typedef struct ocsp_request_st OCSP_REQUEST; + +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; + +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 + +DEFINE_STACK_OF(OCSP_RESPID) + +typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; + +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 + +typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; +typedef struct ocsp_single_response_st OCSP_SINGLERESP; + +DEFINE_STACK_OF(OCSP_SINGLERESP) + +typedef struct ocsp_response_data_st OCSP_RESPDATA; + +typedef struct ocsp_basic_response_st OCSP_BASICRESP; + +typedef struct ocsp_crl_id_st OCSP_CRLID; +typedef struct ocsp_service_locator_st OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST, \ + bp,(char **)(x),cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) (OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE, \ + bp,(char **)(x),cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, + const X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, + const ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs); +const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs); +const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs); +const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, + const ASN1_OCTET_STRING **pid, + const X509_NAME **pname); +int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, + ASN1_OCTET_STRING **pid, + X509_NAME **pname); + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); +int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, + X509 *signer, EVP_MD_CTX *ctx, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert); + +X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); +const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsperr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsperr.h new file mode 100644 index 00000000..8dd9e01a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ocsperr.h @@ -0,0 +1,78 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OCSPERR_H +# define HEADER_OCSPERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_OCSP + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OCSP_strings(void); + +/* + * OCSP function codes. + */ +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_SIGN_CTX 119 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_PARSE_HTTP_LINE1 118 + +/* + * OCSP reason codes. + */ +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_NO_SIGNER_KEY 130 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslconf.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslconf.h new file mode 100644 index 00000000..942b46db --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslconf.h @@ -0,0 +1,195 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/opensslconf.h.in + * + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_ALGORITHM_DEFINES +# error OPENSSL_ALGORITHM_DEFINES no longer supported +#endif + +/* + * OpenSSL was configured with the following options: + */ + +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_RAND_SEED_OS +# define OPENSSL_RAND_SEED_OS +#endif +#ifndef OPENSSL_NO_AFALGENG +# define OPENSSL_NO_AFALGENG +#endif +#ifndef OPENSSL_NO_ASAN +# define OPENSSL_NO_ASAN +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG +# define OPENSSL_NO_CRYPTO_MDEBUG +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE +#endif +#ifndef OPENSSL_NO_DEVCRYPTOENG +# define OPENSSL_NO_DEVCRYPTOENG +#endif +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_EGD +# define OPENSSL_NO_EGD +#endif +#ifndef OPENSSL_NO_EXTERNAL_TESTS +# define OPENSSL_NO_EXTERNAL_TESTS +#endif +#ifndef OPENSSL_NO_FUZZ_AFL +# define OPENSSL_NO_FUZZ_AFL +#endif +#ifndef OPENSSL_NO_FUZZ_LIBFUZZER +# define OPENSSL_NO_FUZZ_LIBFUZZER +#endif +#ifndef OPENSSL_NO_HEARTBEATS +# define OPENSSL_NO_HEARTBEATS +#endif +#ifndef OPENSSL_NO_MSAN +# define OPENSSL_NO_MSAN +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL3 +# define OPENSSL_NO_SSL3 +#endif +#ifndef OPENSSL_NO_SSL3_METHOD +# define OPENSSL_NO_SSL3_METHOD +#endif +#ifndef OPENSSL_NO_UBSAN +# define OPENSSL_NO_UBSAN +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif +#ifndef OPENSSL_NO_STATIC_ENGINE +# define OPENSSL_NO_STATIC_ENGINE +#endif + + +/* + * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers + * don't like that. This will hopefully silence them. + */ +#define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy; + +/* + * Applications should use -DOPENSSL_API_COMPAT= to suppress the + * declarations of functions deprecated in or before . Otherwise, they + * still won't see them if the library has been built to disable deprecated + * functions. + */ +#ifndef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f; +# ifdef __GNUC__ +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) +# undef DECLARE_DEPRECATED +# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); +# endif +# endif +#endif + +#ifndef OPENSSL_FILE +# ifdef OPENSSL_NO_FILENAMES +# define OPENSSL_FILE "" +# define OPENSSL_LINE 0 +# else +# define OPENSSL_FILE __FILE__ +# define OPENSSL_LINE __LINE__ +# endif +#endif + +#ifndef OPENSSL_MIN_API +# define OPENSSL_MIN_API 0 +#endif + +#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API +# undef OPENSSL_API_COMPAT +# define OPENSSL_API_COMPAT OPENSSL_MIN_API +#endif + +/* + * Do not deprecate things to be deprecated in version 1.2.0 before the + * OpenSSL version number matches. + */ +#if OPENSSL_VERSION_NUMBER < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) f; +#elif OPENSSL_API_COMPAT < 0x10200000L +# define DEPRECATEDIN_1_2_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_2_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10100000L +# define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_1_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x10000000L +# define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_1_0_0(f) +#endif + +#if OPENSSL_API_COMPAT < 0x00908000L +# define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) +#else +# define DEPRECATEDIN_0_9_8(f) +#endif + +/* Generate 80386 code? */ +#undef I386_ONLY + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* + * The following are cipher-specific, but are part of the public API. + */ +#if !defined(OPENSSL_SYS_UEFI) +# undef BN_LLONG +/* Only one for the following should be defined */ +# define SIXTY_FOUR_BIT_LONG +# undef SIXTY_FOUR_BIT +# undef THIRTY_TWO_BIT +#endif + +#define RC4_INT unsigned int + +#ifdef __cplusplus +} +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslv.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslv.h new file mode 100644 index 00000000..17d271f5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/opensslv.h @@ -0,0 +1,101 @@ +/* + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1010107fL +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1g 21 Apr 2020" + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major version number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.1" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ossl_typ.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ossl_typ.h new file mode 100644 index 00000000..e0edfaaf --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ossl_typ.h @@ -0,0 +1,197 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_sctx_st ASN1_SCTX; + +# ifdef _WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +struct dane_st; +typedef struct bio_st BIO; +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_md_st EVP_MD; +typedef struct evp_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; + +typedef struct hmac_ctx_st HMAC_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_pss_params_st RSA_PSS_PARAMS; + +typedef struct ec_key_st EC_KEY; +typedef struct ec_key_method_st EC_KEY_METHOD; + +typedef struct rand_meth_st RAND_METHOD; +typedef struct rand_drbg_st RAND_DRBG; + +typedef struct ssl_dane_st SSL_DANE; +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct x509_object_st X509_OBJECT; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; + +typedef struct x509_sig_info_st X509_SIG_INFO; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct comp_ctx_st COMP_CTX; +typedef struct comp_method_st COMP_METHOD; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +typedef struct sct_st SCT; +typedef struct sct_ctx_st SCT_CTX; +typedef struct ctlog_st CTLOG; +typedef struct ctlog_store_st CTLOG_STORE; +typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; + +typedef struct ossl_store_info_st OSSL_STORE_INFO; +typedef struct ossl_store_search_st OSSL_STORE_SEARCH; + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ + defined(INTMAX_MAX) && defined(UINTMAX_MAX) +typedef intmax_t ossl_intmax_t; +typedef uintmax_t ossl_uintmax_t; +#else +/* + * Not long long, because the C-library can only be expected to provide + * strtoll(), strtoull() at the same time as intmax_t and strtoimax(), + * strtoumax(). Since we use these for parsing arguments, we need the + * conversion functions, not just the sizes. + */ +typedef long ossl_intmax_t; +typedef unsigned long ossl_uintmax_t; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem.h new file mode 100644 index 00000000..2ef5b5d0 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem.h @@ -0,0 +1,378 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_STDIO + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_STDIO) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_fp_const(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +# define PEM_FLAG_SECURE 0x1 +# define PEM_FLAG_EAY_COMPATIBLE 0x2 +# define PEM_FLAG_ONLY_B64 0x4 +int PEM_read_bio_ex(BIO *bp, char **name, char **header, + unsigned char **data, long *len, unsigned int flags); +int PEM_bytes_read_bio_secmem(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); + +#ifndef OPENSSL_NO_STDIO +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +#endif + +int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +/* The default pem_password_cb that's used internally */ +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +DECLARE_PEM_write_const(DHxparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); +# endif +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +# ifndef OPENSSL_NO_DSA +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif +# endif + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem2.h new file mode 100644 index 00000000..038fe790 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pem2.h @@ -0,0 +1,13 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEM2_H +# define HEADER_PEM2_H +# include +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pemerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pemerr.h new file mode 100644 index 00000000..0c45918f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pemerr.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PEMERR_H +# define HEADER_PEMERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PEM_strings(void); + +/* + * PEM function codes. + */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_I2B 146 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_GET_HEADER_AND_DATA 143 +# define PEM_F_GET_NAME 144 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_DHPARAMS 141 +# define PEM_F_PEM_READ_BIO_EX 145 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_DHPARAMS 142 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* + * PEM reason codes. + */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_HEADER_TOO_LONG 128 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_MISSING_DEK_IV 129 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNEXPECTED_DEK_IV 130 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12.h new file mode 100644 index 00000000..3f43dad6 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12.h @@ -0,0 +1,223 @@ +/* + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* It's not clear if these are actually needed... */ +# define PKCS12_key_gen PKCS12_key_gen_utf8 +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_utf8 + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA; + +typedef struct PKCS12_st PKCS12; + +typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; + +DEFINE_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +#if OPENSSL_API_COMPAT < 0x10100000L + +# define M_PKCS12_bag_type PKCS12_bag_type +# define M_PKCS12_cert_bag_type PKCS12_cert_bag_type +# define M_PKCS12_crl_bag_type PKCS12_cert_bag_type + +# define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert +# define PKCS12_certbag2scrl PKCS12_SAFEBAG_get1_crl +# define PKCS12_bag_type PKCS12_SAFEBAG_get_nid +# define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid +# define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert +# define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl +# define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf +# define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt + +#endif + +DEPRECATEDIN_1_1_0(ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)) + +ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid); +int PKCS12_mac_present(const PKCS12 *p12); +void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, + const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, + const ASN1_INTEGER **piter, + const PKCS12 *p12); + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, + int attr_nid); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); + +X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); +const STACK_OF(PKCS12_SAFEBAG) * +PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); +const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); +const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, + int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +const STACK_OF(X509_ATTRIBUTE) * +PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(const unsigned char *uni, int unilen); +unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, const char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, const char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +# endif +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +# ifndef OPENSSL_NO_STDIO +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +# endif +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12err.h new file mode 100644 index 00000000..eff5eb26 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs12err.h @@ -0,0 +1,81 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS12ERR_H +# define HEADER_PKCS12ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS12_strings(void); + +/* + * PKCS12 function codes. + */ +# define PKCS12_F_OPENSSL_ASC2UNI 121 +# define PKCS12_F_OPENSSL_UNI2ASC 124 +# define PKCS12_F_OPENSSL_UNI2UTF8 127 +# define PKCS12_F_OPENSSL_UTF82UNI 129 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_KEY_GEN_UTF8 116 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF 112 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 113 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT 133 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ENCRYPT 125 +# define PKCS12_F_PKCS8_SET0_PBE 132 + +/* + * PKCS12 reason codes. + */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7.h new file mode 100644 index 00000000..9b66e002 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7.h @@ -0,0 +1,319 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DEFINE_STACK_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DEFINE_STACK_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DEFINE_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 +# define PKCS7_NO_DUAL_CONTENT 0x10000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +/* CRLF ASCII canonicalisation */ +# define SMIME_ASCIICRLF 0x80000 + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_STDIO +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7err.h new file mode 100644 index 00000000..02e0299a --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/pkcs7err.h @@ -0,0 +1,103 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_PKCS7ERR_H +# define HEADER_PKCS7ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_PKCS7_strings(void); + +/* + * PKCS7 function codes. + */ +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 + +/* + * PKCS7 reason codes. + */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand.h new file mode 100644 index 00000000..38a2a271 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand.h @@ -0,0 +1,77 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct rand_meth_st { + int (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + int (*add) (const void *buf, int num, double randomness); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif + +RAND_METHOD *RAND_OpenSSL(void); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define RAND_cleanup() while(0) continue +# endif +int RAND_bytes(unsigned char *buf, int num); +int RAND_priv_bytes(unsigned char *buf, int num); +DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num)) + +void RAND_seed(const void *buf, int num); +void RAND_keep_random_devices_open(int keep); + +# if defined(__ANDROID__) && defined(__NDK_FPABI__) +__NDK_FPABI__ /* __attribute__((pcs("aapcs"))) on ARM */ +# endif +void RAND_add(const void *buf, int num, double randomness); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); + +# ifndef OPENSSL_NO_EGD +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +# endif + +int RAND_poll(void); + +# if defined(_WIN32) && (defined(BASETYPES) || defined(_WINDEF_H)) +/* application has to include in order to use these */ +DEPRECATEDIN_1_1_0(void RAND_screen(void)) +DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM)) +# endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand_drbg.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand_drbg.h new file mode 100644 index 00000000..45b731b7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rand_drbg.h @@ -0,0 +1,130 @@ +/* + * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DRBG_RAND_H +# define HEADER_DRBG_RAND_H + +# include +# include +# include + +/* + * RAND_DRBG flags + * + * Note: if new flags are added, the constant `rand_drbg_used_flags` + * in drbg_lib.c needs to be updated accordingly. + */ + +/* In CTR mode, disable derivation function ctr_df */ +# define RAND_DRBG_FLAG_CTR_NO_DF 0x1 + + +# if OPENSSL_API_COMPAT < 0x10200000L +/* This #define was replaced by an internal constant and should not be used. */ +# define RAND_DRBG_USED_FLAGS (RAND_DRBG_FLAG_CTR_NO_DF) +# endif + +/* + * Default security strength (in the sense of [NIST SP 800-90Ar1]) + * + * NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that + * of the cipher by collecting less entropy. The current DRBG implementation + * does not take RAND_DRBG_STRENGTH into account and sets the strength of the + * DRBG to that of the cipher. + * + * RAND_DRBG_STRENGTH is currently only used for the legacy RAND + * implementation. + * + * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and + * NID_aes_256_ctr + */ +# define RAND_DRBG_STRENGTH 256 +/* Default drbg type */ +# define RAND_DRBG_TYPE NID_aes_256_ctr +/* Default drbg flags */ +# define RAND_DRBG_FLAGS 0 + + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * Object lifetime functions. + */ +RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent); +RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent); +int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags); +int RAND_DRBG_set_defaults(int type, unsigned int flags); +int RAND_DRBG_instantiate(RAND_DRBG *drbg, + const unsigned char *pers, size_t perslen); +int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); +void RAND_DRBG_free(RAND_DRBG *drbg); + +/* + * Object "use" functions. + */ +int RAND_DRBG_reseed(RAND_DRBG *drbg, + const unsigned char *adin, size_t adinlen, + int prediction_resistance); +int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); +int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen); + +int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval); +int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval); + +int RAND_DRBG_set_reseed_defaults( + unsigned int master_reseed_interval, + unsigned int slave_reseed_interval, + time_t master_reseed_time_interval, + time_t slave_reseed_time_interval + ); + +RAND_DRBG *RAND_DRBG_get0_master(void); +RAND_DRBG *RAND_DRBG_get0_public(void); +RAND_DRBG *RAND_DRBG_get0_private(void); + +/* + * EXDATA + */ +# define RAND_DRBG_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DRBG, l, p, newf, dupf, freef) +int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg); +void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); + +/* + * Callback function typedefs + */ +typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *drbg, + unsigned char **pout, + int entropy, size_t min_len, + size_t max_len, + int prediction_resistance); +typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx, + unsigned char *out, size_t outlen); +typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *drbg, unsigned char **pout, + int entropy, size_t min_len, + size_t max_len); +typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + +int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, + RAND_DRBG_get_entropy_fn get_entropy, + RAND_DRBG_cleanup_entropy_fn cleanup_entropy, + RAND_DRBG_get_nonce_fn get_nonce, + RAND_DRBG_cleanup_nonce_fn cleanup_nonce); + + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/randerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/randerr.h new file mode 100644 index 00000000..79d57905 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/randerr.h @@ -0,0 +1,94 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RANDERR_H +# define HEADER_RANDERR_H + +# include + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RAND_strings(void); + +/* + * RAND function codes. + */ +# define RAND_F_DATA_COLLECT_METHOD 127 +# define RAND_F_DRBG_BYTES 101 +# define RAND_F_DRBG_GET_ENTROPY 105 +# define RAND_F_DRBG_SETUP 117 +# define RAND_F_GET_ENTROPY 106 +# define RAND_F_RAND_BYTES 100 +# define RAND_F_RAND_DRBG_ENABLE_LOCKING 119 +# define RAND_F_RAND_DRBG_GENERATE 107 +# define RAND_F_RAND_DRBG_GET_ENTROPY 120 +# define RAND_F_RAND_DRBG_GET_NONCE 123 +# define RAND_F_RAND_DRBG_INSTANTIATE 108 +# define RAND_F_RAND_DRBG_NEW 109 +# define RAND_F_RAND_DRBG_RESEED 110 +# define RAND_F_RAND_DRBG_RESTART 102 +# define RAND_F_RAND_DRBG_SET 104 +# define RAND_F_RAND_DRBG_SET_DEFAULTS 121 +# define RAND_F_RAND_DRBG_UNINSTANTIATE 118 +# define RAND_F_RAND_LOAD_FILE 111 +# define RAND_F_RAND_POOL_ACQUIRE_ENTROPY 122 +# define RAND_F_RAND_POOL_ADD 103 +# define RAND_F_RAND_POOL_ADD_BEGIN 113 +# define RAND_F_RAND_POOL_ADD_END 114 +# define RAND_F_RAND_POOL_ATTACH 124 +# define RAND_F_RAND_POOL_BYTES_NEEDED 115 +# define RAND_F_RAND_POOL_GROW 125 +# define RAND_F_RAND_POOL_NEW 116 +# define RAND_F_RAND_PSEUDO_BYTES 126 +# define RAND_F_RAND_WRITE_FILE 112 + +/* + * RAND reason codes. + */ +# define RAND_R_ADDITIONAL_INPUT_TOO_LONG 102 +# define RAND_R_ALREADY_INSTANTIATED 103 +# define RAND_R_ARGUMENT_OUT_OF_RANGE 105 +# define RAND_R_CANNOT_OPEN_FILE 121 +# define RAND_R_DRBG_ALREADY_INITIALIZED 129 +# define RAND_R_DRBG_NOT_INITIALISED 104 +# define RAND_R_ENTROPY_INPUT_TOO_LONG 106 +# define RAND_R_ENTROPY_OUT_OF_RANGE 124 +# define RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED 127 +# define RAND_R_ERROR_INITIALISING_DRBG 107 +# define RAND_R_ERROR_INSTANTIATING_DRBG 108 +# define RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 109 +# define RAND_R_ERROR_RETRIEVING_ENTROPY 110 +# define RAND_R_ERROR_RETRIEVING_NONCE 111 +# define RAND_R_FAILED_TO_CREATE_LOCK 126 +# define RAND_R_FUNC_NOT_IMPLEMENTED 101 +# define RAND_R_FWRITE_ERROR 123 +# define RAND_R_GENERATE_ERROR 112 +# define RAND_R_INTERNAL_ERROR 113 +# define RAND_R_IN_ERROR_STATE 114 +# define RAND_R_NOT_A_REGULAR_FILE 122 +# define RAND_R_NOT_INSTANTIATED 115 +# define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128 +# define RAND_R_PARENT_LOCKING_NOT_ENABLED 130 +# define RAND_R_PARENT_STRENGTH_TOO_WEAK 131 +# define RAND_R_PERSONALISATION_STRING_TOO_LONG 116 +# define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED 133 +# define RAND_R_PRNG_NOT_SEEDED 100 +# define RAND_R_RANDOM_POOL_OVERFLOW 125 +# define RAND_R_RANDOM_POOL_UNDERFLOW 134 +# define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117 +# define RAND_R_RESEED_ERROR 118 +# define RAND_R_SELFTEST_FAILURE 119 +# define RAND_R_TOO_LITTLE_NONCE_REQUESTED 135 +# define RAND_R_TOO_MUCH_NONCE_REQUESTED 136 +# define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 +# define RAND_R_UNSUPPORTED_DRBG_TYPE 120 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc2.h new file mode 100644 index 00000000..585f9e4c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc2.h @@ -0,0 +1,51 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include + +# ifndef OPENSSL_NO_RC2 +# ifdef __cplusplus +extern "C" { +# endif + +typedef unsigned int RC2_INT; + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc4.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc4.h new file mode 100644 index 00000000..86803b37 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc4.h @@ -0,0 +1,36 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include + +# ifndef OPENSSL_NO_RC4 +# include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc5.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc5.h new file mode 100644 index 00000000..793f88e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rc5.h @@ -0,0 +1,63 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RC5_H +# define HEADER_RC5_H + +# include + +# ifndef OPENSSL_NO_RC5 +# ifdef __cplusplus +extern "C" { +# endif + +# define RC5_ENCRYPT 1 +# define RC5_DECRYPT 0 + +# define RC5_32_INT unsigned int + +# define RC5_32_BLOCK 8 +# define RC5_32_KEY_LENGTH 16/* This is a default, max is 255 */ + +/* + * This are the only values supported. Tweak the code if you want more The + * most supported modes will be RC5-32/12/16 RC5-32/16/8 + */ +# define RC5_8_ROUNDS 8 +# define RC5_12_ROUNDS 12 +# define RC5_16_ROUNDS 16 + +typedef struct rc5_key_st { + /* Number of rounds */ + int rounds; + RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)]; +} RC5_32_KEY; + +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds); +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC5_32_KEY *key, int enc); +void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *ks, unsigned char *iv, + int enc); +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ripemd.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ripemd.h new file mode 100644 index 00000000..c42026aa --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ripemd.h @@ -0,0 +1,47 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include + +#ifndef OPENSSL_NO_RMD160 +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define RIPEMD160_LONG unsigned int + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); + +# ifdef __cplusplus +} +# endif +# endif + + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsa.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsa.h new file mode 100644 index 00000000..5e76365c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsa.h @@ -0,0 +1,513 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include + +# ifndef OPENSSL_NO_RSA +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# ifdef __cplusplus +extern "C" { +# endif + +/* The types RSA and RSA_METHOD are defined in ossl_typ.h */ + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +/* based on RFC 8017 appendix A.1.2 */ +# define RSA_ASN1_VERSION_DEFAULT 0 +# define RSA_ASN1_VERSION_MULTI 1 + +# define RSA_DEFAULT_PRIME_NUM 2 + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +# if OPENSSL_API_COMPAT < 0x10100000L +/* + * Does nothing. Previously this switched off constant time behaviour. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0000 +# endif +# if OPENSSL_API_COMPAT < 0x00908000L +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) +/* Salt length matches digest */ +# define RSA_PSS_SALTLEN_DIGEST -1 +/* Verify only: auto detect salt length */ +# define RSA_PSS_SALTLEN_AUTO -2 +/* Set salt length to maximum possible */ +# define RSA_PSS_SALTLEN_MAX -3 +/* Old compatible max salt length for sign only */ +# define RSA_PSS_SALTLEN_MAX_SIGN -2 + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes, NULL) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md)) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)(pmd)) + +# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)(l)) + +# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)(l)) + +# define EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, \ + EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_MD, \ + 0, (void *)(md)) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES (EVP_PKEY_ALG_CTRL + 13) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_bits(const RSA *rsa); +int RSA_size(const RSA *rsa); +int RSA_security_bits(const RSA *rsa); + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r,BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], + BIGNUM *coeffs[], int pnum); +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +int RSA_get_multi_prime_extra_count(const RSA *r); +int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]); +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp); +int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], + const BIGNUM *coeffs[]); +const BIGNUM *RSA_get0_n(const RSA *d); +const BIGNUM *RSA_get0_e(const RSA *d); +const BIGNUM *RSA_get0_d(const RSA *d); +const BIGNUM *RSA_get0_p(const RSA *d); +const BIGNUM *RSA_get0_q(const RSA *d); +const BIGNUM *RSA_get0_dmp1(const RSA *r); +const BIGNUM *RSA_get0_dmq1(const RSA *r); +const BIGNUM *RSA_get0_iqmp(const RSA *r); +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r); +void RSA_clear_flags(RSA *r, int flags); +int RSA_test_flags(const RSA *r, int flags); +void RSA_set_flags(RSA *r, int flags); +int RSA_get_version(RSA *r); +ENGINE *RSA_get0_engine(const RSA *r); + +/* Deprecated version */ +DEPRECATEDIN_0_9_8(RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), + void *cb_arg)) + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +/* Multi-prime version */ +int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb); + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, + const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb); + +int RSA_check_key(const RSA *); +int RSA_check_key_ex(const RSA *, BN_GENCB *cb); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_null_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* these are the actual RSA functions */ +const RSA_METHOD *RSA_PKCS1_OpenSSL(void); + +int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; + /* Decoded hash algorithm from maskGenAlgorithm */ + X509_ALGOR *maskHash; +}; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; + /* Decoded hash algorithm from maskGenFunc */ + X509_ALGOR *maskHash; +} RSA_OAEP_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_STDIO +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +int RSA_print(BIO *bp, const RSA *r, int offset); + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +#define RSA_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef) +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +RSA_METHOD *RSA_meth_new(const char *name, int flags); +void RSA_meth_free(RSA_METHOD *meth); +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); +const char *RSA_meth_get0_name(const RSA_METHOD *meth); +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name); +int RSA_meth_get_flags(const RSA_METHOD *meth); +int RSA_meth_set_flags(RSA_METHOD *meth, int flags); +void *RSA_meth_get0_app_data(const RSA_METHOD *meth); +int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data); +int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_enc(RSA_METHOD *rsa, + int (*pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_pub_dec(RSA_METHOD *rsa, + int (*pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_enc(RSA_METHOD *rsa, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth)) + (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_meth_set_priv_dec(RSA_METHOD *rsa, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)); +int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); +int RSA_meth_set_mod_exp(RSA_METHOD *rsa, + int (*mod_exp) (BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx)); +int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth)) + (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx)); +int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa)); +int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa); +int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa)); +int (*RSA_meth_get_sign(const RSA_METHOD *meth)) + (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); +int RSA_meth_set_sign(RSA_METHOD *rsa, + int (*sign) (int type, const unsigned char *m, + unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa)); +int (*RSA_meth_get_verify(const RSA_METHOD *meth)) + (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); +int RSA_meth_set_verify(RSA_METHOD *rsa, + int (*verify) (int dtype, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa)); +int (*RSA_meth_get_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_keygen(RSA_METHOD *rsa, + int (*keygen) (RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb)); +int (*RSA_meth_get_multi_prime_keygen(const RSA_METHOD *meth)) + (RSA *rsa, int bits, int primes, BIGNUM *e, BN_GENCB *cb); +int RSA_meth_set_multi_prime_keygen(RSA_METHOD *meth, + int (*keygen) (RSA *rsa, int bits, + int primes, BIGNUM *e, + BN_GENCB *cb)); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsaerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsaerr.h new file mode 100644 index 00000000..59b15e13 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/rsaerr.h @@ -0,0 +1,167 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_RSAERR_H +# define HEADER_RSAERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_RSA_strings(void); + +/* + * RSA function codes. + */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_ENCODE_PKCS1 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_PSS_INIT 165 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 149 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_ALGOR_TO_MD 156 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_CHECK_KEY_EX 160 +# define RSA_F_RSA_CMS_DECRYPT 159 +# define RSA_F_RSA_CMS_VERIFY 158 +# define RSA_F_RSA_ITEM_VERIFY 148 +# define RSA_F_RSA_METH_DUP 161 +# define RSA_F_RSA_METH_NEW 162 +# define RSA_F_RSA_METH_SET1_NAME 163 +# define RSA_F_RSA_MGF1_TO_MD 157 +# define RSA_F_RSA_MULTIP_INFO_NEW 166 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_OSSL_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_OSSL_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_OSSL_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 154 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 152 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 153 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PARAM_DECODE 164 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIV_DECODE 150 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PSS_GET_PARAM 151 +# define RSA_F_RSA_PSS_TO_CTX 155 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 126 +# define RSA_F_SETUP_TBUF 167 + +/* + * RSA reason codes. + */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_DOES_NOT_MATCH 158 +# define RSA_R_DIGEST_NOT_ALLOWED 145 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST 157 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_LABEL 160 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_MULTI_PRIME_KEY 167 +# define RSA_R_INVALID_OAEP_PARAMETERS 161 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_PRIME_NUM_INVALID 165 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MISSING_PRIVATE_KEY 179 +# define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 +# define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 +# define RSA_R_MP_R_NOT_PRIME 170 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_PSS_SALTLEN_TOO_SMALL 164 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_DIGEST 166 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 162 +# define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/safestack.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/safestack.h new file mode 100644 index 00000000..38b55789 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/safestack.h @@ -0,0 +1,207 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define STACK_OF(type) struct stack_st_##type + +# define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ + { \ + return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ + { \ + return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ + { \ + return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ + { \ + OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ + { \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ + sk_##t1##_copyfunc copyfunc, \ + sk_##t1##_freefunc freefunc) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \ + (OPENSSL_sk_copyfunc)copyfunc, \ + (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ + { \ + return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \ + } + +# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2) +# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) +# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \ + SKM_DEFINE_STACK_OF(t1, const t2, t2) +# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; +typedef const char *OPENSSL_CSTRING; + +/*- + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char) +DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * If called without higher optimization (min. -xO3) the Oracle Developer + * Studio compiler generates code for the defined (static inline) functions + * above. + * This would later lead to the linker complaining about missing symbols when + * this header file is included but the resulting object is not linked against + * the Crypto library (openssl#6912). + */ +# ifdef __SUNPRO_C +# pragma weak OPENSSL_sk_num +# pragma weak OPENSSL_sk_value +# pragma weak OPENSSL_sk_new +# pragma weak OPENSSL_sk_new_null +# pragma weak OPENSSL_sk_new_reserve +# pragma weak OPENSSL_sk_reserve +# pragma weak OPENSSL_sk_free +# pragma weak OPENSSL_sk_zero +# pragma weak OPENSSL_sk_delete +# pragma weak OPENSSL_sk_delete_ptr +# pragma weak OPENSSL_sk_push +# pragma weak OPENSSL_sk_unshift +# pragma weak OPENSSL_sk_pop +# pragma weak OPENSSL_sk_shift +# pragma weak OPENSSL_sk_pop_free +# pragma weak OPENSSL_sk_insert +# pragma weak OPENSSL_sk_set +# pragma weak OPENSSL_sk_find +# pragma weak OPENSSL_sk_find_ex +# pragma weak OPENSSL_sk_sort +# pragma weak OPENSSL_sk_is_sorted +# pragma weak OPENSSL_sk_dup +# pragma weak OPENSSL_sk_deep_copy +# pragma weak OPENSSL_sk_set_cmp_func +# endif /* __SUNPRO_C */ + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/seed.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/seed.h new file mode 100644 index 00000000..de10b085 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/seed.h @@ -0,0 +1,96 @@ +/* + * Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include + +# ifndef OPENSSL_NO_SEED +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# include + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/sha.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/sha.h new file mode 100644 index 00000000..6a1eb0de --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/sha.h @@ -0,0 +1,119 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ +# define SHA_LONG unsigned int + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); + +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; + +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/srp.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/srp.h new file mode 100644 index 00000000..aaf13558 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/srp.h @@ -0,0 +1,135 @@ +/* + * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2004, EdelKey Project. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Christophe Renou and Peter Sylvester, + * for the EdelKey project. + */ + +#ifndef HEADER_SRP_H +# define HEADER_SRP_H + +#include + +#ifndef OPENSSL_NO_SRP +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DEFINE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +DEFINE_STACK_OF(SRP_user_pwd) + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + const BIGNUM *default_g; + const BIGNUM *default_N; +} SRP_VBASE; + +/* + * Internal structure storing N and g pair + */ +typedef struct SRP_gN_st { + char *id; + const BIGNUM *g; + const BIGNUM *N; +} SRP_gN; + +DEFINE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +void SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +DEPRECATEDIN_1_1_0(SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)) +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, + const BIGNUM *b, const BIGNUM *N); +BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v); +int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N); +BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g); +BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u); +int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/srtp.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/srtp.h new file mode 100644 index 00000000..0b57c235 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/srtp.h @@ -0,0 +1,50 @@ +/* + * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +/* AEAD SRTP protection profiles from RFC 7714 */ +# define SRTP_AEAD_AES_128_GCM 0x0007 +# define SRTP_AEAD_AES_256_GCM 0x0008 + +# ifndef OPENSSL_NO_SRTP + +__owur int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +__owur int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +__owur STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +__owur SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl.h new file mode 100644 index 00000000..6724ccf2 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl.h @@ -0,0 +1,2438 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include +# include +# include +# include +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif +# include +# include +# include +# include + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* OpenSSL version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* The maximum number of encrypt/decrypt pipelines we can support */ +# define SSL_MAX_PIPELINES 32 + +/* text strings for the ciphers */ + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr"/* this cipher class has been removed */ +# define SSL_TXT_kDHd "kDHd"/* this cipher class has been removed */ +# define SSL_TXT_kDH "kDH"/* this cipher class has been removed */ +# define SSL_TXT_kEDH "kEDH"/* alias for kDHE */ +# define SSL_TXT_kDHE "kDHE" +# define SSL_TXT_kECDHr "kECDHr"/* this cipher class has been removed */ +# define SSL_TXT_kECDHe "kECDHe"/* this cipher class has been removed */ +# define SSL_TXT_kECDH "kECDH"/* this cipher class has been removed */ +# define SSL_TXT_kEECDH "kEECDH"/* alias for kECDHE */ +# define SSL_TXT_kECDHE "kECDHE" +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kRSAPSK "kRSAPSK" +# define SSL_TXT_kECDHEPSK "kECDHEPSK" +# define SSL_TXT_kDHEPSK "kDHEPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDH "aECDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST12 "aGOST12" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_DHE "DHE"/* same as "kDHE:-ADH" */ +# define SSL_TXT_EDH "EDH"/* alias for DHE */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* alias for ECDHE" */ +# define SSL_TXT_ECDHE "ECDHE"/* same as "kECDHE:-AECDH" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_AES_CCM "AESCCM" +# define SSL_TXT_AES_CCM_8 "AESCCM8" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" +# define SSL_TXT_CHACHA20 "CHACHA20" +# define SSL_TXT_GOST "GOST89" +# define SSL_TXT_ARIA "ARIA" +# define SSL_TXT_ARIA_GCM "ARIAGCM" +# define SSL_TXT_ARIA128 "ARIA128" +# define SSL_TXT_ARIA256 "ARIA256" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_GOST12 "GOST12" +# define SSL_TXT_GOST89MAC12 "GOST89MAC12" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + * This applies to ciphersuites for TLSv1.2 and below. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL" +/* This is the default set of TLSv1.3 ciphersuites */ +# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_CHACHA20_POLY1305_SHA256:" \ + "TLS_AES_128_GCM_SHA256" +# else +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_AES_128_GCM_SHA256" +#endif +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; +typedef struct ssl_comp_st SSL_COMP; + +STACK_OF(SSL_CIPHER); +STACK_OF(SSL_COMP); + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg); + +/* Extension context codes */ +/* This extension is only allowed in TLS */ +#define SSL_EXT_TLS_ONLY 0x0001 +/* This extension is only allowed in DTLS */ +#define SSL_EXT_DTLS_ONLY 0x0002 +/* Some extensions may be allowed in DTLS but we don't implement them for it */ +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +/* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ +#define SSL_EXT_SSL3_ALLOWED 0x0008 +/* Extension is only defined for TLS1.2 and below */ +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +/* Extension is only defined for TLS1.3 and above */ +#define SSL_EXT_TLS1_3_ONLY 0x0020 +/* Ignore this extension during parsing if we are resuming */ +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 +#define SSL_EXT_CLIENT_HELLO 0x0080 +/* Really means TLS1.2 or below */ +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb)(SSL *s, unsigned int ext_type, + const unsigned char **out, size_t *outlen, + int *al, void *add_arg); + +typedef void (*custom_ext_free_cb)(SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb)(SSL *s, unsigned int ext_type, + const unsigned char *in, size_t inlen, + int *al, void *parse_arg); + + +typedef int (*SSL_custom_ext_add_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, + size_t *outlen, X509 *x, + size_t chainidx, + int *al, void *add_arg); + +typedef void (*SSL_custom_ext_free_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *out, + void *add_arg); + +typedef int (*SSL_custom_ext_parse_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *in, + size_t inlen, X509 *x, + size_t chainidx, + int *al, void *parse_arg); + +/* Typedef for verification callback */ +typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/* + * Some values are reserved until OpenSSL 1.2.0 because they were previously + * included in SSL_OP_ALL in a 1.1.x release. + * + * Reserved value (until OpenSSL 1.2.0) 0x00000001U + * Reserved value (until OpenSSL 1.2.0) 0x00000002U + */ +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U + +/* Reserved value (until OpenSSL 1.2.0) 0x00000008U */ +# define SSL_OP_TLSEXT_PADDING 0x00000010U +/* Reserved value (until OpenSSL 1.2.0) 0x00000020U */ +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U +/* + * Reserved value (until OpenSSL 1.2.0) 0x00000080U + * Reserved value (until OpenSSL 1.2.0) 0x00000100U + * Reserved value (until OpenSSL 1.2.0) 0x00000200U + */ + +/* In TLSv1.3 allow a non-(ec)dhe based kex_mode */ +# define SSL_OP_ALLOW_NO_DHE_KEX 0x00000400U + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. Added in 0.9.6e + */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800U + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000U +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000U +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000U +# ifndef OPENSSL_NO_DTLS1_METHOD +/* Use Cisco's "speshul" version of DTLS_BAD_VER + * (only with deprecated DTLSv1_client_method()) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# endif + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000U +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000U +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000U +/* Disable encrypt-then-mac */ +# define SSL_OP_NO_ENCRYPT_THEN_MAC 0x00080000U + +/* + * Enable TLSv1.3 Compatibility mode. This is on by default. A future version + * of OpenSSL may have this disabled by default. + */ +# define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0x00100000U + +/* Prioritize Chacha20Poly1305 when client does. + * Modifies SSL_OP_CIPHER_SERVER_PREFERENCE */ +# define SSL_OP_PRIORITIZE_CHACHA 0x00200000U + +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000U +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000U + +/* + * Switches off automatic TLSv1.3 anti-replay protection for early data. This + * is a server-side option only (no effect on the client). + */ +# define SSL_OP_NO_ANTI_REPLAY 0x01000000U + +# define SSL_OP_NO_SSLv3 0x02000000U +# define SSL_OP_NO_TLSv1 0x04000000U +# define SSL_OP_NO_TLSv1_2 0x08000000U +# define SSL_OP_NO_TLSv1_1 0x10000000U +# define SSL_OP_NO_TLSv1_3 0x20000000U + +# define SSL_OP_NO_DTLSv1 0x04000000U +# define SSL_OP_NO_DTLSv1_2 0x08000000U + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +# define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) + +/* Disallow all renegotiation */ +# define SSL_OP_NO_RENEGOTIATION 0x40000000U + +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000U + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. + * This used to be 0x80000BFFU before 1.1.1. + */ +# define SSL_OP_ALL (SSL_OP_CRYPTOPRO_TLSEXT_BUG|\ + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS|\ + SSL_OP_LEGACY_SERVER_CONNECT|\ + SSL_OP_TLSEXT_PADDING|\ + SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + +/* OBSOLETE OPTIONS: retained for compatibility */ + +/* Removed from OpenSSL 1.1.0. Was 0x00000001L */ +/* Related to removed SSLv2. */ +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000002L */ +/* Related to removed SSLv2. */ +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +/* Removed from OpenSSL 0.9.8q and 1.0.0c. Was 0x00000008L */ +/* Dead forever, see CVE-2010-4180 */ +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +/* Removed from OpenSSL 1.0.1h and 1.0.2. Was 0x00000010L */ +/* Refers to ancient SSLREF and SSLv2. */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000020 */ +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +/* Removed from OpenSSL 0.9.7h and 0.9.8b. Was 0x00000040L */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000080 */ +/* Ancient SSLeay version. */ +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000100L */ +# define SSL_OP_TLS_D5_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000200L */ +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00080000L */ +# define SSL_OP_SINGLE_ECDH_USE 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00100000L */ +# define SSL_OP_SINGLE_DH_USE 0x0 +/* Removed from OpenSSL 1.0.1k and 1.0.2. Was 0x00200000L */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x01000000L */ +# define SSL_OP_NO_SSLv2 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x08000000L */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x10000000L */ +# define SSL_OP_PKCS1_CHECK_2 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x20000000L */ +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x40000000L */ +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001U +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004U +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008U +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) Released buffers are freed. + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010U +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020U +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040U +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U +/* + * Support Asynchronous operation + */ +# define SSL_MODE_ASYNC 0x00000100U + +/* + * When using DTLS/SCTP, include the terminating zero in the label + * used for computing the endpoint-pair shared secret. Required for + * interoperability with implementations having this bug like these + * older version of OpenSSL: + * - OpenSSL 1.0.0 series + * - OpenSSL 1.0.1 series + * - OpenSSL 1.0.2 series + * - OpenSSL 1.1.0 series + * - OpenSSL 1.1.1 and 1.1.1a + */ +# define SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certificate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001U + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +# define SSL_CONF_FLAG_REQUIRE_PRIVATE 0x40 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 +# define SSL_CONF_TYPE_NONE 0x4 + +/* Maximum length of the application-controlled segment of a a TLSv1.3 cookie */ +# define SSL_COOKIE_LENGTH 4096 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +unsigned long SSL_CTX_get_options(const SSL_CTX *ctx); +unsigned long SSL_get_options(const SSL *s); +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_clear_options(SSL *s, unsigned long op); +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_set_options(SSL *s, unsigned long op); + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# define SSL_get_extms_support(s) \ + SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL) + +# ifndef OPENSSL_NO_SRP + +/* see tls_srp.c */ +__owur int SSL_SRP_CTX_init(SSL *s); +__owur int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +__owur int SSL_srp_server_param_with_username(SSL *s, int *ad); +__owur int SRP_Calc_A_param(SSL *s); + +# endif + +/* 100k max cert list */ +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv3/TLSv1 it is 32 + * bytes. The callback can alter this length to be less if desired. It is + * also an error for the callback to set the size to zero. + */ +typedef int (*GEN_SESSION_CB) (SSL *ssl, unsigned char *id, + unsigned int *id_len); + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + const unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + const unsigned char *data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +__owur int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + const unsigned + char *cookie, + unsigned int + cookie_len)); + +void SSL_CTX_set_stateless_cookie_generate_cb( + SSL_CTX *ctx, + int (*gen_stateless_cookie_cb) (SSL *ssl, + unsigned char *cookie, + size_t *cookie_len)); +void SSL_CTX_set_stateless_cookie_verify_cb( + SSL_CTX *ctx, + int (*verify_stateless_cookie_cb) (SSL *ssl, + const unsigned char *cookie, + size_t cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG + +typedef int (*SSL_CTX_npn_advertised_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned int *outlen, + void *arg); +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + SSL_CTX_npn_advertised_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_advertised_cb SSL_CTX_set_next_protos_advertised_cb + +typedef int (*SSL_CTX_npn_select_cb_func)(SSL *s, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + SSL_CTX_npn_select_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_select_cb SSL_CTX_set_next_proto_select_cb + +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# define SSL_get0_npn_negotiated SSL_get0_next_proto_negotiated +# endif + +__owur int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +__owur int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +typedef int (*SSL_CTX_alpn_select_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + SSL_CTX_alpn_select_cb_func cb, + void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); +void SSL_set_psk_client_callback(SSL *ssl, SSL_psk_client_cb_func cb); + +typedef unsigned int (*SSL_psk_server_cb_func)(SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb); +void SSL_set_psk_server_callback(SSL *ssl, SSL_psk_server_cb_func cb); + +__owur int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +__owur int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +typedef int (*SSL_psk_find_session_cb_func)(SSL *ssl, + const unsigned char *identity, + size_t identity_len, + SSL_SESSION **sess); +typedef int (*SSL_psk_use_session_cb_func)(SSL *ssl, const EVP_MD *md, + const unsigned char **id, + size_t *idlen, + SSL_SESSION **sess); + +void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb); +void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, + SSL_psk_find_session_cb_func cb); +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb); +void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, + SSL_psk_use_session_cb_func cb); + +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +__owur int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, + unsigned int ext_type); + +__owur int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg); + +__owur int SSL_extension_supported(unsigned int ext_type); + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 +# define SSL_ASYNC_PAUSED 5 +# define SSL_ASYNC_NO_JOBS 6 +# define SSL_CLIENT_HELLO_CB 7 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) +# define SSL_want_async(s) (SSL_want(s) == SSL_ASYNC_PAUSED) +# define SSL_want_async_job(s) (SSL_want(s) == SSL_ASYNC_NO_JOBS) +# define SSL_want_client_hello_cb(s) (SSL_want(s) == SSL_CLIENT_HELLO_CB) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +/* + * A callback for logging out TLS key material. This callback should log out + * |line| followed by a newline. + */ +typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line); + +/* + * SSL_CTX_set_keylog_callback configures a callback to log key material. This + * is intended for debugging use with tools like Wireshark. The cb function + * should log line followed by a newline. + */ +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); + +/* + * SSL_CTX_get_keylog_callback returns the callback configured by + * SSL_CTX_set_keylog_callback. + */ +SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); +uint32_t SSL_get_max_early_data(const SSL *s); +int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data); +uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx); +int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data); +uint32_t SSL_get_recv_max_early_data(const SSL *s); + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These need to be after the above set of includes due to a compiler bug + * in VisualStudio 2015 + */ +DEFINE_STACK_OF_CONST(SSL_CIPHER) +DEFINE_STACK_OF(SSL_COMP) + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)(arg))) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0, \ + (char *)(a))) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0, \ + (char *)(arg))) +DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug)) + +/* TLSv1.3 KeyUpdate message types */ +/* -1 used so that this is an invalid value for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NONE -1 +/* Values as defined for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +/* + * The valid handshake states (one for each type message sent and one for each + * type of message received). There are also two "special" states: + * TLS = TLS or DTLS state + * DTLS = DTLS specific state + * CR/SR = Client Read/Server Read + * CW/SW = Client Write/Server Write + * + * The "special" states are: + * TLS_ST_BEFORE = No handshake has been initiated yet + * TLS_ST_OK = A handshake has been successfully completed + */ +typedef enum { + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED, + TLS_ST_SW_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_CERT_VRFY, + TLS_ST_SW_CERT_VRFY, + TLS_ST_CR_HELLO_REQ, + TLS_ST_SW_KEY_UPDATE, + TLS_ST_CW_KEY_UPDATE, + TLS_ST_SR_KEY_UPDATE, + TLS_ST_CR_KEY_UPDATE, + TLS_ST_EARLY_DATA, + TLS_ST_PENDING_EARLY_DATA_END, + TLS_ST_CW_END_OF_EARLY_DATA, + TLS_ST_SR_END_OF_EARLY_DATA +} OSSL_HANDSHAKE_STATE; + +/* + * Most of the following state values are no longer used and are defined to be + * the closest equivalent value in the current state machine code. Not all + * defines have an equivalent and are set to a dummy value (-1). SSL_ST_CONNECT + * and SSL_ST_ACCEPT are still in use in the definition of SSL_CB_ACCEPT_LOOP, + * SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP and SSL_CB_CONNECT_EXIT. + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 + +# define SSL_ST_MASK 0x0FFF + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_in_connect_init(a) (SSL_in_init(a) && !SSL_is_server(a)) +# define SSL_in_accept_init(a) (SSL_in_init(a) && SSL_is_server(a)) +int SSL_in_init(const SSL *s); +int SSL_in_before(const SSL *s); +int SSL_is_init_finished(const SSL *s); + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 +# define SSL_VERIFY_POST_HANDSHAKE 0x08 + +# if OPENSSL_API_COMPAT < 0x10100000L +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() +# endif + +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION +# define SSL_AD_CERTIFICATE_REQUIRED TLS13_AD_CERTIFICATE_REQUIRED +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_ERROR_WANT_ASYNC 9 +# define SSL_ERROR_WANT_ASYNC_JOB 10 +# define SSL_ERROR_WANT_CLIENT_HELLO_CB 11 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 */ +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB 79 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_GROUPS 90 +# define SSL_CTRL_SET_GROUPS 91 +# define SSL_CTRL_SET_GROUPS_LIST 92 +# define SSL_CTRL_GET_SHARED_GROUP 93 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_PEER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_SET_DH_AUTO 118 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CTRL_GET_EXTMS_SUPPORT 122 +# define SSL_CTRL_SET_MIN_PROTO_VERSION 123 +# define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +# define SSL_CTRL_SET_SPLIT_SEND_FRAGMENT 125 +# define SSL_CTRL_SET_MAX_PIPELINES 126 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE 127 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB 128 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129 +# define SSL_CTRL_GET_MIN_PROTO_VERSION 130 +# define SSL_CTRL_GET_MAX_PROTO_VERSION 131 +# define SSL_CTRL_GET_SIGNATURE_NID 132 +# define SSL_CTRL_GET_TMP_KEY 133 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)(arg)) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_set1_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_add0_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_add1_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_get0_chain_certs(s,px509) \ + SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(s) \ + SSL_set0_chain(s,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_set_current_cert(s,op) \ + SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_get1_groups(s, glist) \ + SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_CTX_set1_groups(ctx, glist, glistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_CTX_set1_groups_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s)) +# define SSL_set1_groups(s, glist, glistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_set1_groups_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str)) +# define SSL_get_shared_group(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str)) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_client_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_client_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str)) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist)) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen, \ + (char *)(clist)) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)(clist)) +# define SSL_get_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_SIGNATURE_NID,0,pn) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_peer_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_TMP_KEY,0,pk) +# define SSL_get_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,plst) +# define SSL_CTX_set_min_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_CTX_set_max_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_CTX_get_min_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_CTX_get_max_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +# define SSL_set_min_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_set_max_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_get_min_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_get_max_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) + +/* Backwards compatibility, original 1.1.0 names */ +# define SSL_CTRL_GET_SERVER_TMP_KEY \ + SSL_CTRL_GET_PEER_TMP_KEY +# define SSL_get_server_tmp_key(s, pk) \ + SSL_get_peer_tmp_key(s, pk) + +/* + * The following symbol names are old and obsolete. They are kept + * for compatibility reasons only and should not be used anymore. + */ +# define SSL_CTRL_GET_CURVES SSL_CTRL_GET_GROUPS +# define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS +# define SSL_CTRL_SET_CURVES_LIST SSL_CTRL_SET_GROUPS_LIST +# define SSL_CTRL_GET_SHARED_CURVE SSL_CTRL_GET_SHARED_GROUP + +# define SSL_get1_curves SSL_get1_groups +# define SSL_CTX_set1_curves SSL_CTX_set1_groups +# define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +# define SSL_set1_curves SSL_set1_groups +# define SSL_set1_curves_list SSL_set1_groups_list +# define SSL_get_shared_curve SSL_get_shared_group + + +# if OPENSSL_API_COMPAT < 0x10100000L +/* Provide some compatibility macros for removed functionality. */ +# define SSL_CTX_need_tmp_RSA(ctx) 0 +# define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +# define SSL_need_tmp_RSA(ssl) 0 +# define SSL_set_tmp_rsa(ssl,rsa) 1 +# define SSL_CTX_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +# define SSL_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +/* + * We "pretend" to call the callback to avoid warnings about unused static + * functions. + */ +# define SSL_CTX_set_tmp_rsa_callback(ctx, cb) while(0) (cb)(NULL, 0, 0) +# define SSL_set_tmp_rsa_callback(ssl, cb) while(0) (cb)(NULL, 0, 0) +# endif +__owur const BIO_METHOD *BIO_f_ssl(void); +__owur BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +__owur BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +__owur BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +__owur int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +__owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +__owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +int SSL_CTX_up_ref(SSL_CTX *ctx); +void SSL_CTX_free(SSL_CTX *); +__owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +__owur long SSL_CTX_get_timeout(const SSL_CTX *ctx); +__owur X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +void SSL_CTX_set1_cert_store(SSL_CTX *, X509_STORE *); +__owur int SSL_want(const SSL *s); +__owur int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +__owur const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +__owur const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s); +__owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +__owur const char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +__owur const char *OPENSSL_cipher_name(const char *rfc_name); +__owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); +__owur uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +__owur const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c); +__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c); + +__owur int SSL_get_fd(const SSL *s); +__owur int SSL_get_rfd(const SSL *s); +__owur int SSL_get_wfd(const SSL *s); +__owur const char *SSL_get_cipher_list(const SSL *s, int n); +__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); +__owur int SSL_get_read_ahead(const SSL *s); +__owur int SSL_pending(const SSL *s); +__owur int SSL_has_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +__owur int SSL_set_fd(SSL *s, int fd); +__owur int SSL_set_rfd(SSL *s, int fd); +__owur int SSL_set_wfd(SSL *s, int fd); +# endif +void SSL_set0_rbio(SSL *s, BIO *rbio); +void SSL_set0_wbio(SSL *s, BIO *wbio); +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +__owur BIO *SSL_get_rbio(const SSL *s); +__owur BIO *SSL_get_wbio(const SSL *s); +__owur int SSL_set_cipher_list(SSL *s, const char *str); +__owur int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +__owur int SSL_set_ciphersuites(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +__owur int SSL_get_verify_mode(const SSL *s); +__owur int SSL_get_verify_depth(const SSL *s); +__owur SSL_verify_cb SSL_get_verify_callback(const SSL *s); +void SSL_set_verify(SSL *s, int mode, SSL_verify_cb callback); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +__owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, + long len); +# endif +__owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +__owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +__owur int SSL_use_certificate(SSL *ssl, X509 *x); +__owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +__owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + + +/* serverinfo file format versions */ +# define SSL_SERVERINFOV1 1 +# define SSL_SERVERINFOV2 2 + +/* Set serverinfo data for the current active cert. */ +__owur int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, + const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +#endif + +__owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +__owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +#endif +__owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +__owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +/* PEM type */ +__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file); +__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_load_error_strings() \ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \ + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# endif + +__owur const char *SSL_state_string(const SSL *s); +__owur const char *SSL_rstate_string(const SSL *s); +__owur const char *SSL_state_string_long(const SSL *s); +__owur const char *SSL_rstate_string_long(const SSL *s); +__owur long SSL_SESSION_get_time(const SSL_SESSION *s); +__owur long SSL_SESSION_set_time(SSL_SESSION *s, long t); +__owur long SSL_SESSION_get_timeout(const SSL_SESSION *s); +__owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +__owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); +__owur int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version); + +__owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s); +__owur int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname); +void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, + const unsigned char **alpn, + size_t *len); +__owur int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, + const unsigned char *alpn, + size_t len); +__owur const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s); +__owur int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher); +__owur int SSL_SESSION_has_ticket(const SSL_SESSION *s); +__owur unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s); +void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick, + size_t *len); +__owur uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s); +__owur int SSL_SESSION_set_max_early_data(SSL_SESSION *s, + uint32_t max_early_data); +__owur int SSL_copy_session_id(SSL *to, const SSL *from); +__owur X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +__owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); +__owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len); +__owur int SSL_SESSION_is_resumable(const SSL_SESSION *s); + +__owur SSL_SESSION *SSL_SESSION_new(void); +__owur SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s, + unsigned int *len); +__owur unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_STDIO +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); +int SSL_SESSION_up_ref(SSL_SESSION *ses); +void SSL_SESSION_free(SSL_SESSION *ses); +__owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +__owur int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); +__owur int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); +__owur int SSL_set_generate_session_id(SSL *s, GEN_SESSION_CB cb); +__owur int SSL_has_matching_session_id(const SSL *s, + const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +__owur X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +__owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +__owur int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +__owur int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +__owur SSL_verify_cb SSL_CTX_get_verify_callback(const SSL_CTX *ctx); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +__owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +# endif +__owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +__owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +__owur int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +__owur int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); +__owur int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); +pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx); +void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx); +void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb); +void SSL_set_default_passwd_cb_userdata(SSL *s, void *u); +pem_password_cb *SSL_get_default_passwd_cb(SSL *s); +void *SSL_get_default_passwd_cb_userdata(SSL *s); + +__owur int SSL_CTX_check_private_key(const SSL_CTX *ctx); +__owur int SSL_check_private_key(const SSL *ctx); + +__owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_up_ref(SSL *s); +int SSL_is_dtls(const SSL *s); +__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +__owur int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); +__owur int SSL_set_purpose(SSL *ssl, int purpose); +__owur int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); +__owur int SSL_set_trust(SSL *ssl, int trust); + +__owur int SSL_set1_host(SSL *s, const char *hostname); +__owur int SSL_add1_host(SSL *s, const char *hostname); +__owur const char *SSL_get0_peername(SSL *s); +void SSL_set_hostflags(SSL *s, unsigned int flags); + +__owur int SSL_CTX_dane_enable(SSL_CTX *ctx); +__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, + uint8_t mtype, uint8_t ord); +__owur int SSL_dane_enable(SSL *s, const char *basedomain); +__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, + uint8_t mtype, unsigned const char *data, size_t dlen); +__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki); +__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, + uint8_t *mtype, unsigned const char **data, + size_t *dlen); +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +SSL_DANE *SSL_get0_dane(SSL *ssl); +/* + * DANE flags + */ +unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags); +unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags); + +__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +__owur X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +__owur X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +__owur BIGNUM *SSL_get_srp_g(SSL *s); +__owur BIGNUM *SSL_get_srp_N(SSL *s); + +__owur char *SSL_get_srp_username(SSL *s); +__owur char *SSL_get_srp_userinfo(SSL *s); +# endif + +/* + * ClientHello callback and helpers. + */ + +# define SSL_CLIENT_HELLO_SUCCESS 1 +# define SSL_CLIENT_HELLO_ERROR 0 +# define SSL_CLIENT_HELLO_RETRY (-1) + +typedef int (*SSL_client_hello_cb_fn) (SSL *s, int *al, void *arg); +void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb, + void *arg); +int SSL_client_hello_isv2(SSL *s); +unsigned int SSL_client_hello_get0_legacy_version(SSL *s); +size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_compression_methods(SSL *s, + const unsigned char **out); +int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get0_ext(SSL *s, unsigned int type, + const unsigned char **out, size_t *outlen); + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +# ifdef OSSL_ASYNC_FD +/* + * Windows application developer has to include windows.h to use these. + */ +__owur int SSL_waiting_for_async(SSL *s); +__owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); +__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +# endif +__owur int SSL_accept(SSL *ssl); +__owur int SSL_stateless(SSL *s); +__owur int SSL_connect(SSL *ssl); +__owur int SSL_read(SSL *ssl, void *buf, int num); +__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); + +# define SSL_READ_EARLY_DATA_ERROR 0 +# define SSL_READ_EARLY_DATA_SUCCESS 1 +# define SSL_READ_EARLY_DATA_FINISH 2 + +__owur int SSL_read_early_data(SSL *s, void *buf, size_t num, + size_t *readbytes); +__owur int SSL_peek(SSL *ssl, void *buf, int num); +__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); +__owur int SSL_write(SSL *ssl, const void *buf, int num); +__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); +__owur int SSL_write_early_data(SSL *s, const void *buf, size_t num, + size_t *written); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +# define SSL_EARLY_DATA_NOT_SENT 0 +# define SSL_EARLY_DATA_REJECTED 1 +# define SSL_EARLY_DATA_ACCEPTED 2 + +__owur int SSL_get_early_data_status(const SSL *s); + +__owur int SSL_get_error(const SSL *s, int ret_code); +__owur const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL3_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_client_method(void)) +# endif + +#define SSLv23_method TLS_method +#define SSLv23_server_method TLS_server_method +#define SSLv23_client_method TLS_client_method + +/* Negotiate highest available SSL/TLS version */ +__owur const SSL_METHOD *TLS_method(void); +__owur const SSL_METHOD *TLS_server_method(void); +__owur const SSL_METHOD *TLS_client_method(void); + +# ifndef OPENSSL_NO_TLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_2_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_2_METHOD +/* DTLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) +# endif + +__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +__owur size_t DTLS_get_data_mtu(const SSL *s); + +__owur STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); +__owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s); + +__owur int SSL_do_handshake(SSL *s); +int SSL_key_update(SSL *s, int updatetype); +int SSL_get_key_update_type(const SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +__owur int SSL_renegotiate_pending(const SSL *s); +int SSL_shutdown(SSL *s); +__owur int SSL_verify_client_post_handshake(SSL *s); +void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val); +void SSL_set_post_handshake_auth(SSL *s, int val); + +__owur const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx); +__owur const SSL_METHOD *SSL_get_ssl_method(const SSL *s); +__owur int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +__owur const char *SSL_alert_type_string_long(int value); +__owur const char *SSL_alert_type_string(int value); +__owur const char *SSL_alert_desc_string_long(int value); +__owur const char *SSL_alert_desc_string(int value); + +void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s); +__owur const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx); +__owur int SSL_add1_to_CA_list(SSL *ssl, const X509 *x); +__owur int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x); +__owur const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +__owur STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +__owur int SSL_add_client_CA(SSL *ssl, X509 *x); +__owur int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +__owur long SSL_get_default_timeout(const SSL *s); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_library_init() OPENSSL_init_ssl(0, NULL) +# endif + +__owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk); + +__owur SSL *SSL_dup(SSL *ssl); + +__owur X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ +struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +__owur X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +__owur EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +__owur int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +__owur int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +__owur int SSL_get_shutdown(const SSL *ssl); +__owur int SSL_version(const SSL *ssl); +__owur int SSL_client_version(const SSL *s); +__owur int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); +__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +__owur SSL_SESSION *SSL_get_session(const SSL *ssl); +__owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +__owur SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +__owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +void SSL_set_verify_result(SSL *ssl, long v); +__owur long SSL_get_verify_result(const SSL *ssl); +__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s); + +__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_SESSION_get_master_key(const SSL_SESSION *sess, + unsigned char *out, size_t outlen); +__owur int SSL_SESSION_set1_master_key(SSL_SESSION *sess, + const unsigned char *in, size_t len); +uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *sess); + +#define SSL_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef) +__owur int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +#define SSL_SESSION_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, l, p, newf, dupf, freef) +__owur int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +#define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) +__owur int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); + +__owur int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_split_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_set_split_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_max_pipelines(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) +# define SSL_set_max_pipelines(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) + +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); +void SSL_set_default_read_buffer_len(SSL *s, size_t len); + +# ifndef OPENSSL_NO_DH +/* NB: the |keylength| is only applicable when is_export is true */ +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif + +__owur const COMP_METHOD *SSL_get_current_compression(const SSL *s); +__owur const COMP_METHOD *SSL_get_current_expansion(const SSL *s); +__owur const char *SSL_COMP_get_name(const COMP_METHOD *comp); +__owur const char *SSL_COMP_get0_name(const SSL_COMP *comp); +__owur int SSL_COMP_get_id(const SSL_COMP *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +__owur STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_COMP_free_compression_methods() while(0) continue +# endif +__owur int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); +int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, + int isv2format, STACK_OF(SSL_CIPHER) **sk, + STACK_OF(SSL_CIPHER) **scsvs); + +/* TLS extensions functions */ +__owur int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +__owur int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +__owur int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn session_secret_cb, + void *arg); + +void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + int + is_forward_secure)); + +void SSL_set_not_resumable_session_callback(SSL *ssl, + int (*cb) (SSL *ssl, + int is_forward_secure)); + +void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); +void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); +int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); + +void SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); +void *SSL_get_record_padding_callback_arg(const SSL *ssl); +int SSL_set_block_padding(SSL *ssl, size_t block_size); + +int SSL_set_num_tickets(SSL *s, size_t num_tickets); +size_t SSL_get_num_tickets(const SSL *s); +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_cache_hit(s) SSL_session_reused(s) +# endif + +__owur int SSL_session_reused(const SSL *s); +__owur int SSL_is_server(const SSL *s); + +__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +__owur unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, + unsigned int flags); +__owur int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +__owur int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +__owur int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +__owur int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +void SSL_add_ssl_module(void); +int SSL_config(SSL *s, const char *name); +int SSL_CTX_config(SSL_CTX *ctx, const char *name); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +# endif + +# ifndef OPENSSL_NO_SOCK +int DTLSv1_listen(SSL *s, BIO_ADDR *client); +# endif + +# ifndef OPENSSL_NO_CT + +/* + * A callback for verifying that the received SCTs are sufficient. + * Expected to return 1 if they are sufficient, otherwise 0. + * May return a negative integer if an error occurs. + * A connection should be aborted if the SCTs are deemed insufficient. + */ +typedef int (*ssl_ct_validation_cb)(const CT_POLICY_EVAL_CTX *ctx, + const STACK_OF(SCT) *scts, void *arg); + +/* + * Sets a |callback| that is invoked upon receipt of ServerHelloDone to validate + * the received SCTs. + * If the callback returns a non-positive result, the connection is terminated. + * Call this function before beginning a handshake. + * If a NULL |callback| is provided, SCT validation is disabled. + * |arg| is arbitrary userdata that will be passed to the callback whenever it + * is invoked. Ownership of |arg| remains with the caller. + * + * NOTE: A side-effect of setting a CT callback is that an OCSP stapled response + * will be requested. + */ +int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, + void *arg); +int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, + ssl_ct_validation_cb callback, + void *arg); +#define SSL_disable_ct(s) \ + ((void) SSL_set_validation_callback((s), NULL, NULL)) +#define SSL_CTX_disable_ct(ctx) \ + ((void) SSL_CTX_set_validation_callback((ctx), NULL, NULL)) + +/* + * The validation type enumerates the available behaviours of the built-in SSL + * CT validation callback selected via SSL_enable_ct() and SSL_CTX_enable_ct(). + * The underlying callback is a static function in libssl. + */ +enum { + SSL_CT_VALIDATION_PERMISSIVE = 0, + SSL_CT_VALIDATION_STRICT +}; + +/* + * Enable CT by setting up a callback that implements one of the built-in + * validation variants. The SSL_CT_VALIDATION_PERMISSIVE variant always + * continues the handshake, the application can make appropriate decisions at + * handshake completion. The SSL_CT_VALIDATION_STRICT variant requires at + * least one valid SCT, or else handshake termination will be requested. The + * handshake may continue anyway if SSL_VERIFY_NONE is in effect. + */ +int SSL_enable_ct(SSL *s, int validation_mode); +int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode); + +/* + * Report whether a non-NULL callback is enabled. + */ +int SSL_ct_is_enabled(const SSL *s); +int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx); + +/* Gets the SCTs received from a connection */ +const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s); + +/* + * Loads the CT log list from the default location. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx); + +/* + * Loads the CT log list from the specified file path. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path); + +/* + * Sets the CT log list used by all SSL connections created from this SSL_CTX. + * Ownership of the CTLOG_STORE is transferred to the SSL_CTX. + */ +void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs); + +/* + * Gets the CT log list used by all SSL connections created from this SSL_CTX. + * This will be NULL unless one of the following functions has been called: + * - SSL_CTX_set_default_ctlog_list_file + * - SSL_CTX_set_ctlog_list_file + * - SSL_CTX_set_ctlog_store + */ +const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx); + +# endif /* OPENSSL_NO_CT */ + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +# define SSL_SECOP_OTHER_TYPE 0xffff0000 +# define SSL_SECOP_OTHER_NONE 0 +# define SSL_SECOP_OTHER_CIPHER (1 << 16) +# define SSL_SECOP_OTHER_CURVE (2 << 16) +# define SSL_SECOP_OTHER_DH (3 << 16) +# define SSL_SECOP_OTHER_PKEY (4 << 16) +# define SSL_SECOP_OTHER_SIGALG (5 << 16) +# define SSL_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +# define SSL_SECOP_PEER 0x1000 + +/* Values for "op" parameter in security callback */ + +/* Called to filter ciphers */ +/* Ciphers client supports */ +# define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +# define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +# define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +# define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +# define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +# define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE) +/* Temporary DH key */ +# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_PKEY) +/* SSL/TLS version */ +# define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE) +/* Session tickets */ +# define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +# define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +# define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +# define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +# define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +# define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE) +/* EE key in certificate */ +# define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT) +/* CA key in certificate */ +# define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +# define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +# define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER) +/* Peer CA key in certificate */ +# define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +# define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER) + +void SSL_set_security_level(SSL *s, int level); +__owur int SSL_get_security_level(const SSL *s); +void SSL_set_security_callback(SSL *s, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, + const SSL_CTX *ctx, int op, + int bits, int nid, void *other, + void *ex); +void SSL_set0_security_ex_data(SSL *s, void *ex); +__owur void *SSL_get0_security_ex_data(const SSL *s); + +void SSL_CTX_set_security_level(SSL_CTX *ctx, int level); +__owur int SSL_CTX_get_security_level(const SSL_CTX *ctx); +void SSL_CTX_set_security_callback(SSL_CTX *ctx, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s, + const SSL_CTX *ctx, + int op, int bits, + int nid, + void *other, + void *ex); +void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex); +__owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx); + +/* OPENSSL_INIT flag 0x010000 reserved for internal use */ +# define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L +# define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L + +# define OPENSSL_INIT_SSL_DEFAULT \ + (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS) + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + +# ifndef OPENSSL_NO_UNIT_TEST +__owur const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +__owur int SSL_free_buffers(SSL *ssl); +__owur int SSL_alloc_buffers(SSL *ssl); + +/* Status codes passed to the decrypt session ticket callback. Some of these + * are for internal use only and are never passed to the callback. */ +typedef int SSL_TICKET_STATUS; + +/* Support for ticket appdata */ +/* fatal error, malloc failure */ +# define SSL_TICKET_FATAL_ERR_MALLOC 0 +/* fatal error, either from parsing or decrypting the ticket */ +# define SSL_TICKET_FATAL_ERR_OTHER 1 +/* No ticket present */ +# define SSL_TICKET_NONE 2 +/* Empty ticket present */ +# define SSL_TICKET_EMPTY 3 +/* the ticket couldn't be decrypted */ +# define SSL_TICKET_NO_DECRYPT 4 +/* a ticket was successfully decrypted */ +# define SSL_TICKET_SUCCESS 5 +/* same as above but the ticket needs to be renewed */ +# define SSL_TICKET_SUCCESS_RENEW 6 + +/* Return codes for the decrypt session ticket callback */ +typedef int SSL_TICKET_RETURN; + +/* An error occurred */ +#define SSL_TICKET_RETURN_ABORT 0 +/* Do not use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE 1 +/* Do not use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE_RENEW 2 +/* Use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE 3 +/* Use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE_RENEW 4 + +typedef int (*SSL_CTX_generate_session_ticket_fn)(SSL *s, void *arg); +typedef SSL_TICKET_RETURN (*SSL_CTX_decrypt_session_ticket_fn)(SSL *s, SSL_SESSION *ss, + const unsigned char *keyname, + size_t keyname_length, + SSL_TICKET_STATUS status, + void *arg); +int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx, + SSL_CTX_generate_session_ticket_fn gen_cb, + SSL_CTX_decrypt_session_ticket_fn dec_cb, + void *arg); +int SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len); +int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len); + +extern const char SSL_version_str[]; + +typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us); + +void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb); + + +typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg); +void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx, + SSL_allow_early_data_cb_fn cb, + void *arg); +void SSL_set_allow_early_data_cb(SSL *s, + SSL_allow_early_data_cb_fn cb, + void *arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl2.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl2.h new file mode 100644 index 00000000..5321bd27 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl2.h @@ -0,0 +1,24 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL2_VERSION 0x0002 + +# define SSL2_MT_CLIENT_HELLO 1 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl3.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl3.h new file mode 100644 index 00000000..8d01fcc4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ssl3.h @@ -0,0 +1,339 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA SSL3_CK_DHE_DSS_DES_40_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA SSL3_CK_DHE_DSS_DES_64_CBC_SHA +# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA SSL3_CK_DHE_DSS_DES_192_CBC3_SHA +# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA SSL3_CK_DHE_RSA_DES_40_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA SSL3_CK_DHE_RSA_DES_64_CBC_SHA +# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA 0x03000016 +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA SSL3_CK_DHE_RSA_DES_192_CBC3_SHA + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define SSL3_RFC_RSA_NULL_MD5 "TLS_RSA_WITH_NULL_MD5" +# define SSL3_RFC_RSA_NULL_SHA "TLS_RSA_WITH_NULL_SHA" +# define SSL3_RFC_RSA_DES_192_CBC3_SHA "TLS_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_DSS_DES_192_CBC3_SHA "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_DHE_RSA_DES_192_CBC3_SHA "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_ADH_DES_192_CBC_SHA "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA" +# define SSL3_RFC_RSA_IDEA_128_SHA "TLS_RSA_WITH_IDEA_CBC_SHA" +# define SSL3_RFC_RSA_RC4_128_MD5 "TLS_RSA_WITH_RC4_128_MD5" +# define SSL3_RFC_RSA_RC4_128_SHA "TLS_RSA_WITH_RC4_128_SHA" +# define SSL3_RFC_ADH_RC4_128_MD5 "TLS_DH_anon_WITH_RC4_128_MD5" + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" + +/* + * This next block of six "EDH" labels is for backward compatibility with + * older versions of OpenSSL. New code should use the six "DHE" labels above + * instead: + */ +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD 256 + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define DTLS1_RT_HEARTBEAT 24 + +/* Pseudo content types to indicate additional parameters */ +# define TLS1_RT_CRYPTO 0x1000 +# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) +# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) +# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) +# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) + +# define TLS1_RT_CRYPTO_READ 0x0000 +# define TLS1_RT_CRYPTO_WRITE 0x0100 +# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) +# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) +# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) +# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) + +/* Pseudo content types for SSL/TLS header info */ +# define SSL3_RT_HEADER 0x100 +# define SSL3_RT_INNER_CONTENT_TYPE 0x101 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined for *either* SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 10 + +# if defined(TLS_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +/* No longer used as of OpenSSL 1.1.1 */ +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 + +/* Removed from OpenSSL 1.1.0 */ +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0 + +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 + +/* Set if we encrypt then mac instead of usual mac then encrypt */ +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_READ 0x0100 +# define TLS1_FLAGS_ENCRYPT_THEN_MAC TLS1_FLAGS_ENCRYPT_THEN_MAC_READ + +/* Set if extended master secret extension received from peer */ +# define TLS1_FLAGS_RECEIVED_EXTMS 0x0200 + +# define TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE 0x0400 + +# define TLS1_FLAGS_STATELESS 0x0800 + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_END_OF_EARLY_DATA 5 +# define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_URL 21 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# define SSL3_MT_SUPPLEMENTAL_DATA 23 +# define SSL3_MT_KEY_UPDATE 24 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define SSL3_MT_MESSAGE_HASH 254 +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +/* Dummy message type for handling CCS like a normal handshake message */ +# define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x001 +# define SSL3_CC_WRITE 0x002 +# define SSL3_CC_CLIENT 0x010 +# define SSL3_CC_SERVER 0x020 +# define SSL3_CC_EARLY 0x040 +# define SSL3_CC_HANDSHAKE 0x080 +# define SSL3_CC_APPLICATION 0x100 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/sslerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/sslerr.h new file mode 100644 index 00000000..82983d3c --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/sslerr.h @@ -0,0 +1,773 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SSLERR_H +# define HEADER_SSLERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_SSL_strings(void); + +/* + * SSL function codes. + */ +# define SSL_F_ADD_CLIENT_KEY_SHARE_EXT 438 +# define SSL_F_ADD_KEY_SHARE 512 +# define SSL_F_BYTES_TO_CIPHER_LIST 519 +# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 +# define SSL_F_CIPHERSUITE_CB 622 +# define SSL_F_CONSTRUCT_CA_NAMES 552 +# define SSL_F_CONSTRUCT_KEY_EXCHANGE_TBS 553 +# define SSL_F_CONSTRUCT_STATEFUL_TICKET 636 +# define SSL_F_CONSTRUCT_STATELESS_TICKET 637 +# define SSL_F_CREATE_SYNTHETIC_MESSAGE_HASH 539 +# define SSL_F_CREATE_TICKET_PREQUEL 638 +# define SSL_F_CT_MOVE_SCTS 345 +# define SSL_F_CT_STRICT 349 +# define SSL_F_CUSTOM_EXT_ADD 554 +# define SSL_F_CUSTOM_EXT_PARSE 555 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DANE_CTX_ENABLE 347 +# define SSL_F_DANE_MTYPE_SET 393 +# define SSL_F_DANE_TLSA_ADD 394 +# define SSL_F_DERIVE_SECRET_KEY_AND_IV 514 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 318 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_HM_FRAGMENT_NEW 623 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 339 +# define SSL_F_DTLS1_RETRANSMIT_MESSAGE 390 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_DTLS1_WRITE_BYTES 545 +# define SSL_F_DTLSV1_LISTEN 350 +# define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC 371 +# define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385 +# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370 +# define SSL_F_DTLS_PROCESS_HELLO_VERIFY 386 +# define SSL_F_DTLS_RECORD_LAYER_NEW 635 +# define SSL_F_DTLS_WAIT_FOR_DRY 592 +# define SSL_F_EARLY_DATA_COUNT_OK 532 +# define SSL_F_FINAL_EARLY_DATA 556 +# define SSL_F_FINAL_EC_PT_FORMATS 485 +# define SSL_F_FINAL_EMS 486 +# define SSL_F_FINAL_KEY_SHARE 503 +# define SSL_F_FINAL_MAXFRAGMENTLEN 557 +# define SSL_F_FINAL_RENEGOTIATE 483 +# define SSL_F_FINAL_SERVER_NAME 558 +# define SSL_F_FINAL_SIG_ALGS 497 +# define SSL_F_GET_CERT_VERIFY_TBS_DATA 588 +# define SSL_F_NSS_KEYLOG_INT 500 +# define SSL_F_OPENSSL_INIT_SSL 342 +# define SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION 436 +# define SSL_F_OSSL_STATEM_CLIENT13_WRITE_TRANSITION 598 +# define SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE 430 +# define SSL_F_OSSL_STATEM_CLIENT_POST_PROCESS_MESSAGE 593 +# define SSL_F_OSSL_STATEM_CLIENT_PROCESS_MESSAGE 594 +# define SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION 417 +# define SSL_F_OSSL_STATEM_CLIENT_WRITE_TRANSITION 599 +# define SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION 437 +# define SSL_F_OSSL_STATEM_SERVER13_WRITE_TRANSITION 600 +# define SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE 431 +# define SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE 601 +# define SSL_F_OSSL_STATEM_SERVER_POST_WORK 602 +# define SSL_F_OSSL_STATEM_SERVER_PRE_WORK 640 +# define SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE 603 +# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION 418 +# define SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION 604 +# define SSL_F_PARSE_CA_NAMES 541 +# define SSL_F_PITEM_NEW 624 +# define SSL_F_PQUEUE_NEW 625 +# define SSL_F_PROCESS_KEY_SHARE_EXT 439 +# define SSL_F_READ_STATE_MACHINE 352 +# define SSL_F_SET_CLIENT_CIPHERSUITE 540 +# define SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET 595 +# define SSL_F_SRP_GENERATE_SERVER_MASTER_SECRET 589 +# define SSL_F_SRP_VERIFY_SERVER_PARAM 596 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 608 +# define SSL_F_SSL3_FINAL_FINISH_MAC 285 +# define SSL_F_SSL3_FINISH_MAC 587 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_INIT_FINISHED_MAC 397 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CERT_CHAIN 316 +# define SSL_F_SSL_ADD_CERT_TO_BUF 319 +# define SSL_F_SSL_ADD_CERT_TO_WPACKET 493 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BUILD_CERT_CHAIN 332 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CACHE_CIPHERLIST 520 +# define SSL_F_SSL_CERT_ADD0_CHAIN_CERT 346 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CERT_SET0_CHAIN 340 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO 606 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CHOOSE_CLIENT_VERSION 607 +# define SSL_F_SSL_CIPHER_DESCRIPTION 626 +# define SSL_F_SSL_CIPHER_LIST_TO_BYTES 425 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT 627 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CONF_CMD 334 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_ENABLE_CT 398 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_ALPN_PROTOS 343 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK 396 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH 551 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_CTX_USE_SERVERINFO 336 +# define SSL_F_SSL_CTX_USE_SERVERINFO_EX 543 +# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 +# define SSL_F_SSL_DANE_DUP 403 +# define SSL_F_SSL_DANE_ENABLE 395 +# define SSL_F_SSL_DERIVE 590 +# define SSL_F_SSL_DO_CONFIG 391 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_DUP_CA_LIST 408 +# define SSL_F_SSL_ENABLE_CT 402 +# define SSL_F_SSL_GENERATE_PKEY_GROUP 559 +# define SSL_F_SSL_GENERATE_SESSION_ID 547 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_HANDSHAKE_HASH 560 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_KEY_UPDATE 515 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_LOG_MASTER_SECRET 498 +# define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499 +# define SSL_F_SSL_MODULE_INIT 392 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_NEXT_PROTO_VALIDATE 565 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PEEK_EX 432 +# define SSL_F_SSL_PEEK_INTERNAL 522 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_READ_EARLY_DATA 529 +# define SSL_F_SSL_READ_EX 434 +# define SSL_F_SSL_READ_INTERNAL 523 +# define SSL_F_SSL_RENEGOTIATE 516 +# define SSL_F_SSL_RENEGOTIATE_ABBREVIATED 546 +# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 +# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID 423 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SET_ALPN_PROTOS 344 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CERT_AND_KEY 621 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK 399 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH 550 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_START_ASYNC_JOB 389 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VALIDATE_CT 400 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE 616 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_SSL_WRITE_EARLY_DATA 526 +# define SSL_F_SSL_WRITE_EARLY_FINISH 527 +# define SSL_F_SSL_WRITE_EX 433 +# define SSL_F_SSL_WRITE_INTERNAL 524 +# define SSL_F_STATE_MACHINE 353 +# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 +# define SSL_F_TLS12_COPY_SIGALGS 533 +# define SSL_F_TLS13_CHANGE_CIPHER_STATE 440 +# define SSL_F_TLS13_ENC 609 +# define SSL_F_TLS13_FINAL_FINISH_MAC 605 +# define SSL_F_TLS13_GENERATE_SECRET 591 +# define SSL_F_TLS13_HKDF_EXPAND 561 +# define SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA 617 +# define SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA 618 +# define SSL_F_TLS13_SETUP_KEY_BLOCK 441 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS 341 +# define SSL_F_TLS1_ENC 401 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_GET_CURVELIST 338 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SAVE_U16 628 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_TLS1_SET_GROUPS 629 +# define SSL_F_TLS1_SET_RAW_SIGALGS 630 +# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 +# define SSL_F_TLS1_SET_SHARED_SIGALGS 631 +# define SSL_F_TLS1_SET_SIGALGS 632 +# define SSL_F_TLS_CHOOSE_SIGALG 513 +# define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK 354 +# define SSL_F_TLS_COLLECT_EXTENSIONS 435 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES 542 +# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST 372 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS 429 +# define SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY 494 +# define SSL_F_TLS_CONSTRUCT_CERT_VERIFY 496 +# define SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC 427 +# define SSL_F_TLS_CONSTRUCT_CKE_DHE 404 +# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405 +# define SSL_F_TLS_CONSTRUCT_CKE_GOST 406 +# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407 +# define SSL_F_TLS_CONSTRUCT_CKE_RSA 409 +# define SSL_F_TLS_CONSTRUCT_CKE_SRP 410 +# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE 484 +# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO 487 +# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE 488 +# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY 489 +# define SSL_F_TLS_CONSTRUCT_CTOS_ALPN 466 +# define SSL_F_TLS_CONSTRUCT_CTOS_CERTIFICATE 355 +# define SSL_F_TLS_CONSTRUCT_CTOS_COOKIE 535 +# define SSL_F_TLS_CONSTRUCT_CTOS_EARLY_DATA 530 +# define SSL_F_TLS_CONSTRUCT_CTOS_EC_PT_FORMATS 467 +# define SSL_F_TLS_CONSTRUCT_CTOS_EMS 468 +# define SSL_F_TLS_CONSTRUCT_CTOS_ETM 469 +# define SSL_F_TLS_CONSTRUCT_CTOS_HELLO 356 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_EXCHANGE 357 +# define SSL_F_TLS_CONSTRUCT_CTOS_KEY_SHARE 470 +# define SSL_F_TLS_CONSTRUCT_CTOS_MAXFRAGMENTLEN 549 +# define SSL_F_TLS_CONSTRUCT_CTOS_NPN 471 +# define SSL_F_TLS_CONSTRUCT_CTOS_PADDING 472 +# define SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH 619 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK 501 +# define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 509 +# define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 473 +# define SSL_F_TLS_CONSTRUCT_CTOS_SCT 474 +# define SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME 475 +# define SSL_F_TLS_CONSTRUCT_CTOS_SESSION_TICKET 476 +# define SSL_F_TLS_CONSTRUCT_CTOS_SIG_ALGS 477 +# define SSL_F_TLS_CONSTRUCT_CTOS_SRP 478 +# define SSL_F_TLS_CONSTRUCT_CTOS_STATUS_REQUEST 479 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS 480 +# define SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS 481 +# define SSL_F_TLS_CONSTRUCT_CTOS_USE_SRTP 482 +# define SSL_F_TLS_CONSTRUCT_CTOS_VERIFY 358 +# define SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS 443 +# define SSL_F_TLS_CONSTRUCT_END_OF_EARLY_DATA 536 +# define SSL_F_TLS_CONSTRUCT_EXTENSIONS 447 +# define SSL_F_TLS_CONSTRUCT_FINISHED 359 +# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST 373 +# define SSL_F_TLS_CONSTRUCT_HELLO_RETRY_REQUEST 510 +# define SSL_F_TLS_CONSTRUCT_KEY_UPDATE 517 +# define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET 428 +# define SSL_F_TLS_CONSTRUCT_NEXT_PROTO 426 +# define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE 490 +# define SSL_F_TLS_CONSTRUCT_SERVER_HELLO 491 +# define SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE 492 +# define SSL_F_TLS_CONSTRUCT_STOC_ALPN 451 +# define SSL_F_TLS_CONSTRUCT_STOC_CERTIFICATE 374 +# define SSL_F_TLS_CONSTRUCT_STOC_COOKIE 613 +# define SSL_F_TLS_CONSTRUCT_STOC_CRYPTOPRO_BUG 452 +# define SSL_F_TLS_CONSTRUCT_STOC_DONE 375 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA 531 +# define SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA_INFO 525 +# define SSL_F_TLS_CONSTRUCT_STOC_EC_PT_FORMATS 453 +# define SSL_F_TLS_CONSTRUCT_STOC_EMS 454 +# define SSL_F_TLS_CONSTRUCT_STOC_ETM 455 +# define SSL_F_TLS_CONSTRUCT_STOC_HELLO 376 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_EXCHANGE 377 +# define SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE 456 +# define SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN 548 +# define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG 457 +# define SSL_F_TLS_CONSTRUCT_STOC_PSK 504 +# define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE 458 +# define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME 459 +# define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET 460 +# define SSL_F_TLS_CONSTRUCT_STOC_STATUS_REQUEST 461 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS 544 +# define SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_VERSIONS 611 +# define SSL_F_TLS_CONSTRUCT_STOC_USE_SRTP 462 +# define SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO 521 +# define SSL_F_TLS_FINISH_HANDSHAKE 597 +# define SSL_F_TLS_GET_MESSAGE_BODY 351 +# define SSL_F_TLS_GET_MESSAGE_HEADER 387 +# define SSL_F_TLS_HANDLE_ALPN 562 +# define SSL_F_TLS_HANDLE_STATUS_REQUEST 563 +# define SSL_F_TLS_PARSE_CERTIFICATE_AUTHORITIES 566 +# define SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT 449 +# define SSL_F_TLS_PARSE_CTOS_ALPN 567 +# define SSL_F_TLS_PARSE_CTOS_COOKIE 614 +# define SSL_F_TLS_PARSE_CTOS_EARLY_DATA 568 +# define SSL_F_TLS_PARSE_CTOS_EC_PT_FORMATS 569 +# define SSL_F_TLS_PARSE_CTOS_EMS 570 +# define SSL_F_TLS_PARSE_CTOS_KEY_SHARE 463 +# define SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN 571 +# define SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH 620 +# define SSL_F_TLS_PARSE_CTOS_PSK 505 +# define SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES 572 +# define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 464 +# define SSL_F_TLS_PARSE_CTOS_SERVER_NAME 573 +# define SSL_F_TLS_PARSE_CTOS_SESSION_TICKET 574 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS 575 +# define SSL_F_TLS_PARSE_CTOS_SIG_ALGS_CERT 615 +# define SSL_F_TLS_PARSE_CTOS_SRP 576 +# define SSL_F_TLS_PARSE_CTOS_STATUS_REQUEST 577 +# define SSL_F_TLS_PARSE_CTOS_SUPPORTED_GROUPS 578 +# define SSL_F_TLS_PARSE_CTOS_USE_SRTP 465 +# define SSL_F_TLS_PARSE_STOC_ALPN 579 +# define SSL_F_TLS_PARSE_STOC_COOKIE 534 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA 538 +# define SSL_F_TLS_PARSE_STOC_EARLY_DATA_INFO 528 +# define SSL_F_TLS_PARSE_STOC_EC_PT_FORMATS 580 +# define SSL_F_TLS_PARSE_STOC_KEY_SHARE 445 +# define SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN 581 +# define SSL_F_TLS_PARSE_STOC_NPN 582 +# define SSL_F_TLS_PARSE_STOC_PSK 502 +# define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 448 +# define SSL_F_TLS_PARSE_STOC_SCT 564 +# define SSL_F_TLS_PARSE_STOC_SERVER_NAME 583 +# define SSL_F_TLS_PARSE_STOC_SESSION_TICKET 584 +# define SSL_F_TLS_PARSE_STOC_STATUS_REQUEST 585 +# define SSL_F_TLS_PARSE_STOC_SUPPORTED_VERSIONS 612 +# define SSL_F_TLS_PARSE_STOC_USE_SRTP 446 +# define SSL_F_TLS_POST_PROCESS_CLIENT_HELLO 378 +# define SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE 384 +# define SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE 360 +# define SSL_F_TLS_PROCESS_AS_HELLO_RETRY_REQUEST 610 +# define SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST 361 +# define SSL_F_TLS_PROCESS_CERT_STATUS 362 +# define SSL_F_TLS_PROCESS_CERT_STATUS_BODY 495 +# define SSL_F_TLS_PROCESS_CERT_VERIFY 379 +# define SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC 363 +# define SSL_F_TLS_PROCESS_CKE_DHE 411 +# define SSL_F_TLS_PROCESS_CKE_ECDHE 412 +# define SSL_F_TLS_PROCESS_CKE_GOST 413 +# define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 414 +# define SSL_F_TLS_PROCESS_CKE_RSA 415 +# define SSL_F_TLS_PROCESS_CKE_SRP 416 +# define SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE 380 +# define SSL_F_TLS_PROCESS_CLIENT_HELLO 381 +# define SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE 382 +# define SSL_F_TLS_PROCESS_ENCRYPTED_EXTENSIONS 444 +# define SSL_F_TLS_PROCESS_END_OF_EARLY_DATA 537 +# define SSL_F_TLS_PROCESS_FINISHED 364 +# define SSL_F_TLS_PROCESS_HELLO_REQ 507 +# define SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST 511 +# define SSL_F_TLS_PROCESS_INITIAL_SERVER_FLIGHT 442 +# define SSL_F_TLS_PROCESS_KEY_EXCHANGE 365 +# define SSL_F_TLS_PROCESS_KEY_UPDATE 518 +# define SSL_F_TLS_PROCESS_NEW_SESSION_TICKET 366 +# define SSL_F_TLS_PROCESS_NEXT_PROTO 383 +# define SSL_F_TLS_PROCESS_SERVER_CERTIFICATE 367 +# define SSL_F_TLS_PROCESS_SERVER_DONE 368 +# define SSL_F_TLS_PROCESS_SERVER_HELLO 369 +# define SSL_F_TLS_PROCESS_SKE_DHE 419 +# define SSL_F_TLS_PROCESS_SKE_ECDHE 420 +# define SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE 421 +# define SSL_F_TLS_PROCESS_SKE_SRP 422 +# define SSL_F_TLS_PSK_DO_BINDER 506 +# define SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT 450 +# define SSL_F_TLS_SETUP_HANDSHAKE 508 +# define SSL_F_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_WPACKET_INTERN_INIT_LEN 633 +# define SSL_F_WPACKET_START_SUB_PACKET_LEN__ 634 +# define SSL_F_WRITE_STATE_MACHINE 586 + +/* + * SSL reason codes. + */ +# define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE 143 +# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CIPHER 186 +# define SSL_R_BAD_DATA 390 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_VALUE 102 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_EARLY_DATA 233 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_EXTENSION 110 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HANDSHAKE_STATE 236 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_HRR_VERSION 263 +# define SSL_R_BAD_KEY_SHARE 108 +# define SSL_R_BAD_KEY_UPDATE 122 +# define SSL_R_BAD_LEGACY_VERSION 292 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_PACKET 240 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK 219 +# define SSL_R_BAD_PSK_IDENTITY 114 +# define SSL_R_BAD_RECORD_TYPE 443 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_VALUE 384 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BINDER_DOES_NOT_VERIFY 253 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CALLBACK_FAILED 234 +# define SSL_R_CANNOT_CHANGE_CIPHER 109 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_KEY_TOO_SMALL 397 +# define SSL_R_CA_MD_TOO_WEAK 398 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_CB_ERROR 377 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED 218 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_CONTEXT_NOT_DANE_ENABLED 167 +# define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED 206 +# define SSL_R_DANE_ALREADY_ENABLED 172 +# define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL 173 +# define SSL_R_DANE_NOT_ENABLED 175 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE 180 +# define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE 184 +# define SSL_R_DANE_TLSA_BAD_DATA_LENGTH 189 +# define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH 192 +# define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE 200 +# define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY 201 +# define SSL_R_DANE_TLSA_BAD_SELECTOR 202 +# define SSL_R_DANE_TLSA_NULL_DATA 203 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 394 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 +# define SSL_R_EE_KEY_TOO_SMALL 399 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204 +# define SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE 194 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTENSION_NOT_RECEIVED 279 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_EXT_LENGTH_MISMATCH 163 +# define SSL_R_FAILED_TO_INIT_ASYNC 405 +# define SSL_R_FRAGMENTED_CLIENT_HELLO 401 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_POINT_COMPRESSION 162 +# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INCONSISTENT_EARLY_DATA_ALPN 222 +# define SSL_R_INCONSISTENT_EARLY_DATA_SNI 231 +# define SSL_R_INCONSISTENT_EXTMS 104 +# define SSL_R_INSUFFICIENT_SECURITY 241 +# define SSL_R_INVALID_ALERT 205 +# define SSL_R_INVALID_CCS_MESSAGE 260 +# define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_CONFIG 283 +# define SSL_R_INVALID_CONFIGURATION_NAME 113 +# define SSL_R_INVALID_CONTEXT 282 +# define SSL_R_INVALID_CT_VALIDATION_TYPE 212 +# define SSL_R_INVALID_KEY_UPDATE_TYPE 120 +# define SSL_R_INVALID_MAX_EARLY_DATA 174 +# define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_SEQUENCE_NUMBER 402 +# define SSL_R_INVALID_SERVERINFO_DATA 388 +# define SSL_R_INVALID_SESSION_ID 999 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_LONG 404 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 +# define SSL_R_MISSING_FATAL 256 +# define SSL_R_MISSING_PARAMETERS 290 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SIGALGS_EXTENSION 112 +# define SSL_R_MISSING_SIGNING_CERT 221 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION 209 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 +# define SSL_R_NOT_ON_RECORD_BOUNDARY 182 +# define SSL_R_NOT_REPLACING_CERTIFICATE 289 +# define SSL_R_NOT_SERVER 284 +# define SSL_R_NO_APPLICATION_PROTOCOL 235 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CHANGE_FOLLOWING_HRR 214 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_COOKIE_CALLBACK_SET 287 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PEM_EXTENSIONS 389 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SHARED_GROUPS 410 +# define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_SUITABLE_KEY_SHARE 101 +# define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 +# define SSL_R_NO_VALID_SCTS 216 +# define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_OVERFLOW_ERROR 237 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEM_NAME_BAD_PREFIX 391 +# define SSL_R_PEM_NAME_TOO_SHORT 392 +# define SSL_R_PIPELINE_FAILURE 406 +# define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278 +# define SSL_R_PRIVATE_KEY_MISMATCH 288 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUEST_PENDING 285 +# define SSL_R_REQUEST_SENT 286 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SCT_VERIFICATION_FAILED 208 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH 232 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_COMMAND_SECTION_EMPTY 117 +# define SSL_R_SSL_COMMAND_SECTION_NOT_FOUND 125 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_NEGATIVE_LENGTH 372 +# define SSL_R_SSL_SECTION_EMPTY 126 +# define SSL_R_SSL_SECTION_NOT_FOUND 136 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_TOO_LONG 408 +# define SSL_R_SSL_SESSION_VERSION_MISMATCH 210 +# define SSL_R_STILL_IN_INIT 121 +# define SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 +# define SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TOO_MANY_KEY_UPDATES 132 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 +# define SSL_R_TOO_MUCH_EARLY_DATA 164 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_CCS_MESSAGE 262 +# define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_CMD_NAME 386 +# define SSL_R_UNKNOWN_COMMAND 139 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSOLICITED_EXTENSION 217 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_VERSION_TOO_HIGH 166 +# define SSL_R_VERSION_TOO_LOW 396 +# define SSL_R_WRONG_CERTIFICATE_TYPE 383 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/stack.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/stack.h new file mode 100644 index 00000000..cfc07505 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/stack.h @@ -0,0 +1,83 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */ + +typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); +typedef void (*OPENSSL_sk_freefunc)(void *); +typedef void *(*OPENSSL_sk_copyfunc)(const void *); + +int OPENSSL_sk_num(const OPENSSL_STACK *); +void *OPENSSL_sk_value(const OPENSSL_STACK *, int); + +void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data); + +OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n); +int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n); +void OPENSSL_sk_free(OPENSSL_STACK *); +void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *)); +OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *, + OPENSSL_sk_copyfunc c, + OPENSSL_sk_freefunc f); +int OPENSSL_sk_insert(OPENSSL_STACK *sk, const void *data, int where); +void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc); +void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p); +int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data); +int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data); +void *OPENSSL_sk_shift(OPENSSL_STACK *st); +void *OPENSSL_sk_pop(OPENSSL_STACK *st); +void OPENSSL_sk_zero(OPENSSL_STACK *st); +OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_compfunc cmp); +OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *st); +void OPENSSL_sk_sort(OPENSSL_STACK *st); +int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define _STACK OPENSSL_STACK +# define sk_num OPENSSL_sk_num +# define sk_value OPENSSL_sk_value +# define sk_set OPENSSL_sk_set +# define sk_new OPENSSL_sk_new +# define sk_new_null OPENSSL_sk_new_null +# define sk_free OPENSSL_sk_free +# define sk_pop_free OPENSSL_sk_pop_free +# define sk_deep_copy OPENSSL_sk_deep_copy +# define sk_insert OPENSSL_sk_insert +# define sk_delete OPENSSL_sk_delete +# define sk_delete_ptr OPENSSL_sk_delete_ptr +# define sk_find OPENSSL_sk_find +# define sk_find_ex OPENSSL_sk_find_ex +# define sk_push OPENSSL_sk_push +# define sk_unshift OPENSSL_sk_unshift +# define sk_shift OPENSSL_sk_shift +# define sk_pop OPENSSL_sk_pop +# define sk_zero OPENSSL_sk_zero +# define sk_set_cmp_func OPENSSL_sk_set_cmp_func +# define sk_dup OPENSSL_sk_dup +# define sk_sort OPENSSL_sk_sort +# define sk_is_sorted OPENSSL_sk_is_sorted +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/store.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/store.h new file mode 100644 index 00000000..a40a7339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/store.h @@ -0,0 +1,266 @@ +/* + * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STORE_H +# define HEADER_OSSL_STORE_H + +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * The main OSSL_STORE functions. + * ------------------------------ + * + * These allow applications to open a channel to a resource with supported + * data (keys, certs, crls, ...), read the data a piece at a time and decide + * what to do with it, and finally close. + */ + +typedef struct ossl_store_ctx_st OSSL_STORE_CTX; + +/* + * Typedef for the OSSL_STORE_INFO post processing callback. This can be used + * to massage the given OSSL_STORE_INFO, or to drop it entirely (by returning + * NULL). + */ +typedef OSSL_STORE_INFO *(*OSSL_STORE_post_process_info_fn)(OSSL_STORE_INFO *, + void *); + +/* + * Open a channel given a URI. The given UI method will be used any time the + * loader needs extra input, for example when a password or pin is needed, and + * will be passed the same user data every time it's needed in this context. + * + * Returns a context reference which represents the channel to communicate + * through. + */ +OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, + void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data); + +/* + * Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be + * done, and depends on the underlying loader (use OSSL_STORE_get0_scheme to + * determine which loader is used), except for common commands (see below). + * Each command takes different arguments. + */ +int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */); +int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); + +/* + * Common ctrl commands that different loaders may choose to support. + */ +/* int on = 0 or 1; STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on); */ +# define OSSL_STORE_C_USE_SECMEM 1 +/* Where custom commands start */ +# define OSSL_STORE_C_CUSTOM_START 100 + +/* + * Read one data item (a key, a cert, a CRL) that is supported by the OSSL_STORE + * functionality, given a context. + * Returns a OSSL_STORE_INFO pointer, from which OpenSSL typed data can be + * extracted with OSSL_STORE_INFO_get0_PKEY(), OSSL_STORE_INFO_get0_CERT(), ... + * NULL is returned on error, which may include that the data found at the URI + * can't be figured out for certain or is ambiguous. + */ +OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx); + +/* + * Check if end of data (end of file) is reached + * Returns 1 on end, 0 otherwise. + */ +int OSSL_STORE_eof(OSSL_STORE_CTX *ctx); + +/* + * Check if an error occurred + * Returns 1 if it did, 0 otherwise. + */ +int OSSL_STORE_error(OSSL_STORE_CTX *ctx); + +/* + * Close the channel + * Returns 1 on success, 0 on error. + */ +int OSSL_STORE_close(OSSL_STORE_CTX *ctx); + + +/*- + * Extracting OpenSSL types from and creating new OSSL_STORE_INFOs + * --------------------------------------------------------------- + */ + +/* + * Types of data that can be ossl_stored in a OSSL_STORE_INFO. + * OSSL_STORE_INFO_NAME is typically found when getting a listing of + * available "files" / "tokens" / what have you. + */ +# define OSSL_STORE_INFO_NAME 1 /* char * */ +# define OSSL_STORE_INFO_PARAMS 2 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_PKEY 3 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_CERT 4 /* X509 * */ +# define OSSL_STORE_INFO_CRL 5 /* X509_CRL * */ + +/* + * Functions to generate OSSL_STORE_INFOs, one function for each type we + * support having in them, as well as a generic constructor. + * + * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO + * and will therefore be freed when the OSSL_STORE_INFO is freed. + */ +OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name); +int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); + +/* + * Functions to try to extract data from a OSSL_STORE_INFO. + */ +int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info); +const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info); +char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info); +X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info); +X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info); + +const char *OSSL_STORE_INFO_type_string(int type); + +/* + * Free the OSSL_STORE_INFO + */ +void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info); + + +/*- + * Functions to construct a search URI from a base URI and search criteria + * ----------------------------------------------------------------------- + */ + +/* OSSL_STORE search types */ +# define OSSL_STORE_SEARCH_BY_NAME 1 /* subject in certs, issuer in CRLs */ +# define OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 2 +# define OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 3 +# define OSSL_STORE_SEARCH_BY_ALIAS 4 + +/* To check what search types the scheme handler supports */ +int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type); + +/* Search term constructors */ +/* + * The input is considered to be owned by the caller, and must therefore + * remain present throughout the lifetime of the returned OSSL_STORE_SEARCH + */ +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, + const ASN1_INTEGER + *serial); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, + const unsigned char + *bytes, size_t len); +OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias); + +/* Search term destructor */ +void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search); + +/* Search term accessors */ +int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion); +X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion); +const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH + *criterion); +const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH + *criterion, size_t *length); +const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion); +const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion); + +/* + * Add search criterion and expected return type (which can be unspecified) + * to the loading channel. This MUST happen before the first OSSL_STORE_load(). + */ +int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type); +int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search); + + +/*- + * Function to register a loader for the given URI scheme. + * ------------------------------------------------------- + * + * The loader receives all the main components of an URI except for the + * scheme. + */ + +typedef struct ossl_store_loader_st OSSL_STORE_LOADER; +OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme); +const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); +const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); +/* struct ossl_store_loader_ctx_st is defined differently by each loader */ +typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; +typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER + *loader, + const char *uri, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, + OSSL_STORE_open_fn open_function); +typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd, + va_list args); +int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, + OSSL_STORE_ctrl_fn ctrl_function); +typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected); +int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader, + OSSL_STORE_expect_fn expect_function); +typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx, + OSSL_STORE_SEARCH *criteria); +int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader, + OSSL_STORE_find_fn find_function); +typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader, + OSSL_STORE_load_fn load_function); +typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader, + OSSL_STORE_eof_fn eof_function); +typedef int (*OSSL_STORE_error_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, + OSSL_STORE_error_fn error_function); +typedef int (*OSSL_STORE_close_fn)(OSSL_STORE_LOADER_CTX *ctx); +int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, + OSSL_STORE_close_fn close_function); +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); + +int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); +OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme); + +/*- + * Functions to list STORE loaders + * ------------------------------- + */ +int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER + *loader, void *do_arg), + void *do_arg); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/storeerr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/storeerr.h new file mode 100644 index 00000000..190eab07 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/storeerr.h @@ -0,0 +1,91 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_OSSL_STOREERR_H +# define HEADER_OSSL_STOREERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_OSSL_STORE_strings(void); + +/* + * OSSL_STORE function codes. + */ +# define OSSL_STORE_F_FILE_CTRL 129 +# define OSSL_STORE_F_FILE_FIND 138 +# define OSSL_STORE_F_FILE_GET_PASS 118 +# define OSSL_STORE_F_FILE_LOAD 119 +# define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 124 +# define OSSL_STORE_F_FILE_NAME_TO_URI 126 +# define OSSL_STORE_F_FILE_OPEN 120 +# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 127 +# define OSSL_STORE_F_OSSL_STORE_EXPECT 130 +# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 128 +# define OSSL_STORE_F_OSSL_STORE_FIND 131 +# define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 100 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 101 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL 102 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME 103 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION 135 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS 104 +# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY 105 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT 106 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL 107 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED 123 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME 109 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS 110 +# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY 111 +# define OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION 134 +# define OSSL_STORE_F_OSSL_STORE_INIT_ONCE 112 +# define OSSL_STORE_F_OSSL_STORE_LOADER_NEW 113 +# define OSSL_STORE_F_OSSL_STORE_OPEN 114 +# define OSSL_STORE_F_OSSL_STORE_OPEN_INT 115 +# define OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT 117 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS 132 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 133 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 136 +# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME 137 +# define OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT 116 +# define OSSL_STORE_F_TRY_DECODE_PARAMS 121 +# define OSSL_STORE_F_TRY_DECODE_PKCS12 122 +# define OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED 125 + +/* + * OSSL_STORE reason codes. + */ +# define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107 +# define OSSL_STORE_R_BAD_PASSWORD_READ 115 +# define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113 +# define OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST 121 +# define OSSL_STORE_R_INVALID_SCHEME 106 +# define OSSL_STORE_R_IS_NOT_A 112 +# define OSSL_STORE_R_LOADER_INCOMPLETE 116 +# define OSSL_STORE_R_LOADING_STARTED 117 +# define OSSL_STORE_R_NOT_A_CERTIFICATE 100 +# define OSSL_STORE_R_NOT_A_CRL 101 +# define OSSL_STORE_R_NOT_A_KEY 102 +# define OSSL_STORE_R_NOT_A_NAME 103 +# define OSSL_STORE_R_NOT_PARAMETERS 104 +# define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114 +# define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108 +# define OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 119 +# define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109 +# define OSSL_STORE_R_UNREGISTERED_SCHEME 105 +# define OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE 110 +# define OSSL_STORE_R_UNSUPPORTED_OPERATION 118 +# define OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE 120 +# define OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED 111 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/symhacks.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/symhacks.h new file mode 100644 index 00000000..156ea6e4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/symhacks.h @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/tls1.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/tls1.h new file mode 100644 index 00000000..76d9fda4 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/tls1.h @@ -0,0 +1,1237 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Default security level if not overridden at config time */ +# ifndef OPENSSL_TLS_SECURITY_LEVEL +# define OPENSSL_TLS_SECURITY_LEVEL 1 +# endif + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS1_3_VERSION 0x0304 +# define TLS_MAX_VERSION TLS1_3_VERSION + +/* Special value for method supporting multiple versions */ +# define TLS_ANY_VERSION 0x10000 + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((SSL_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_version(s) : 0) + +# define TLS1_get_client_version(s) \ + ((SSL_client_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_client_version(s) : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* TLSv1.3 alerts */ +# define TLS13_AD_MISSING_EXTENSION 109 /* fatal */ +# define TLS13_AD_CERTIFICATE_REQUIRED 116 /* fatal */ +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ +# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +/* + * Prior to TLSv1.3 the supported_groups extension was known as + * elliptic_curves + */ +# define TLSEXT_TYPE_supported_groups 10 +# define TLSEXT_TYPE_elliptic_curves TLSEXT_TYPE_supported_groups +# define TLSEXT_TYPE_ec_point_formats 11 + + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC7301 */ +# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* + * Extension type for Certificate Transparency + * https://tools.ietf.org/html/rfc6962#section-3.3.1 + */ +# define TLSEXT_TYPE_signed_certificate_timestamp 18 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC7366 */ +# define TLSEXT_TYPE_encrypt_then_mac 22 + +/* ExtensionType value from RFC7627 */ +# define TLSEXT_TYPE_extended_master_secret 23 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* As defined for TLS1.3 */ +# define TLSEXT_TYPE_psk 41 +# define TLSEXT_TYPE_early_data 42 +# define TLSEXT_TYPE_supported_versions 43 +# define TLSEXT_TYPE_cookie 44 +# define TLSEXT_TYPE_psk_kex_modes 45 +# define TLSEXT_TYPE_certificate_authorities 47 +# define TLSEXT_TYPE_post_handshake_auth 49 +# define TLSEXT_TYPE_signature_algorithms_cert 50 +# define TLSEXT_TYPE_key_share 51 + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 +# define TLSEXT_signature_gostr34102001 237 +# define TLSEXT_signature_gostr34102012_256 238 +# define TLSEXT_signature_gostr34102012_512 239 + +/* Total number of different signature algorithms */ +# define TLSEXT_signature_num 7 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 +# define TLSEXT_hash_gostr3411 237 +# define TLSEXT_hash_gostr34112012_256 238 +# define TLSEXT_hash_gostr34112012_512 239 + +/* Total number of different digest algorithms */ + +# define TLSEXT_hash_num 10 + +/* Flag set for unrecognised algorithms */ +# define TLSEXT_nid_unknown 0x1000000 + +/* ECC curves */ + +# define TLSEXT_curve_P_256 23 +# define TLSEXT_curve_P_384 24 + +/* OpenSSL value to disable maximum fragment length extension */ +# define TLSEXT_max_fragment_length_DISABLED 0 +/* Allowed values for max fragment length extension */ +# define TLSEXT_max_fragment_length_512 1 +# define TLSEXT_max_fragment_length_1024 2 +# define TLSEXT_max_fragment_length_2048 3 +# define TLSEXT_max_fragment_length_4096 4 + +int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode); +int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode); + +# define TLSEXT_MAXLEN_host_name 255 + +__owur const char *SSL_get_servername(const SSL *s, const int type); +__owur int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * 0 or -1 otherwise. + */ +__owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context); + +/* + * SSL_export_keying_material_early exports a value derived from the + * early exporter master secret, as specified in + * https://tools.ietf.org/html/draft-ietf-tls-tls13-23. It writes + * |olen| bytes to |out| given a label and optional context. It + * returns 1 on success and 0 otherwise. + */ +__owur int SSL_export_keying_material_early(SSL *s, unsigned char *out, + size_t olen, const char *label, + size_t llen, + const unsigned char *context, + size_t contextlen); + +int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid); +int SSL_get_signature_type_nid(const SSL *s, int *pnid); + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +__owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); + +# define SSL_set_tlsext_host_name(s,name) \ + SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,\ + (void *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ + SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,\ + (void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0,arg) + +# define SSL_get_tlsext_status_type(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_set_tlsext_status_type(ssl, type) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0,arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0,arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0,arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen,arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ + SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,\ + (void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0,arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_TLSEXT_TICKET_KEYS,keylen,keys) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_TICKET_KEYS,keylen,keys) + +# define SSL_CTX_get_tlsext_status_cb(ssl, cb) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB,0,(void *)cb) +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,\ + (void (*)(void))cb) + +# define SSL_CTX_get_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0,arg) + +# define SSL_CTX_set_tlsext_status_type(ssl, type) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type,NULL) + +# define SSL_CTX_get_tlsext_status_type(ssl) \ + SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0,NULL) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ + SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,\ + (void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_DTLSEXT_HB_ENABLED 0x01 +# define SSL_DTLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_DTLSEXT_HB_DONT_RECV_REQUESTS 0x04 +# define SSL_get_dtlsext_heartbeat_pending(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_dtlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl(ssl,SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) + +# if OPENSSL_API_COMPAT < 0x10100000L +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT \ + SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING \ + SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS \ + SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS +# define SSL_TLSEXT_HB_ENABLED \ + SSL_DTLSEXT_HB_ENABLED +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS \ + SSL_DTLSEXT_HB_DONT_SEND_REQUESTS +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS \ + SSL_DTLSEXT_HB_DONT_RECV_REQUESTS +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_get_dtlsext_heartbeat_pending(ssl) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_set_dtlsext_heartbeat_no_requests(ssl,arg) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D +# define TLS1_CK_DHE_PSK_WITH_RC4_128_SHA 0x0300008E +# define TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008F +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA 0x03000090 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA 0x03000091 +# define TLS1_CK_RSA_PSK_WITH_RC4_128_SHA 0x03000092 +# define TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x03000093 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA 0x03000094 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA 0x03000095 + +/* PSK ciphersuites from 5487 */ +# define TLS1_CK_PSK_WITH_AES_128_GCM_SHA256 0x030000A8 +# define TLS1_CK_PSK_WITH_AES_256_GCM_SHA384 0x030000A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256 0x030000AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384 0x030000AB +# define TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256 0x030000AC +# define TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384 0x030000AD +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA256 0x030000AE +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA384 0x030000AF +# define TLS1_CK_PSK_WITH_NULL_SHA256 0x030000B0 +# define TLS1_CK_PSK_WITH_NULL_SHA384 0x030000B1 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256 0x030000B2 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384 0x030000B3 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA256 0x030000B4 +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA384 0x030000B5 +# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256 0x030000B6 +# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384 0x030000B7 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA256 0x030000B8 +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA384 0x030000B9 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_PSK_WITH_NULL_SHA 0x0300002C +# define TLS1_CK_DHE_PSK_WITH_NULL_SHA 0x0300002D +# define TLS1_CK_RSA_PSK_WITH_NULL_SHA 0x0300002E + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_CK_RSA_WITH_AES_128_CCM 0x0300C09C +# define TLS1_CK_RSA_WITH_AES_256_CCM 0x0300C09D +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM 0x0300C09E +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM 0x0300C09F +# define TLS1_CK_RSA_WITH_AES_128_CCM_8 0x0300C0A0 +# define TLS1_CK_RSA_WITH_AES_256_CCM_8 0x0300C0A1 +# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8 0x0300C0A2 +# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8 0x0300C0A3 +# define TLS1_CK_PSK_WITH_AES_128_CCM 0x0300C0A4 +# define TLS1_CK_PSK_WITH_AES_256_CCM 0x0300C0A5 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM 0x0300C0A6 +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM 0x0300C0A7 +# define TLS1_CK_PSK_WITH_AES_128_CCM_8 0x0300C0A8 +# define TLS1_CK_PSK_WITH_AES_256_CCM_8 0x0300C0A9 +# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8 0x0300C0AA +# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8 0x0300C0AB + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM 0x0300C0AC +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM 0x0300C0AD +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8 0x0300C0AE +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8 0x0300C0AF + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BA +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BB +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BC +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 0x030000BD +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x030000BE +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256 0x030000BF + +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C0 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C1 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C2 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 0x030000C3 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0x030000C4 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256 0x030000C5 + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* ECDHE PSK ciphersuites from RFC5489 */ +# define TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA 0x0300C033 +# define TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0x0300C034 +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0x0300C037 +# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0x0300C038 + +/* NULL PSK ciphersuites from RFC4785 */ +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA 0x0300C039 +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256 0x0300C03A +# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384 0x0300C03B + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C072 +# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C073 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C074 +# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C075 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C076 +# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C077 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C078 +# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C079 + +# define TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C094 +# define TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C095 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C096 +# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C097 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C098 +# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C099 +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C09A +# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C09B + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCA8 +# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0x0300CCA9 +# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCAA +# define TLS1_CK_PSK_WITH_CHACHA20_POLY1305 0x0300CCAB +# define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAC +# define TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305 0x0300CCAD +# define TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305 0x0300CCAE + +/* TLS v1.3 ciphersuites */ +# define TLS1_3_CK_AES_128_GCM_SHA256 0x03001301 +# define TLS1_3_CK_AES_256_GCM_SHA384 0x03001302 +# define TLS1_3_CK_CHACHA20_POLY1305_SHA256 0x03001303 +# define TLS1_3_CK_AES_128_CCM_SHA256 0x03001304 +# define TLS1_3_CK_AES_128_CCM_8_SHA256 0x03001305 + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_CK_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C050 +# define TLS1_CK_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C051 +# define TLS1_CK_DHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C052 +# define TLS1_CK_DHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C053 +# define TLS1_CK_DH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C054 +# define TLS1_CK_DH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C055 +# define TLS1_CK_DHE_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C056 +# define TLS1_CK_DHE_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C057 +# define TLS1_CK_DH_DSS_WITH_ARIA_128_GCM_SHA256 0x0300C058 +# define TLS1_CK_DH_DSS_WITH_ARIA_256_GCM_SHA384 0x0300C059 +# define TLS1_CK_DH_anon_WITH_ARIA_128_GCM_SHA256 0x0300C05A +# define TLS1_CK_DH_anon_WITH_ARIA_256_GCM_SHA384 0x0300C05B +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05C +# define TLS1_CK_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05D +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 0x0300C05E +# define TLS1_CK_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 0x0300C05F +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C060 +# define TLS1_CK_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C061 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 0x0300C062 +# define TLS1_CK_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 0x0300C063 +# define TLS1_CK_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06A +# define TLS1_CK_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06B +# define TLS1_CK_DHE_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06C +# define TLS1_CK_DHE_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06D +# define TLS1_CK_RSA_PSK_WITH_ARIA_128_GCM_SHA256 0x0300C06E +# define TLS1_CK_RSA_PSK_WITH_ARIA_256_GCM_SHA384 0x0300C06F + +/* a bundle of RFC standard cipher names, generated from ssl3_ciphers[] */ +# define TLS1_RFC_RSA_WITH_AES_128_SHA "TLS_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA "TLS_DHE_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_128_SHA "TLS_DH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_WITH_AES_256_SHA "TLS_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA "TLS_DHE_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_AES_256_SHA "TLS_DH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_NULL_SHA256 "TLS_RSA_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_SHA256 "TLS_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_SHA256 "TLS_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_SHA256 "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_SHA256 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_SHA256 "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_SHA256 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_128_SHA256 "TLS_DH_anon_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_SHA256 "TLS_DH_anon_WITH_AES_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_AES_128_GCM_SHA256 "TLS_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_AES_256_GCM_SHA384 "TLS_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_AES_128_GCM_SHA256 "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_AES_256_GCM_SHA384 "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ADH_WITH_AES_128_GCM_SHA256 "TLS_DH_anon_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ADH_WITH_AES_256_GCM_SHA384 "TLS_DH_anon_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_WITH_AES_128_CCM "TLS_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_RSA_WITH_AES_256_CCM "TLS_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM "TLS_DHE_RSA_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM "TLS_DHE_RSA_WITH_AES_256_CCM" +# define TLS1_RFC_RSA_WITH_AES_128_CCM_8 "TLS_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_RSA_WITH_AES_256_CCM_8 "TLS_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_128_CCM_8 "TLS_DHE_RSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_RSA_WITH_AES_256_CCM_8 "TLS_DHE_RSA_WITH_AES_256_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_128_CCM "TLS_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_PSK_WITH_AES_256_CCM "TLS_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM "TLS_DHE_PSK_WITH_AES_128_CCM" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM "TLS_DHE_PSK_WITH_AES_256_CCM" +# define TLS1_RFC_PSK_WITH_AES_128_CCM_8 "TLS_PSK_WITH_AES_128_CCM_8" +# define TLS1_RFC_PSK_WITH_AES_256_CCM_8 "TLS_PSK_WITH_AES_256_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CCM_8 "TLS_PSK_DHE_WITH_AES_128_CCM_8" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CCM_8 "TLS_PSK_DHE_WITH_AES_256_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM "TLS_ECDHE_ECDSA_WITH_AES_128_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM "TLS_ECDHE_ECDSA_WITH_AES_256_CCM" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CCM_8 "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8" +# define TLS1_3_RFC_AES_128_GCM_SHA256 "TLS_AES_128_GCM_SHA256" +# define TLS1_3_RFC_AES_256_GCM_SHA384 "TLS_AES_256_GCM_SHA384" +# define TLS1_3_RFC_CHACHA20_POLY1305_SHA256 "TLS_CHACHA20_POLY1305_SHA256" +# define TLS1_3_RFC_AES_128_CCM_SHA256 "TLS_AES_128_CCM_SHA256" +# define TLS1_3_RFC_AES_128_CCM_8_SHA256 "TLS_AES_128_CCM_8_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_NULL_SHA "TLS_ECDHE_ECDSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_NULL_SHA "TLS_ECDHE_RSA_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_DES_192_CBC3_SHA "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_CBC_SHA "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_NULL_SHA "TLS_ECDH_anon_WITH_NULL_SHA" +# define TLS1_RFC_ECDH_anon_WITH_DES_192_CBC3_SHA "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_128_CBC_SHA "TLS_ECDH_anon_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDH_anon_WITH_AES_256_CBC_SHA "TLS_ECDH_anon_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA "TLS_PSK_WITH_NULL_SHA" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA "TLS_DHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA "TLS_RSA_PSK_WITH_NULL_SHA" +# define TLS1_RFC_PSK_WITH_3DES_EDE_CBC_SHA "TLS_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA "TLS_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA "TLS_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_3DES_EDE_CBC_SHA "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA "TLS_RSA_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA "TLS_RSA_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_PSK_WITH_AES_128_GCM_SHA256 "TLS_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_GCM_SHA384 "TLS_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_GCM_SHA256 "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_GCM_SHA384 "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_GCM_SHA256 "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_GCM_SHA384 "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_AES_128_CBC_SHA256 "TLS_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_AES_256_CBC_SHA384 "TLS_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_NULL_SHA256 "TLS_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_PSK_WITH_NULL_SHA384 "TLS_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA256 "TLS_DHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_NULL_SHA384 "TLS_DHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_AES_128_CBC_SHA256 "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_AES_256_CBC_SHA384 "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA256 "TLS_RSA_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_NULL_SHA384 "TLS_RSA_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA "TLS_ECDHE_PSK_WITH_NULL_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA256 "TLS_ECDHE_PSK_WITH_NULL_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_NULL_SHA384 "TLS_ECDHE_PSK_WITH_NULL_SHA384" +# define TLS1_RFC_SRP_SHA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA" +# define TLS1_RFC_SRP_SHA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CHACHA20_POLY1305 "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA256 "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" +# define TLS1_RFC_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_256_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA" +# define TLS1_RFC_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ADH_WITH_CAMELLIA_128_CBC_SHA "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" +# define TLS1_RFC_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" +# define TLS1_RFC_RSA_WITH_SEED_SHA "TLS_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_DSS_WITH_SEED_SHA "TLS_DHE_DSS_WITH_SEED_CBC_SHA" +# define TLS1_RFC_DHE_RSA_WITH_SEED_SHA "TLS_DHE_RSA_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ADH_WITH_SEED_SHA "TLS_DH_anon_WITH_SEED_CBC_SHA" +# define TLS1_RFC_ECDHE_PSK_WITH_RC4_128_SHA "TLS_ECDHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDH_anon_WITH_RC4_128_SHA "TLS_ECDH_anon_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_ECDSA_WITH_RC4_128_SHA "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" +# define TLS1_RFC_ECDHE_RSA_WITH_RC4_128_SHA "TLS_ECDHE_RSA_WITH_RC4_128_SHA" +# define TLS1_RFC_PSK_WITH_RC4_128_SHA "TLS_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_PSK_WITH_RC4_128_SHA "TLS_RSA_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_DHE_PSK_WITH_RC4_128_SHA "TLS_DHE_PSK_WITH_RC4_128_SHA" +# define TLS1_RFC_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_DSS_WITH_ARIA_128_GCM_SHA256 "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_DSS_WITH_ARIA_256_GCM_SHA384 "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DH_anon_WITH_ARIA_128_GCM_SHA256 "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DH_anon_WITH_ARIA_256_GCM_SHA384 "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" +# define TLS1_RFC_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" + + +/* + * XXX Backward compatibility alert: Older versions of OpenSSL gave some DHE + * ciphers names with "EDH" instead of "DHE". Going forward, we should be + * using DHE everywhere, though we may indefinitely maintain aliases for + * users or configurations that used "EDH" + */ +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +# define TLS1_TXT_PSK_WITH_NULL_SHA "PSK-NULL-SHA" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA "DHE-PSK-NULL-SHA" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA "RSA-PSK-NULL-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +# define TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA "DHE-PSK-RC4-SHA" +# define TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA "DHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA "DHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA "DHE-PSK-AES256-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA "RSA-PSK-RC4-SHA" +# define TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA "RSA-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA "RSA-PSK-AES128-CBC-SHA" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA "RSA-PSK-AES256-CBC-SHA" + +/* PSK ciphersuites from RFC 5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256 "DHE-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384 "DHE-PSK-AES256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256 "RSA-PSK-AES128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384 "RSA-PSK-AES256-GCM-SHA384" + +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256 "PSK-AES128-CBC-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384 "PSK-AES256-CBC-SHA384" +# define TLS1_TXT_PSK_WITH_NULL_SHA256 "PSK-NULL-SHA256" +# define TLS1_TXT_PSK_WITH_NULL_SHA384 "PSK-NULL-SHA384" + +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256 "DHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384 "DHE-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA256 "DHE-PSK-NULL-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA384 "DHE-PSK-NULL-SHA384" + +# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256 "RSA-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384 "RSA-PSK-AES256-CBC-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA256 "RSA-PSK-NULL-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA384 "RSA-PSK-NULL-SHA384" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256 "CAMELLIA128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DH-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 "DHE-DSS-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "DHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256 "ADH-CAMELLIA128-SHA256" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256 "CAMELLIA256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DH-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DH-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 "DHE-DSS-CAMELLIA256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 "DHE-RSA-CAMELLIA256-SHA256" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256 "ADH-CAMELLIA256-SHA256" + +# define TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256 "PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384 "PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "DHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "DHE-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 "RSA-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 "RSA-PSK-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-PSK-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-PSK-CAMELLIA256-SHA384" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* CCM ciphersuites from RFC6655 */ +# define TLS1_TXT_RSA_WITH_AES_128_CCM "AES128-CCM" +# define TLS1_TXT_RSA_WITH_AES_256_CCM "AES256-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM "DHE-RSA-AES128-CCM" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM "DHE-RSA-AES256-CCM" + +# define TLS1_TXT_RSA_WITH_AES_128_CCM_8 "AES128-CCM8" +# define TLS1_TXT_RSA_WITH_AES_256_CCM_8 "AES256-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8 "DHE-RSA-AES128-CCM8" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8 "DHE-RSA-AES256-CCM8" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM "PSK-AES128-CCM" +# define TLS1_TXT_PSK_WITH_AES_256_CCM "PSK-AES256-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM "DHE-PSK-AES128-CCM" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM "DHE-PSK-AES256-CCM" + +# define TLS1_TXT_PSK_WITH_AES_128_CCM_8 "PSK-AES128-CCM8" +# define TLS1_TXT_PSK_WITH_AES_256_CCM_8 "PSK-AES256-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8 "DHE-PSK-AES128-CCM8" +# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8 "DHE-PSK-AES256-CCM8" + +/* CCM ciphersuites from RFC7251 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM "ECDHE-ECDSA-AES128-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM "ECDHE-ECDSA-AES256-CCM" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8 "ECDHE-ECDSA-AES128-CCM8" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8 "ECDHE-ECDSA-AES256-CCM8" + +/* ECDH HMAC based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +/* TLS v1.2 PSK GCM ciphersuites from RFC5487 */ +# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256 "PSK-AES128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384 "PSK-AES256-GCM-SHA384" + +/* ECDHE PSK ciphersuites from RFC 5489 */ +# define TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA "ECDHE-PSK-RC4-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA "ECDHE-PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-PSK-AES256-CBC-SHA" + +# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256 "ECDHE-PSK-AES128-CBC-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384 "ECDHE-PSK-AES256-CBC-SHA384" + +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA "ECDHE-PSK-NULL-SHA" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256 "ECDHE-PSK-NULL-SHA256" +# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384 "ECDHE-PSK-NULL-SHA384" + +/* Camellia-CBC ciphersuites from RFC6367 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-ECDSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-ECDSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-RSA-CAMELLIA256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-RSA-CAMELLIA128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-RSA-CAMELLIA256-SHA384" + +/* draft-ietf-tls-chacha20-poly1305-03 */ +# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305" +# define TLS1_TXT_PSK_WITH_CHACHA20_POLY1305 "PSK-CHACHA20-POLY1305" +# define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305 "ECDHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305 "DHE-PSK-CHACHA20-POLY1305" +# define TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305 "RSA-PSK-CHACHA20-POLY1305" + +/* Aria ciphersuites from RFC6209 */ +# define TLS1_TXT_RSA_WITH_ARIA_128_GCM_SHA256 "ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_ARIA_256_GCM_SHA384 "ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_128_GCM_SHA256 "DHE-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_ARIA_256_GCM_SHA384 "DHE-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_ARIA_128_GCM_SHA256 "DH-RSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_ARIA_256_GCM_SHA384 "DH-RSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_128_GCM_SHA256 "DHE-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_ARIA_256_GCM_SHA384 "DHE-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_ARIA_128_GCM_SHA256 "DH-DSS-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_ARIA_256_GCM_SHA384 "DH-DSS-ARIA256-GCM-SHA384" +# define TLS1_TXT_DH_anon_WITH_ARIA_128_GCM_SHA256 "ADH-ARIA128-GCM-SHA256" +# define TLS1_TXT_DH_anon_WITH_ARIA_256_GCM_SHA384 "ADH-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ECDSA-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ECDSA-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 "ECDHE-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 "ECDHE-ARIA256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 "ECDH-ARIA128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 "ECDH-ARIA256-GCM-SHA384" +# define TLS1_TXT_PSK_WITH_ARIA_128_GCM_SHA256 "PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_PSK_WITH_ARIA_256_GCM_SHA384 "PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_128_GCM_SHA256 "DHE-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_DHE_PSK_WITH_ARIA_256_GCM_SHA384 "DHE-PSK-ARIA256-GCM-SHA384" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_128_GCM_SHA256 "RSA-PSK-ARIA128-GCM-SHA256" +# define TLS1_TXT_RSA_PSK_WITH_ARIA_256_GCM_SHA384 "RSA-PSK-ARIA256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST01_SIGN 22 +# define TLS_CT_GOST12_SIGN 238 +# define TLS_CT_GOST12_512_SIGN 239 + +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 10 + +# if defined(SSL3_CT_NUMBER) +# if TLS_CT_NUMBER != SSL3_CT_NUMBER +# error "SSL/TLS CT_NUMBER values do not match" +# endif +# endif + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 22 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "extended master secret" +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE 22 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# undef TLS_MD_EXTENDED_MASTER_SECRET_CONST +/* + * extended master secret + */ +# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x6e\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ts.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ts.h new file mode 100644 index 00000000..3b58aa52 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ts.h @@ -0,0 +1,559 @@ +/* + * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include + +# ifndef OPENSSL_NO_TS +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# include +# include + +typedef struct TS_msg_imprint_st TS_MSG_IMPRINT; +typedef struct TS_req_st TS_REQ; +typedef struct TS_accuracy_st TS_ACCURACY; +typedef struct TS_tst_info_st TS_TST_INFO; + +/* Possible values for status. */ +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* Possible values for failure_info. */ +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + + +typedef struct TS_status_info_st TS_STATUS_INFO; +typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; +typedef struct ESS_cert_id ESS_CERT_ID; +typedef struct ESS_signing_cert ESS_SIGNING_CERT; + +DEFINE_STACK_OF(ESS_CERT_ID) + +typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2; +typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2; + +DEFINE_STACK_OF(ESS_CERT_ID_V2) + +typedef struct TS_resp_st TS_RESP; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +#ifndef OPENSSL_NO_STDIO +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +#endif +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +#ifndef OPENSSL_NO_STDIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +#endif +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +#ifndef OPENSSL_NO_STDIO +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +#endif +TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +#ifndef OPENSSL_NO_STDIO +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +#endif +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new(void); +void ESS_CERT_ID_V2_free(ESS_CERT_ID_V2 *a); +int i2d_ESS_CERT_ID_V2(const ESS_CERT_ID_V2 *a, unsigned char **pp); +ESS_CERT_ID_V2 *d2i_ESS_CERT_ID_V2(ESS_CERT_ID_V2 **a, + const unsigned char **pp, long length); +ESS_CERT_ID_V2 *ESS_CERT_ID_V2_dup(ESS_CERT_ID_V2 *a); + +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new(void); +void ESS_SIGNING_CERT_V2_free(ESS_SIGNING_CERT_V2 *a); +int i2d_ESS_SIGNING_CERT_V2(const ESS_SIGNING_CERT_V2 *a, unsigned char **pp); +ESS_SIGNING_CERT_V2 *d2i_ESS_SIGNING_CERT_V2(ESS_SIGNING_CERT_V2 **a, + const unsigned char **pp, + long length); +ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_dup(ESS_SIGNING_CERT_V2 *a); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i); +const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a); + +const STACK_OF(ASN1_UTF8STRING) * +TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a); + +const ASN1_BIT_STRING * +TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, + int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx TS_RESP_CTX; + +DEFINE_STACK_OF_CONST(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, + const EVP_MD *signer_digest); +int TS_RESP_CTX_set_ess_cert_id_digest(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* Maximum status message length */ +# define TS_MAX_STATUS_LENGTH (1024 * 1024) + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); +int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f); +int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f); +BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b); +unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, + unsigned char *hexstr, long len); +X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s); +STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +#ifndef OPENSSL_NO_ENGINE +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +#endif +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_digest(CONF *conf, const char *section, + const char *md, TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_digest(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/tserr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/tserr.h new file mode 100644 index 00000000..07f23339 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/tserr.h @@ -0,0 +1,132 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TSERR_H +# define HEADER_TSERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# include + +# ifndef OPENSSL_NO_TS + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_TS_strings(void); + +/* + * TS function codes. + */ +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_ADD_SIGNING_CERT_V2 147 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_CERT_ID_V2_NEW_INIT 156 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_ESS_SIGNING_CERT_V2_NEW_INIT 157 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_INVALID 151 +# define TS_F_TS_CONF_LOAD_CERT 153 +# define TS_F_TS_CONF_LOAD_CERTS 154 +# define TS_F_TS_CONF_LOAD_KEY 155 +# define TS_F_TS_CONF_LOOKUP_FAIL 152 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* + * TS reason codes. + */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CANNOT_LOAD_CERT 137 +# define TS_R_CANNOT_LOAD_KEY 138 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR 139 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_VAR_BAD_VALUE 135 +# define TS_R_VAR_LOOKUP_FAILURE 136 +# define TS_R_WRONG_CONTENT_TYPE 114 + +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/txt_db.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/txt_db.h new file mode 100644 index 00000000..ec981a43 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/txt_db.h @@ -0,0 +1,57 @@ +/* + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include +# include +# include +# include + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 +# define DB_ERROR_WRONG_NUM_FIELDS 6 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DEFINE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/ui.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ui.h new file mode 100644 index 00000000..7c721ec8 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/ui.h @@ -0,0 +1,368 @@ +/* + * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# endif +# include +# include +# include +# include + +/* For compatibility reasons, the macro OPENSSL_NO_UI is currently retained */ +# if OPENSSL_API_COMPAT < 0x10200000L +# ifdef OPENSSL_NO_UI_CONSOLE +# define OPENSSL_NO_UI +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is useful when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* + * Alternatively, this function is used to duplicate the user data. + * This uses the duplicator method function. The destroy function will + * be used to free the user data in this case. + */ +int UI_dup_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); +int UI_get_result_length(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parameterised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) + +# define UI_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, l, p, newf, dupf, freef) +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +# ifndef OPENSSL_NO_UI_CONSOLE + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +# endif + +/* + * NULL method. Literally does nothing, but may serve as a placeholder + * to avoid internal default. + */ +const UI_METHOD *UI_null(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called with all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DEFINE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(const char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_data_duplicator(UI_METHOD *method, + void *(*duplicator) (UI *ui, void *ui_data), + void (*destructor)(UI *ui, void *ui_data)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data); +int (*UI_method_get_opener(const UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(const UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(const UI_METHOD *method)) + (UI *, const char *, const char *); +void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *); +void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *); +const void *UI_method_get_ex_data(const UI_METHOD *method, int idx); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean prompt + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +int UI_get_result_string_length(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); +int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); +UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/uierr.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/uierr.h new file mode 100644 index 00000000..bd68864d --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/uierr.h @@ -0,0 +1,65 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_UIERR_H +# define HEADER_UIERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_UI_strings(void); + +/* + * UI function codes. + */ +# define UI_F_CLOSE_CONSOLE 115 +# define UI_F_ECHO_CONSOLE 116 +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_NOECHO_CONSOLE 117 +# define UI_F_OPEN_CONSOLE 114 +# define UI_F_UI_CONSTRUCT_PROMPT 121 +# define UI_F_UI_CREATE_METHOD 112 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_USER_DATA 118 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_GET_RESULT_LENGTH 119 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_PROCESS 113 +# define UI_F_UI_SET_RESULT 105 +# define UI_F_UI_SET_RESULT_EX 120 + +/* + * UI reason codes. + */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_PROCESSING_ERROR 107 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_SYSASSIGN_ERROR 109 +# define UI_R_SYSDASSGN_ERROR 110 +# define UI_R_SYSQIOW_ERROR 111 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 +# define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE 108 +# define UI_R_USER_DATA_DUPLICATION_UNSUPPORTED 112 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/whrlpool.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/whrlpool.h new file mode 100644 index 00000000..20ea3503 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/whrlpool.h @@ -0,0 +1,48 @@ +/* + * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +#include + +# ifndef OPENSSL_NO_WHIRLPOOL +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509.h new file mode 100644 index 00000000..39ca0ba5 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509.h @@ -0,0 +1,1047 @@ +/* + * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# if OPENSSL_API_COMPAT < 0x10100000L +# include +# include +# include +# endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Flags for X509_get_signature_info() */ +/* Signature info is valid */ +# define X509_SIG_INFO_VALID 0x1 +/* Signature is suitable for TLS use */ +# define X509_SIG_INFO_TLS 0x2 + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +typedef struct X509_sig_st X509_SIG; + +typedef struct X509_name_entry_st X509_NAME_ENTRY; + +DEFINE_STACK_OF(X509_NAME_ENTRY) + +DEFINE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) + +typedef struct x509_attributes_st X509_ATTRIBUTE; + +DEFINE_STACK_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st X509_REQ_INFO; + +typedef struct X509_req_st X509_REQ; + +typedef struct x509_cert_aux_st X509_CERT_AUX; + +typedef struct x509_cinf_st X509_CINF; + +DEFINE_STACK_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DEFINE_STACK_OF(X509_TRUST) + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT 0 /* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC (1U << 0) +# define X509_TRUST_DYNAMIC_NAME (1U << 1) +/* No compat trust if self-signed, preempts "DO_SS" */ +# define X509_TRUST_NO_SS_COMPAT (1U << 2) +/* Compat trust if no explicit accepted trust EKUs */ +# define X509_TRUST_DO_SS_COMPAT (1U << 3) +/* Accept "anyEKU" as a wildcard trust OID */ +# define X509_TRUST_OK_ANY_EKU (1U << 4) + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional; use old X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +DEFINE_STACK_OF(X509_REVOKED) + +typedef struct X509_crl_info_st X509_CRL_INFO; + +DEFINE_STACK_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; +} X509_PKEY; + +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; +} X509_INFO; + +DEFINE_STACK_OF(X509_INFO) + +/* + * The next 2 structures and their 8 routines are used to manipulate Netscape's + * spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +#ifndef OPENSSL_NO_SCRYPT +typedef struct SCRYPT_PARAMS_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; + ASN1_INTEGER *blockSize; + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; +} SCRYPT_PARAMS; +#endif + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +const char *X509_verify_cert_error_string(long n); + +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +# endif +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +# endif +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + +# ifndef OPENSSL_NO_STDIO +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, const X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +long X509_get_pathlen(X509 *x); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, + const ASN1_OCTET_STRING **pdigest); +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, + ASN1_OCTET_STRING **pdigest); + +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +#define X509_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef) +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid, + int *secbits, uint32_t *flags); +void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, + int secbits, uint32_t flags); + +int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, + uint32_t *flags); + +void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_trusted(const X509 *x); +int X509_alias_set1(X509 *x, const unsigned char *name, int len); +int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x); +STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); + +long X509_get_version(const X509 *x); +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(const X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(const X509 *a); +const ASN1_TIME * X509_get0_notBefore(const X509 *x); +ASN1_TIME *X509_getm_notBefore(const X509 *x); +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); +const ASN1_TIME *X509_get0_notAfter(const X509 *x); +ASN1_TIME *X509_getm_notAfter(const X509 *x); +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +int X509_up_ref(X509 *x); +int X509_get_signature_type(const X509 *x); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_get_notBefore X509_getm_notBefore +# define X509_get_notAfter X509_getm_notAfter +# define X509_set_notBefore X509_set1_notBefore +# define X509_set_notAfter X509_set1_notAfter +#endif + + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf) + */ +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); +void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid); +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); + +EVP_PKEY *X509_get0_pubkey(const X509 *x); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); + +long X509_REQ_get_version(const X509_REQ *req); +int X509_REQ_set_version(X509_REQ *x, long version); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_REQ_get_signature_nid(const X509_REQ *req); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); +int X509_CRL_up_ref(X509_CRL *crl); + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +# define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate +#endif + +long X509_CRL_get_version(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)) +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)) +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_CRL_get_signature_nid(const X509_CRL *crl); +int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); + +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); +const STACK_OF(X509_EXTENSION) * +X509_REVOKED_get0_extensions(const X509_REVOKED *r); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_aux_print(BIO *out, X509 *x, int indent); +# ifndef OPENSSL_NO_STDIO +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags); +# endif + +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); + +int X509_NAME_entry_count(const X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, + const unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(const X509 *x); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(const X509_CRL *x); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, + int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, + int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + const ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) +#ifndef OPENSSL_NO_SCRYPT +DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS) +#endif + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +#ifndef OPENSSL_NO_SCRYPT +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p); +#endif + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); + +const STACK_OF(X509_ATTRIBUTE) * +PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(const X509_TRUST *xp); +char *X509_TRUST_get0_name(const X509_TRUST *xp); +int X509_TRUST_get_trust(const X509_TRUST *xp); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509_vfy.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509_vfy.h new file mode 100644 index 00000000..adb8bce7 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509_vfy.h @@ -0,0 +1,628 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +/* + * Protect against recursion, x509.h and x509_vfy.h each include the other. + */ +# ifndef HEADER_X509_H +# include +# endif + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +typedef enum { + X509_LU_NONE = 0, + X509_LU_X509, X509_LU_CRL +} X509_LOOKUP_TYPE; + +#if OPENSSL_API_COMPAT < 0x10100000L +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#endif + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_STACK_OF(X509_OBJECT) +DEFINE_STACK_OF(X509_VERIFY_PARAM) + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, + X509_STORE_CTX *ctx, X509 *x); +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, + X509 *x, X509 *issuer); +typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL **crl, X509 *x); +typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); +typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL *crl, X509 *x); +typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); +typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)(X509_STORE_CTX *ctx, + X509_NAME *nm); +typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); + + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +# define X509_V_ERR_UNNESTED_RESOURCE 46 +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +# define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +# define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +# define X509_V_ERR_EE_KEY_TOO_SMALL 66 +# define X509_V_ERR_CA_KEY_TOO_SMALL 67 +# define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +# define X509_V_ERR_NO_VALID_SCTS 71 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +/* OCSP status errors */ +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ + +/* Certificate verify flags */ + +# if OPENSSL_API_COMPAT < 0x10100000L +# define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */ +# endif +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check self-signed CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.1.0. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +/* Do not check certificate/CRL validity against current time */ +# define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + X509_LOOKUP_TYPE type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +int X509_OBJECT_up_ref_count(X509_OBJECT *a); +X509_OBJECT *X509_OBJECT_new(void); +void X509_OBJECT_free(X509_OBJECT *a); +X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); +X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a); +int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); +int X509_STORE_lock(X509_STORE *ctx); +int X509_STORE_unlock(X509_STORE *ctx); +int X509_STORE_up_ref(X509_STORE *v); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx),(func)) +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_fn verify); +X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); +void X509_STORE_set_verify_cb(X509_STORE *ctx, + X509_STORE_CTX_verify_cb verify_cb); +# define X509_STORE_set_verify_cb_func(ctx,func) \ + X509_STORE_set_verify_cb((ctx),(func)) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx); +void X509_STORE_set_get_issuer(X509_STORE *ctx, + X509_STORE_CTX_get_issuer_fn get_issuer); +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx); +void X509_STORE_set_check_issued(X509_STORE *ctx, + X509_STORE_CTX_check_issued_fn check_issued); +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx); +void X509_STORE_set_check_revocation(X509_STORE *ctx, + X509_STORE_CTX_check_revocation_fn check_revocation); +X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx); +void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl); +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx); +void X509_STORE_set_check_crl(X509_STORE *ctx, + X509_STORE_CTX_check_crl_fn check_crl); +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx); +void X509_STORE_set_cert_crl(X509_STORE *ctx, + X509_STORE_CTX_cert_crl_fn cert_crl); +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx); +void X509_STORE_set_check_policy(X509_STORE *ctx, + X509_STORE_CTX_check_policy_fn check_policy); +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx); +void X509_STORE_set_lookup_certs(X509_STORE *ctx, + X509_STORE_CTX_lookup_certs_fn lookup_certs); +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx); +void X509_STORE_set_lookup_crls(X509_STORE *ctx, + X509_STORE_CTX_lookup_crls_fn lookup_crls); +#define X509_STORE_set_lookup_crls_cb(ctx, func) \ + X509_STORE_set_lookup_crls((ctx), (func)) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx); +void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn cleanup); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx); + +#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) +int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); +void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); +STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_cb verify); +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx); +X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx); +X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx); + +#if OPENSSL_API_COMPAT < 0x10100000L +# define X509_STORE_CTX_get_chain X509_STORE_CTX_get0_chain +# define X509_STORE_CTX_set_chain X509_STORE_CTX_set0_untrusted +# define X509_STORE_CTX_trusted_stack X509_STORE_CTX_set0_trusted_stack +# define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject +# define X509_STORE_get1_certs X509_STORE_CTX_get1_certs +# define X509_STORE_get1_crls X509_STORE_CTX_get1_crls +/* the following macro is misspelled; use X509_STORE_get1_certs instead */ +# define X509_STORE_get1_cert X509_STORE_CTX_get1_certs +/* the following macro is misspelled; use X509_STORE_get1_crls instead */ +# define X509_STORE_get1_crl X509_STORE_CTX_get1_crls +#endif + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + X509_NAME *name, + ASN1_INTEGER *serial, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_fingerprint_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const unsigned char* bytes, + int len, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_alias_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const char *str, + int len, + X509_OBJECT *ret); + +X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name); +void X509_LOOKUP_meth_free(X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_new_item(X509_LOOKUP_METHOD *method, + int (*new_item) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_new_item(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_free(X509_LOOKUP_METHOD *method, + void (*free_fn) (X509_LOOKUP *ctx)); +void (*X509_LOOKUP_meth_get_free(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_init(X509_LOOKUP_METHOD *method, + int (*init) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_init(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_shutdown(X509_LOOKUP_METHOD *method, + int (*shutdown) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_shutdown(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_ctrl(X509_LOOKUP_METHOD *method, + X509_LOOKUP_ctrl_fn ctrl_fn); +X509_LOOKUP_ctrl_fn X509_LOOKUP_meth_get_ctrl(const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_subject(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_subject_fn fn); +X509_LOOKUP_get_by_subject_fn X509_LOOKUP_meth_get_get_by_subject( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_issuer_serial(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_issuer_serial_fn fn); +X509_LOOKUP_get_by_issuer_serial_fn X509_LOOKUP_meth_get_get_by_issuer_serial( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_fingerprint(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_fingerprint_fn fn); +X509_LOOKUP_get_by_fingerprint_fn X509_LOOKUP_meth_get_get_by_fingerprint( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_alias(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_alias_fn fn); +X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( + const X509_LOOKUP_METHOD *method); + + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + X509_NAME *name); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + X509_NAME *name, ASN1_INTEGER *serial, + X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const char *str, int len, X509_OBJECT *ret); +int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data); +void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); +X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane); +#define DANE_FLAG_NO_DANE_EE_NAMECHECKS (1L << 0) + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); +time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, + uint32_t flags); +uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +/* Non positive return values are errors */ +#define X509_PCY_TREE_FAILURE -2 /* Failure to satisfy explicit policy */ +#define X509_PCY_TREE_INVALID -1 /* Inconsistent or invalid extensions */ +#define X509_PCY_TREE_INTERNAL 0 /* Internal error, most likely malloc */ + +/* + * Positive return values form a bit mask, all but the first are internal to + * the library and don't appear in results from X509_policy_check(). + */ +#define X509_PCY_TREE_VALID 1 /* The policy tree is valid */ +#define X509_PCY_TREE_EMPTY 2 /* The policy tree is empty */ +#define X509_PCY_TREE_EXPLICIT 4 /* Explicit policy required */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509err.h new file mode 100644 index 00000000..02738531 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509err.h @@ -0,0 +1,130 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509ERR_H +# define HEADER_X509ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509_strings(void); + +/* + * X509 function codes. + */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BUILD_CHAIN 106 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_NAME_CONSTRAINTS 149 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DANE_I2D 107 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_I2D_X509_AUX 151 +# define X509_F_LOOKUP_CERTS_SK 152 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_NEW_DIR 153 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_DIFF 105 +# define X509_F_X509_CRL_METHOD_NEW 154 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_LOOKUP_METH_NEW 160 +# define X509_F_X509_LOOKUP_NEW 155 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_CANON 156 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_OBJECT_NEW 150 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_DECODE 148 +# define X509_F_X509_PUBKEY_GET0 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_ADD_LOOKUP 157 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_STORE_NEW 158 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 +# define X509_F_X509_VERIFY_PARAM_NEW 159 + +/* + * X509 reason codes. + */ +# define X509_R_AKID_MISMATCH 110 +# define X509_R_BAD_SELECTOR 133 +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_CRL_ALREADY_DELTA 127 +# define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_IDP_MISMATCH 128 +# define X509_R_INVALID_ATTRIBUTES 138 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_ISSUER_MISMATCH 129 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NEWER_CRL_NOT_NEWER 132 +# define X509_R_NO_CERTIFICATE_FOUND 135 +# define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_NO_CRL_FOUND 137 +# define X509_R_NO_CRL_NUMBER 130 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3.h new file mode 100644 index 00000000..6c6eca38 --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3.h @@ -0,0 +1,937 @@ +/* + * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, const char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 +# define X509V3_CTX_REPLACE 0x2 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; + +DEFINE_STACK_OF(GENERAL_NAME) +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; +DEFINE_STACK_OF(GENERAL_NAMES) + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DEFINE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DEFINE_STACK_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DEFINE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DEFINE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DEFINE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, \ + "section:", (val)->section, \ + ",name:", (val)->name, ",value:", (val)->value) + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +/* EXFLAG_SET is set to indicate that some values have been precomputed */ +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +/* Self signed */ +# define EXFLAG_SS 0x2000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DEFINE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, const char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); +char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); +int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *name, const char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +#if OPENSSL_API_COMPAT < 0x10100000L +/* The new declarations are in crypto.h, but the old ones were here. */ +# define hex_to_string OPENSSL_buf2hexstr +# define string_to_hex OPENSSL_hexstr2buf +#endif + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +#ifndef OPENSSL_NO_STDIO +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); +#endif +int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +void X509_set_proxy_flag(X509 *x); +void X509_set_proxy_pathlen(X509 *x, long l); +long X509_get_proxy_pathlen(X509 *x); + +uint32_t X509_get_extension_flags(X509 *x); +uint32_t X509_get_key_usage(X509 *x); +uint32_t X509_get_extended_key_usage(X509 *x); +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x); +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x); +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x); +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x); + +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(const char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg); +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(const X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* Never check the subject CN */ +# define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +#ifndef OPENSSL_NO_RFC3779 +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DEFINE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DEFINE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DEFINE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); +int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int X509v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int X509v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int X509v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned X509v3_addr_get_afi(const IPAddressFamily *f); +int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int X509v3_asid_is_canonical(ASIdentifiers *asid); +int X509v3_addr_is_canonical(IPAddrBlocks *addr); +int X509v3_asid_canonize(ASIdentifiers *asid); +int X509v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int X509v3_asid_inherits(ASIdentifiers *asid); +int X509v3_addr_inherits(IPAddrBlocks *addr); +int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int X509v3_asid_validate_path(X509_STORE_CTX *); +int X509v3_addr_validate_path(X509_STORE_CTX *); +int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, + int allow_inheritance); +int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +#endif /* OPENSSL_NO_RFC3779 */ + +DEFINE_STACK_OF(ASN1_STRING) + +/* + * Admission Syntax + */ +typedef struct NamingAuthority_st NAMING_AUTHORITY; +typedef struct ProfessionInfo_st PROFESSION_INFO; +typedef struct Admissions_st ADMISSIONS; +typedef struct AdmissionSyntax_st ADMISSION_SYNTAX; +DECLARE_ASN1_FUNCTIONS(NAMING_AUTHORITY) +DECLARE_ASN1_FUNCTIONS(PROFESSION_INFO) +DECLARE_ASN1_FUNCTIONS(ADMISSIONS) +DECLARE_ASN1_FUNCTIONS(ADMISSION_SYNTAX) +DEFINE_STACK_OF(ADMISSIONS) +DEFINE_STACK_OF(PROFESSION_INFO) +typedef STACK_OF(PROFESSION_INFO) PROFESSION_INFOS; + +const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId( + const NAMING_AUTHORITY *n); +const ASN1_IA5STRING *NAMING_AUTHORITY_get0_authorityURL( + const NAMING_AUTHORITY *n); +const ASN1_STRING *NAMING_AUTHORITY_get0_authorityText( + const NAMING_AUTHORITY *n); +void NAMING_AUTHORITY_set0_authorityId(NAMING_AUTHORITY *n, + ASN1_OBJECT* namingAuthorityId); +void NAMING_AUTHORITY_set0_authorityURL(NAMING_AUTHORITY *n, + ASN1_IA5STRING* namingAuthorityUrl); +void NAMING_AUTHORITY_set0_authorityText(NAMING_AUTHORITY *n, + ASN1_STRING* namingAuthorityText); + +const GENERAL_NAME *ADMISSION_SYNTAX_get0_admissionAuthority( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_admissionAuthority( + ADMISSION_SYNTAX *as, GENERAL_NAME *aa); +const STACK_OF(ADMISSIONS) *ADMISSION_SYNTAX_get0_contentsOfAdmissions( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_contentsOfAdmissions( + ADMISSION_SYNTAX *as, STACK_OF(ADMISSIONS) *a); +const GENERAL_NAME *ADMISSIONS_get0_admissionAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_admissionAuthority(ADMISSIONS *a, GENERAL_NAME *aa); +const NAMING_AUTHORITY *ADMISSIONS_get0_namingAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_namingAuthority(ADMISSIONS *a, NAMING_AUTHORITY *na); +const PROFESSION_INFOS *ADMISSIONS_get0_professionInfos(const ADMISSIONS *a); +void ADMISSIONS_set0_professionInfos(ADMISSIONS *a, PROFESSION_INFOS *pi); +const ASN1_OCTET_STRING *PROFESSION_INFO_get0_addProfessionInfo( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_addProfessionInfo( + PROFESSION_INFO *pi, ASN1_OCTET_STRING *aos); +const NAMING_AUTHORITY *PROFESSION_INFO_get0_namingAuthority( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_namingAuthority( + PROFESSION_INFO *pi, NAMING_AUTHORITY *na); +const STACK_OF(ASN1_STRING) *PROFESSION_INFO_get0_professionItems( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionItems( + PROFESSION_INFO *pi, STACK_OF(ASN1_STRING) *as); +const STACK_OF(ASN1_OBJECT) *PROFESSION_INFO_get0_professionOIDs( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionOIDs( + PROFESSION_INFO *pi, STACK_OF(ASN1_OBJECT) *po); +const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_registrationNumber( + PROFESSION_INFO *pi, ASN1_PRINTABLESTRING *rn); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3err.h b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3err.h new file mode 100644 index 00000000..5f25442f --- /dev/null +++ b/Hin2n/src/main/jniLibs/x86_64/include/openssl/x509v3err.h @@ -0,0 +1,162 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_X509V3ERR_H +# define HEADER_X509V3ERR_H + +# ifndef HEADER_SYMHACKS_H +# include +# endif + +# ifdef __cplusplus +extern "C" +# endif +int ERR_load_X509V3_strings(void); + +/* + * X509V3 function codes. + */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ADDR_VALIDATE_PATH_INTERNAL 166 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_BIGNUM_TO_STRING 167 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_LEVEL_ADD_NODE 168 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_CACHE_CREATE 169 +# define X509V3_F_POLICY_CACHE_NEW 170 +# define X509V3_F_POLICY_DATA_NEW 171 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_TREE_INIT 172 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V2I_TLS_FEATURE 165 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* + * X509V3 reason codes. + */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#endif diff --git a/Hin2n/src/main/jniLibs/x86_64/libcrypto.so b/Hin2n/src/main/jniLibs/x86_64/libcrypto.so new file mode 100644 index 0000000000000000000000000000000000000000..314e940e142695578be0150642199edfe409654b GIT binary patch literal 3448344 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 )Kj2y1 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

YLA;u}v$%=7Gze=U+ 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 z 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�g1OFbIeZx`dlft+>t=gFEj;2k4KqL4R}4t&jSzXE z$fUF7oEgjBh$C>+s6@FDk^u`gvkQchrt&0v`e~-zJ2iX&!^z(K)*#v!PdcG5zF%S} zbHUphwy~liR#Bfr4q634qSV5xyze zU<0{Q7rSzh)k<2IF&Qkt+rghm^`a}_>yYHT?&N>K5w3sDq@WTvx&!Hf&zEu7Z5-aH zN`22vXw^UTYp;@_3O0bx?j|dOYE%F)50<_D*qZf2JbOU8f}AA&<;sRkbYmpPt`DAa zVv&^SQT2xv2J37@lRpE5F6fKVuwEYTFIajGf0l{*A?c>ohxWX>33}7>Ozz)h#FMmT zY4DUVz%_Opnu}wfUhrmQcxHAbr%k{JXs^ut%#U`Ewl2zIvo*MV(*pF){Qct4!1@l5 z**LcE&B^bJnr6{*EAcA5%yd`0HpMdzhcx>M8L}|STJnAOqL0J%^MSuB@Wph2MSicY zr6mQfR6Ikvs?vzXR%(FTb(igZv+cl&b0E`EAIxU%w*4h`4PX!#9cHX{?a{sS!5)+G zL+%-39l>Rnoq}LKeAQg&=1Z8Pk!;evQw)m+j#FqFL4z=_D1qqla08c1!QPSE!(3tqF{}Y>X8HcZ zdIi;Y)u^)fUA~f;V)C#gIW+*~$a(d8?LiZhJ^HvwowcVdCnG|n#JGb;8OuH70u${4 zJV8#*M1J8Xk(q7#t+O+AzlQG0mZ~M@FOc?q9e^@vqv9u?$#LbE z@!1f-cFRDnz-KXu!U)6iSb6Kyo$scxc?dB4Z6c>O2H$>Sv(Rkqe#3ig&ihUwkZFwt zD*1KeW+iudOl?>?(i(R0rHnVMsAUxVh7Dy=qAP?~)J}RcNh3n$<7I1C)~YeLLlv)S z!~V;d{?4TPzDJ*s+K06hEipm+>0)L6&hhVA>XD}QO#B6UM=;Di{SOOaBx9jgSv6Zb zZ}Fid>?A@{jTBod0eAU(PJ`UMoyM|tUi^D(+QS1WdZ#*Z0+Gr*@D1Ko+y;0`%GJxu zcC>8=SjyoZqc>k-UE%!}^cwUa^_ujxEi`?x#l@DJ>rCsnLtGUaH+N1DFqtl|LtSUu zhbbL${h5Wp!7J~w_Ck|;ONo~7agKcQtsWr!J|9Y-ok#Nomnv{Vr}*Fur0cV`ME&Z} z;K9KupL6+MP@Q2KN09(NCVZWioL|8+zORFYa^zc*;PC{n*0!S&of>tyCS~W+e`S-FX zW{s>mFP9}d!RQclcU1UbN-KwK?@-JeQWHj`G%Bmn6+W1d!NoZeRghWV<=tWPbt0c3 z_7~(!i5*3@$WRBWy|8$>O0adkiG@YfpZziM|CZ`9 z9g1nb4cu|0%zy#XVo8x>iB`jR2Id+>#Ct=rC-RJXESAYT$WX?_&wT#f$HF5>ost`! z$R+tRJa`66_h3X?N06mSjV!F7y9c-jv_ShhkN;^cHXfa%Wbey?mOi7hv@bLI1fo}V{yd{IEk_6`$YWo0ivQ1kJK zL~c@cspNhay=R2cV-u1S$(O&~Srjc(YA&AC9!FcYEUiTLN%Ktt7AK$UT&W3eXm;6^gk8utO)h zINUn!6+|=l^vAJU&|)5s-$UxQqjsGIiD5EE4?3c?3%xIlkpXJkamibhKXkN8*#USf z;%aAJ_D#7=iIuObzx=8}B5NlH+?#ugq}^L$gZb*;wEUy;`gd7dODqNNLeReOk#z=f zf9RjbPVyqkbDYQ?{QJ5GX23nHk&xdKYy2?y}I-(uWk{J zJQ4T3XsiAv_1?E+@Z-?}`m^AL2*VnkEfhd|Zdx1*9Fi~tR-1#P7NIu!0rN<0?%B@= z5e_)vONCh2>P2~-)YQu^!4X04!YMlJvE%IZ7B-Cp)K+5-GEG^JY7L*#%u)7jF^LJ} z-H#7?5i)GNn`)xPT)vud_9K`3VD-;DSv`L(p|T;C2D&8L7|Y~@GgQMMB5oKdEHQ}S zWG`}3cib15DkzkR?uA;vdq!fQb^!5E#x?W{rL#jh75~Y+?^7BK6EbnP#jy8d;J-1< zl&MaAnisHJMPJCXWY7{~0B(;clO;#l)^)fGSx)xHyppXYV%;Kby~DYV16a1mC%XIA zu+0En#9|OP6KD*5Kr=0jTT$50Ub~E*X^+d;*9gY=M?;L;06x14g%K4aR-=BXIe_o!t8q8m8w_aBGzqMINC1dLP)3&OIz=u^Eoa1cj zIku8q6FZfH=LQGwXi`EhkqC2XbPfr}lAc+0Uc;MG54nT0bx9=9vrtEJU6v78L!|Rj z$BmqHXPg)CpFPt4%^3ej;wT_9I03|Yyub6}fZ~>f3W(6X7X z6}~nh9Vz(2z-@%v&!2e94*Fc0TT|EVzMw_%n%0&FpN{O@wwhVE#iuc!;Nto3MQzhd zmG0c}p7cDM|7-~JOyg@0HlsO_)Z2(1y}u32xRxGLC4S4l_vOKuoq;G6vPT8Wo$7j= z-EhaqXdMK{)bOsTo68dzm@CW&#)kfOyvKi)nkrB?lY47pt4+}-+(;R|N8s9+(VZj$ zqJgP|Wi{xBGl@DF-7z%@a$LxeAK@EXE2ZKd{?e0|Yi;b}za@g+r3$_D*7lrVpLbNt zSrn1;v95;O%}G{T&L%&3H4`!(Ll0E~p^3t8Ot^E}&z)7*#5(R7IG2QiYGCr_RUWlh z`|^-sa9`qlWbLD&(Yo13vvX(jkC95p=ZSjs`m`LrlSU2yC zQ&u1WFNvY9RYIfd~x`$&*#~xD1i(n(v z#E53sBBd6+IyVP`LTjC)`YyDr2QQ|80lDM%06zCV970L#Ul%rbCeJ;aPvpd(@E~$) zL*I7Kwx~M$RVNqBIblRsow&M>AmCpDZVC#S)8!H3W4p}@f0w8ds_ZjlCdBt4i&)DPS@=*aJ=U@Rcm&@E&2bgIXn>2&aF*9k zs>3jU-Wrrk{pckT0C_Up>m5DtpFcXi+_q($<~@0&HYX_4I~~-+plR>kYoZ6qxHGk% z-!9vi9f0ESdWYd@f=b-J4Ou-=SR8CulTPkyFJpvsGqZWOHf_`9qP&~qGibDi1^o9D zIf*wJN55wG6;n9eRT#6AV#RX)VUUDQZ9&l!as*L$tFykA$w2U7Zhu4!9gAZPF>TN; zQqj6UL5kvrKLCQuc3Nnoyv+;u2Mu9W#H5@dVD@k94x!G6oAZ4bvMu74UnRLjOrr?v z*~W}^lAnc!`%ld^bI?$-UZIb*BrMNGI91=e!}(I5YW9h<&Zp$LwIYv(MiUMR`2MfL z`nZn9;Zr`2$*w5tO(r4dO!?F+Q)hGOW&8b|qeTg^=o?!*uZt_3c%LF&@kwt!AN1Ig z2Y-+#=!|D)=%)OF&YH%F%pK6KQDhL(GW;3v_p}?*QVg*CJ!51=q@JysR1=Q{H!}NB zzoVJFO-)mxC6)}M{-VOs@wi1A{4k}VA?$WE*IS+{oUBWSHBNhK*Opo1*@6-7%|!q` z@dpyQB<>nPS~QoJE=6Y043(c$u;mtY(EZo3FUOo?mLz89Vcl-a%tP=^s!ZM&tjAS) z^|296;)NPSy_|RFfnel@4+D5Z_8^WjU`qWD40Q^KWO~elj#N(L&$>AU4-pJ@j6pq! z74fl5s!cxsY5ZTc=QAfKF$I#mNAX6K-y+vEBwL7lYy9SAPef{{Zt=rfMjCn?(ebh! zMp_Yap=fNC-DgLbMmo{!@{%*h%_il|oTfqCmAmj*$U1 zaQgqZQ{&X}9;W#xh zP-Vq8i~eyMGn;E67TFwgk2t#vU4pF{Vz(Sy;KEjZepYdjzrYR<$;4rXZwKeu1iZRi z2z%CQsgqt=1i7D@B;5Pz!6tRL3*GEz(?kuG*1(+?nK_jh4J4lF4mM$CM7gxA+piZm&(p(k@SP0IeAO=ENw!+&_8lj<5eZ%MDfH1ZEmSy z4v2@{sAxykm22DSFT95Yuu7eE+?M{5Y|EN%d58-wOiBHGj_}ZOj2?%}61deIp_#Lsx z1&|g4;(LdAVLVTao^&z={8M-eoxCkK*;JI1Pkk604uG_s&VuIXXkHfBni8p7cz?b% zm*Nk%0-jq8^aE4q1nxDGmVBctW7aev%tl{ZRIHY=a_?1Qu#tNoT^e>blSGG$_v4{2AH+{(gHh2 zZ{DGaUKoYc#I_C}ljb=DTl&NOZC|Dd2V!@K37XN$A4}>P)q$rKhSl1*q94#!yH_pEk_^mqdQUE zcd@G`uh4m9)sc8;wJP{?AtQ3BXlE-KW*>~OJG<{#gVCnj5uCC*ZIQ5-C!SG|;)s#( z7~Ir<%CMN@hK^*lI6Rm|F`b2ryn1777f-R~d;iLv`;#YHYNj<`rRD2c+=rjd9qfEy z_1pW?Tv>cqGV3NHJ5*c!HOa(A1_){6?dgF7L@s{{-}cIsI6Nc~I|m%GTVQ-*N@}`6 zr3TIA;?zk=i54k zEpFQuB4h%Tc-5b@&_$cB5uL`{a840lSyxOM-FFmn!guVn2qL_k^=RAIw8fRTGUY;J z{KUABQsbH;q-!|5>;ck3+FkqBkK>?=+*2cX>Gx>rg$tS=(bg)0R_vB-i1y`dohM#R zk+D3@1OC%@e5QV+A5{Jff$HP0(kqp8(*ccE?;m+?GZ7CV#-XEmZS2RX)zDf(!zD7W zIB@?PU}?OGW;_6Wbm&FLn*}AmZwT_TWl8#YV3CHV4utk>9SCqBcC6P$hBCD=+5qN& ziknhnZ;=5$Z+$ITNDkdo`O5XvjZi;nt-L`c@JX>;7^GoVzD3OOO9|RD3DGBeDzOk_i zhV!Y#Bd!@s&s|YD`0&JPF!qQZfCY z4`}+Q{k@#4ew~EMcDS8!GABGscH-;m+z9gHS2JdC8(UU0*jtPZ{5P2Ow8P8~@SLZp z8)Tc1Ip5zsBq(&Th6e(~l%<0LMQlM+x@Z?%UL_M8aWog*W{(Yk7gbY-%fuf9P2DP}O3z0ULiDK6V=tUK<KK zQZ%_~-pz;r93WT6uZEgYBI(_z&NaQ2I0WMjmsN$~!3cI~Fv*s|^~RwC9u_nFZ7+t8H-7wnD}G7#69cjUvnH9DNXEK~5s^*!9q} z+MnyqL2eC(qbtBhaUYw-a%yJ_uxw43-PZqnjV|8G#re)Qc^qWd^}C@icaQEcvXvXL zC9LQ!sb%-Zw-`G7Ot8*oiOdS`Oq3@C5KKc?$+OEm`9GwgahaT{SmU7=+rnFdyxFKO zhO|Xe-~l50`|EI#6^D|?WZ$nD0xh)W%3JC@@YpIevto~EMo_u1 zRWSb~TYHct@r0T+UYRcYyqkV$&)SFMmTlA`#TSFgrdl{&K)Yp+mQ|;4wjBtZPy-w+ezIL~$tjo~*L646&{H|Lj!Eq=xuzM}db)jW64^hb&87 zDMSh&%~$9|u*O&+eSL6zb(Zz{A%(6Kx3Xsgk3@%!)x2Isyr~nx(;|`C&b)a-W(S@} zLS#IBcJwWHC-MxoMAUKQu3=ssN(jZjHWDHB>eEk}ycK@+D`KlOEZ=B0Prq3YPiLNU zP4m~AW`p=0dr2|4!HUE?a0XFbk~=a8AP96qZxtfTD@e#1QvC0EG#3)TF=$+nlyk(7 zQliRDJR6TH5YmJV?3*pY-(=74Mx}VI>pw&B&U1Ui9%3IAhBG%O*6eEb?brdUf*=-V zYv>snfjWcRwVBdUq9b65OYplo47>G2nslyd>osRP-V;Z~Sm4mjOg$_JxwJ|=7k+qF2GRa<)Qg5k+taH3-W}sp7TdIOWtO&mlSanJK z?Hq~K-yG5qzW8T*wTzJ_r~g)b8eKM%-ZEtb#Wf@X&2%OZUi`p9vAdl3{84U_2F0&h zZbKa+uDn10|7&)*(^dWb!bmatA~GY%{l`*k`x)et5dVpHNhKwj+txg%Eb$y+p@lBV z3xV8xRMM>?d?lTaML+7BvDPQPA1q|1fdmw_<_GQg;L?Ud9olNupNbA50g~lO8;o$T zHpv42`b#VB5A$GQYL0~ltv6=Sbkjd)cTCRv-iUE6OVv4MYijjS(#fdY;ZL$&5Byk6 z@^fqMov)q+2W2yhSPiKu$1bnMVq4yBv%=G^&vIPaHADl|8H|QS;eO$hUtox_)ungt z#9*p %wpzxBLHFdgeW@lLPFl{n%2L_aqon7j-xIGghJuJ3bGxcnPHZ^@{ftX9t? z9vONG@vYawjf%fSUjvwg40Rs4aSHTl#Kv6=dw<2j8N6?t=b%Zry^f@bSPyHTPJEz* z&_7)i-Y2UO0fWQLjo>r>DM=2abGtw!t)=wJmk&w5!iL@$&Y@?<36Cg^M?@HgxJx!b zu??i+rRWA9j>xVjM^pE)4vqU#dN#ZsCPU5J{3VVA#yp0@UpVF)~Va3FK5!emxeqsEgEQ2Iv2$ntd++Rc)7lu?cUGD0hsUZ*7B>Wo>H$bz zdH!=CtuXX+>*bD36=bmve2);=?1TuI22x*^z-|uNxc5Z_cv>=Fa8ouJULQ>EvVXGFix@Pa`Hx#E?vj zK8Tj~P>P{A=ea50AOt@uE5^U6A3kl6eJawUxCQzvVmo%3aaJf*T%#w!@__gcMxPG`c>1m;RV@h+YlC79;(ALJhr|gN@{2$vew(v3f{TuL2KWI%@1C++myg)>N8>x)M(i*27R|J0JB)Un{hr^oy0vo-REdnUOE9l zSAvZjJf1v97cn8LwwZjVqOc6|i1@;@qexuyBo~>HK9R?U*2_7ZdD>nc{M2K|m9^be z?N6)=xMOP;wO@W|{Ge`R$??#-2zPU(EU6J+bSRd3mWG;GdGld%P-dzuoAa9QB-8Jt zFEV&By(hzzGZj6s+9@${^3{R$CxG-q3@*nP=Qf4B%|NOToi;6cWm@#+bbso^zdNw) zjdKkc#HdCoSKi>TTN-b57O0E4Faq(^Gb<4c^Tsk_`~TRT5?OTxzge_L8z^daXFK{j zy}@@nmnnFFvk3a%>ULxIj_wrYO*!7h_z zVkjao($Z}0_%>($Mw&&th02})4Zl$AA$o^WSb__bdQ%Ul6a+A$rl}!7x*R_MJd}3s zPJ&Qfx;*&o{M(?w^R$ylfm8X{P4Y-$L3Cl=3H#(t)*@5$C6hgbb3|8!%W?D2^1i9X zHXf#n7}9rg-vY+hr`Ed*ykU<5sXDr$w$N_vg^=`^f^M$XCB};#!0DnL3oC=s&hYU^ z#5bcW-IA1(#|(h_j-b9B6_ZOIbPC@1^9+I$eGeSmf*JqH=G}x~8ItegZuv!W+1DD! zpx!CIjhr!?xq^FfIO@|Rwhl*4Es}L+)Rj9_>}HQfr65KRlT0$y zC#?G!O&=|+?(Lh(=!QVJnrE9EA>9nb{*Z8e7I0Z({PFt9@*p&{i;OZlGi_l?{_$5# zHf4P}$K_Rb=tGl?=Wyw37nN5hHdA1~&TOL_{LKk~bA0?J!~V1WDw+T(K-Ryria;b{ zp&S3VUi^F{l5T~}lf;X`=K}EoC&!T>bgL6aE59JboaiO0!hSQ5b}^*@$6o?{L!Z9V z+~aR zj2J+G=G-nUcIZ=XnnL(a&Tc{46tPG#O>E-Z7jr>dQMS)hL^B#^q|AE68;2 z=8p2ZUeG5AD3EcTEYHq@i2}3TJ~a&sDK6XncezXcp8X4CkhxpC2qE@@cj6|}R^9&s zg$eLWwXvZrigi|Zk^Y5Jqhc$=K+&9xYE-=K2(VnQ6QD;P^5{GVAm^vNt{kZsxGD?b zV}IfZWviOF`Q4-2r*trTaw!Zm3C)P5sS2ML~UEBcmzN7^ATpkv7H zw4CAd3SuXf{dbSi_#Avd9LNQggu-qcPTQE7P1Hxi<%u(XfIUw?L2*zL$EJ8n5COW> zz94sYpmZoPa6^=JrdiP5-3u%`kUbLC;|Re~dvR-}=_3XQ4wSc>YzC}^SuIX^plOWe zl1i2J%$?a!SR}|=2q;fXitA{{F4J0u zws89s8#4l|C!1N7!9;rlEC{_|#1DoV0nLEPMOWgYJ|>_YsE0G|*7Fc8mHQi$GD`BH zaB^r{hD%AxUFJaXdaUuXk>5>EC+-h+yQ-e~(-eY@WlKUATHlGR&VLa85;JkUL}Zp+M_9`!@G+1-JKo;=rq%U_dJtCwC1dFcmj zt7|&X3bV&e5$+2Y^RapqX z(Y2L@)qFAc=WyD+A}9>Zj-etG;}L~&4bs~y|_40)y;he8tezww*qft_IK z$xqS%m4%7h7qlPcGXr&;-n;kykqU!RTv%U}$bIGvQ0rqy)DCl+W(}*sA>yDU^GJte zlVdw%kzzb;q1u8ONmaay_o)DHPB=Dy;e!`?P=A-+BV#n^Do{nTjcBWpX59;IwYC~F zDH6A2F7s{*FExDr4izX6(>Z(2P($D+f(!@2&5ArK@BYbv(=;IaDL0>RA(nD2Nkz+I zzmW2cCPOa#GoSeaGVtAAZ3i$rwJ&81&-fv`d(V;Wp0rOfPzP`?rR)=+bww(1BRrlf zu=_BtS5-CTap!k@7B$)$a8?t0vh4OnE+G7T-x*!#pT5yp$50y&MB~!x3M{`~$(g~c zPW~|!uCTgRk|hJjRO}yYNG_`uhyf@BsQrfzbV{CJ{6?SLk$+~oL!m?}HZ<6@m5V*R zSSh{7&`TbmkUU6pGAS5)n6<~Jp=z9`e!!~g#)CP(=G5Sp9vB#pEA|=%eA82fmPGjr z>zJwOp_ zLs0Il?kD^U0uQk+bDlx21^YvZ(I~(fDykFz_Z;wXGNFfveshp_5QH&i2{Tb=UU}Pn zqv#o!vH;QA^^VK_YLX!^B1-pJ988;UNs7X^tI#TuKXV%GoMoi}uMnw1tBlrr;Ko8Y z$O_kXIQmyB>#9>cs0U|?7~8aE5XHe_$DPo!`@!OkJJM?=67Ao^wtceIn*)84+CwrB z@$j-QnRC8?d!SYLs3)Hv&L@-Y_uiXw$CI0B}ThtNjXv8J+(|!PK(-rPjSQ>6~1C zu#_d}ZZxkTQ=T^uO08wQ<1ve1CP;iH5^D@`@l2I*`DV#c6`~3algG}ns3X0GiCGmN zhAu_% z3klBq;l&JkTPn-@?I+2qHB8tbN!}poCf>9nwx9-#^WEpKi`7ljTjl1#?H`3z=avSR z7FIdYUvMH{vIGN^V5p+7VfaIDfysOhf)WzXmP)n?5@HwmjvnVU$KmmMCA}&!rSwxF z>&>s@nqDIS*MwZ1Z-Y#X^wS6ffr6k?)P1x)H-{>6wNv`bM_Y(j&6XGPZSB@0HD z?90~GUJ=}A&d@KR>OgpD(muS!F&;CfsCJl^fb}m&7h=O;lM~cR1(zc9l8ZZ_@SfRA z_Vh%-7jqm?MM*{&vk8zDzQ)CLOj%xSU^W^u5pY;7BG8yPv4r8#1b%8vQb(X$WeZhB zD<1ksrK!M3@Y)%aHZml9QzgTT3Hbij@`e>^&vgpx;iQZeZYN z5gT>yaPYgU&Ta7ab@5X3wDvh@ueQYBj)Ym6sQKMfupkw}dBaKCw$atw@K1)2_s2AjYS>H$2r^&{oGXh-Dqx6MnXf5!qm^#>nmt-+RQ? zAsC7W!Tu*oB$Wxn6?7j6V1Uhn3*Y~a_$`EG9PDu00jU|&ShFFBDYZi0?pE${hC*&5 zl9jVtKyh#V7Bd*p_koVRTig2iV%Y*(3|<{@Bokm8zfJD_4r13e2XxWC5&(?!!@}bP znnYDJr=8-S#5Smr^xiC1mk@AAUn*#i!qABS*d=jc-G;kYB-)RZhH{@MkGqOAy-V4d zwdxS-V9|s|j-ngY8uZ989OdAvN>3#dMT=NwrI*n90l$6}U4af^s6L2ER^Abcx?oM@ zZF+iwZr*UI8T=PsBoyQ;S3n^FSH?5gKXN`cJAri*n=Ym1h`S(YYSnevaA|*jzxMl4 ztf`>Z5*_II9zpcnFc^%EVA zCk643C$8>v1MdW*TKb*QM_zCIE10c+<9z_z^%XZ^(OMuVo>GZ;DQ6xfc#i2Bgi&yE zGOQdYeN!0t^$_&8ep{i)lOy(lZ#8tpYcWE?THM=`^{@2XtYF})#*Uhh{y2+J?gC!dCr4U3z2Hf=EGJ8mzJlh0sg#Tu^l;9DLbbG zphcS)N3D(B*|^n6&<(7=!Y)01^*XCGuhV-VE&QTy?G06Ck^uCd6S>tNhd!He$NLv; zmZWo~PO{Q-3a8NwH)&_G%EjU|A)jWy1`7q}Mv&efwn*vwSte$eQ2R5kbWCSqbH6HvOla=4NGei+h9hui^qBe8FnYcey}C@2p_2sB=+Cf+`$2O(?sb=m>)qV@Tb+%I)!k>=thT$i`i1H!MD( zhk6A{@K(1fn2)rk09AIVL>y&k&iYb90$z6E3sftmyV9T*#V?XinKWV=Y{6U&i!8=h zI?q9pe`Xu~VQF43mlvS*3&#~)l3|r#O|&3AQrjN~Hye=zdk=4o7Wqi__k0WHudKms zY1pZRPzr`6#EQD-32*#Xp3+ER&|8dxU#?Z$UPEiF5p)s2Z1pFlEHotjUIf*Y4Scq6 zH402DnjOaaxX640ivGsqV&Elx1NFb)u;9&%GgOgr1$g&ebQuf|IgDiIH!B)9PE^h2jqz__cz7*J_ zP`uc*D@N6ta90_r77H90XevQ?9RAenjP&2Yyg>u5X6OTO&qchp8>A$P>TMeF!X!-4 z8WjgrXnR}QebUKd_V3JyHA0pyY3&D#PsNml4Gm4mJm+{7Xed+vRS-^lTAA#%)xb!j zRGKIhRh>(}ch~z^rd6Sv9Z7^5sMl^700~TCFe{nVOTqxXA<>xHp})j_$W2p!yfoZ5 zboO6L*P(tLxR$|a2-2p2lPJ$PZoSLn3C&jhwxtC^e&TZM_jgaE^=Rr9yiz>0{rRPO z3Fh#WZ)g98D?=?VW9iMLuW;n;$X-8+4t*1ZF%qNt5d^gB&wPJxKfyVo3)8Qt z8CQlf&TWE~{9(`xnW8*Xd6@E;#X5nE{r@VXVgi8E~1KE#&3mD`R1 zSV4J^^s2t{Cu#@7p0F(yT~rq2j*x<0E^lo$auUR%;dK2mLYAD|751A^jkwNcPA8%T zcFmsRpf6s(#B&5XXHF<&akg%2-ByRVGI_b^VLpEGQie|Lq{QJqnH1f^4vc?U7w)RS z^NJR1x$VRib?BP2zsF-`HngoEZ`=B>$B^`ULI*dAJ!l*@{xW~AQ`f&vDt z2R;Z(Kiv1vV{>FlIEhGlWgkk$5y&J2+{w!;1I00b`sCd54brSE&+UKq&vektwNT zqAzM0VP_1}E-_oZ7nmE9F-rAv3;+STL8ak|V!Ntg)_R zucDC#cj)OI+9811_nPPH&kE&0PAcEeW!3?&*NUm|AHFddzd*L{psneEFTLn*k-V>L zp##B`jNk}^S%(i7Pyc|ItJ30K@&U3%yk=x(yhF3~5FoEu{zCEc3P3Io-%DSp-oJx1 zsp`K2lhCp70~QF!l^dWgmk_!=$>c-nrt>(ot&+Y+HfF!&LU+3Ww3kAHgK%pTUqysf zfK?8ip4P|l+|Ed=c5Wpqf#j)E6C~?p;IIM&rw7E3guC0?l2m_Qb&ZMDhhGa(f87PxopbhHwWG>g`w%Nls)-9m+Vi;}CU%99cME z1h?{xV^CxMdbG&@V_r=g<{;uaOB^{dlV-TDm8FI4#m%8=KmLc zLd!ND8sOegnqS;CB6f-fEcR31Hq{84-uLBeR}|Myo;)VP_y#c9Hp|M&OlfoAs~F)r zw59hiHWG);@l(z`Qf;cjougLqZP%Ewaq`8SIXyUmZ(Cu!YwkYY=r~2CkqwcnICaNZ zy?D}CyuIZyuB>CZ-%8#*oE8F8(jSPii|vW2pbw^u?x2?cSd^KeJt%Cf10NK@)BgHx zjX-yHh!tizQx>2zpl@;u>=m3m+E$xvll=?{^$NtJu1inj@hK6~+v;gF=zJg^N@r2b z`5rsSBs(b{vY43=!z$5f<&I&X@r+)o?8;;O`)3=rZxWzj35yVu>2&y$D!>g*t6{ z0_oO2w>;cY(HUZqigr9?GJUP0g?7z0q#`M@1)baDV3wlWe#n$$$LrF(-;u2FjeihD zpjYcnb1KopSsy1t9mT?>d}wiB%X@hR#!w&2uujv~*$(X~>%xOZM_c~oMtnq!IyWZVt%YA?tpGm?258jCg$eh@czlO zuy|o(zK~yS;8J(5&r#0q7_aPG?B)agX7|DlM*TG7Q;eX;JRRH8IpI$ z(V2B?M&nJQK}lV=s&vyy@E=euh6RwA&vbd~4%8N(6~Wle3x+cg!_Jf-$ePBs40k&~ zi2HV#4Ov-8Yy#>X{n28DM!T%Gg`HMJVZ_#a9f|OlHVPTTeWBGzl`-|k$g4@$W|@(F zAc`E_H%Jg=88m1w$PiS1E&`Oks6337!rDb)moZ#mR6S?`0d>GXG!k1`#V2tce2SP@eg*EC_%r`DrHRt1rVZ=)KL)% z-wzQpaXEjj4-jA(jFOd%Vl(i2CCHI%2A?p_qO!=yOCTr8S$nemF5^fDrRpQn9$B=D|Vnb7PQU<$XJ~m6e(6-nxy2 zHe8;ivPZj&Lg@6|vls(rdP}+z%^ViJDk#YKtJ<0K4HL5NI%9_wecd?P8Zl+0n|IS> z$nJGtalvG*b_88KC`6GeaRWhzDg5G)k*Jn{!t1jmovzZ;*3W>Y+t$61Y#*@2^S9el z+@b>E)ZUKf@NMgvcUyQDdAEjhQOv_8j-(f4h}m8=G4Iv~6ZXN9)n=D8&-#1p zJIfsi>f? z=q!rzvxw<#*``cDxFJ~pU7UXX`J3lN@t0!t!rgTZV6~~U`<1JmBo+JRZ$*4T>Ah;5VuakF& z6oGlj>>WSsT@vOQ+ISI>K=82#IA=TA)0t{jO{>)RX1$J1OOO6aAPCH>pB+4Y8JA zmcNwd1jdke2}+GW(fSSlDC$x2~vn*}7+Y#qJ0#cey?t z9j>d(rbobEyJSk`Sa=MAGkvDt9D6e&5-@De%>ojlJNbfE*Jc6 zA1@-3o3;ixaIW`k%2^~@?iW(1oc4)ltcBd;UMnMC7Uk(k#Xb&ZG3%ExM@~x;Bg*`$ z6U(3wPa+e7q&wDoPk#z2%-8y_VYG$yeTNr7ei_oAw}l&n-qPv^3Kq^-b(uqK(fj;V|8Td&b0ebf2mUIClB`PM%P|HCw@Hh!BT1W)@02|FIwvU7zCRO`km@HM@dK zb;ivYGh+u%?fmAW$MsVU>%Cv})xFE;aGEm{-vM0sf$J<3fEf1=dP8u%bcaq%YT66B zktnlYZqkeK((BtCBGst_@g|iogx188Q83Ox&F>O+CD#OtAg-KmHrm{|Y=v0xBu(57 z0C_@%zvl8}>fZ_6l@jPZZ1S5oheR9HsWtI!Z7jA>XZ|h6wBz{H-=E=-_OKSjHN6u| zjS0CJp3AruiV+d4K_~|B7^9f=^j7nUFJR!m40;zZeq-Z$H)RuHM|TM{DuV^kUi-2Q zPc8(JJN;f?%J^{Y#{Ex>%&9H43teR79~}V6i}jY31#%Hiyzt0UgrJz?(x6KH-bqgo zI{sUMUtWkKKSbr1t2#sInU62`1m@J_RIvcP|8wExYF@L@EplX$NT9M;$R2ixTV^~y zGB~I`mlNG3YH*Jo-tD9kZL zjg3?#B*k5rLh;Y1GQPx$$kpqE3oHGxr+_-T=rinFmeV?$vp;lsVU32f z`eL;G{Atn8ucqLf*O|1__&+V=@f_S$vf;zVY@YiBbfjr-9hT-td$UO8%sT5-Nd?q| zLUoR_Pa8CQQK~(R`u7WI>?mn3L2S;3BeRwS&8@8vRUEzn`TDg>=Vwm9g_&I8c=ozH zM?%U_MIq6QsxaN>dZZe_DcT&&&&MTW!c%K=f?G7}=8eoN+nHH|W!@WQ!rd(g=I7-H?~gy2~4Hj+>ES?bd`! z>-oWokq402@7mQ3szFKk#bW(u3gj=cvn_uWqFdpYoXRMUkNl#&RP?zwqzwgKF4uV@ zSL;_jm+4;nqU*Kk$~YC_qKsq#ba^uN_IA56w@W|&xD<~wEt;#>Y9dWiSn2wG4G938 z!q`!VIrXIrEhe}+-MsvYI|QBSDJMBsI+VPwJ0?-@H7SN5lg{d&dx31Q1N@$2dcL$~ zvsB<89(tpM-l-)&*<9Cnt?{1owZURgNsqPHHZ)fMsrhto=TWcdDgPMv?0@MM6Vo(O z3LGyfvErzA^1O4b99lGD&;f*1Z#fGmSN+ccZewBw>} zT+G~H%uEmpF4kQn{UHlt;T@}|BhiyM3$By09OquKgIBlri$w?FBM(nov+pxQDk#%VFXfhTEDPXm%YnFotv4}TRMZVnB#Km z@DwI+`02x08t|houG4rq(1uqdSG9t*2g?-~ z%CfUE9VCE+qUJqJ%^p|F?fTiTA~(1kxhJ&Jkpv6= zY^HuMhQuxaT{N>Ov z)Zet|;VNqztjhs|$JJEVtT`$XDRv2Fxk|c|nOST2fz|n$r{2jXs{Z=IsIhYdr3EEB zRj+9jBQvDd*A{&u`IkMdJogqeRdf>{wL8C3d`^`K>#shQ5hQcn?cX7%c|{!*A()c1 zHPkz*95N9!6=3=os#UYE4lm>wO7G{i01!7>e91~+7@T!~aE!#^Woz4|#q44~l@y{l zbFp{|lToq^$N05qJ~_5|E;3WT(#v{xlYz#+Y0-fB!#OH_K0PVxY15TZRX%MDVe zOPS;mb(@p^a9t<7rfZ9llITlh{NUx<s=77MOZ){u5mBXH^tnN~JL2s_Pg?XZO-r zt<$O~bI0e`{by3#n9Q%kh|C#DOU<|~uxc)|4PrO254 z71^YjHxXY}2b986f%4=b4{35ha$x@g&j;o<+>F_ZsVse@31;>69vw%&psi%`BWC!# zwp^a7hXxF{Y#cxr@+5)DH58`QUt@`ZrjFUEueguW_))?@DtxB7zC_xhhh5ExBUGE< zmg{{(!F?!X+h+t7Ik>CMyWU~pKAMB^LYJPWDO zLMu))@fJAsBmggxj*;a_Ei%VtwlI}L`?JBb0n8H5h4yj*h5-x59XVJVBJLHrB-zU?z7 zJX``Mnt)!hh~H3?rh)0^j{O3KH)1!Eo4yhZ7V?otB_!}AiDxCZLqwN)lre_vQp`d7 zg6Ir<@&{bCO?w0V{LjAGC4>=rj47646LZV>@!#Oo)Ves-Z9p$@uU zS4;p$QWO>bw{s(m_HE8OtT((}{@=rO{3XfVb1K6<3+`nvLCATw>%SaDl`>j!DVlEg zXqSlDN79P2f6gH6c}5;&-=)v~Ityx@8%6QBEA=T5<;$6|W%gT(-<_E|RGh zUTgv1dc(E~Ne7Ce+ee|IWsyVmhPNp0hU+aGDy?ippJhY}SArYxM&*OKsn+G&H>eXwEz%SrnIlAT7_!|_E z!_sZ>m>Up)*>-ZZW)Cm8{euX0^Y6n;b>7#BK&!%CLk6}3tnORj-&1bQ%_TFuV(9Vm z!vjxuA$bqo8_ZHgA#%!>a-Y#0{%Q?c>-&T8+!YC;JU}diKug-6LR3P&-HvlI8qe&t z_8po=@Zq~CLjPJzll%==f1NckD252|HR6k*snZUyx(~CZzWB{^bQ8ujmuJPRMqgYk z;)*J`J^Ach@cU?~LB2hGJ%3ypgGD{k$Ek@v4bN}udD?Q6=h zy*rd_l6Xb(;Wb6p2CU-u>ZpW^U)`A`(`=LAS5D9lemw;eon0{Gb^zT=qVQ)QxhJJG z>PGCG@JgEJ$D4~~p+{4(buX_qZ+X&dHN;Uska?A?U1d7MqupsHqe@YTE<8|OLETd~ zHxr@Xcu#c;b4CR}y(M8ucUBm`YyfpP$RhyznRo*_F9#3$SL#X*>$W07TGD2Cc3$2+ zZ>l#)_yp^=xXtk_8d()nJZMfWK~MW_Iv?&xq&|{<)vuxj_t^xNNJ;8IGfEx4FTG5( z^zlVoes#=Bc7v~9_m9?NxSG$WOF$0aX)o4_->gElh1@l z%4_B0V2$RF6<^*b89&wd&d<3@4RZ>l5d*Q^iVE&d(LASbopDK0NQYGY@IDf#7Gu^) zI8^!Pv@OGPRCt~Z3DPbu2L+#A z--+;lc}R0OJpt%HW*Re`$oxWI>0N&TXLaT1W_Slf7~A~$&Vl#Ibm0=4+8q-(Ds=;j zqe|E%;tUK;37+6ZrMte8ivVO5$AogIF|FwLs=McxY_!C;?DVXcv!^0HK(?q}0K_H) zg_4#|rj;^Ya8{(IS-h$uyh2%DOmQi>?Se7-y=Y;Yx>7+9Wu_J)Xk(JL1C5YI`%w~F zblCN&$0aAns7H5}p6LHE4bPO%)QK(xvsesL zgzTF!4XR;NCUzz&t%tmi0;6xp)dq`PtI~t~MyyW$qJ^iid3SGwycLtV1*M+v7T7V* zh1}N_YW|TUGiw2~1S=CS$Fv+6<9}2sp;ZB8rr2iNZ)w4;;n!ws&~nWRljZA}HFO)y zP(|`(?4`N1lM^G(`F#f4)FMhF0Gt2Hm7v|2!N~w&pmn?(mG+#I$f;lzUy|UNK5YQc zS~ntNmP*$xy7g+cYDA00@wB<%gC;3ZqyOp}v`oX|!H1QbKOh&23^mc}2a;871eSmM z6{2PxztB`?}`D!GSTGwHQLdwAk6}}w`g^B$maI|d6!jn@Y1XgPr2wgb>sa5uk)e){2hpO*r5?#@ABfo zF0iJv#ij+uyDL2zEeo16?*3mgMu-faB&W6~%4fsz91jKLeY_9Jn_9@5G7zERqQrBf zsgnb(w=zPuDXo1LuzpwdvWmBq0rLbFi!>?duav3_LPKRi-Prqgn&V`-r4F^)ZpYKm zJf6bTWEs&`eCFDKFUQu>khvtEap+6w@ssOfityir~{OuT;MrT zF3qQuv{CkNY%`e#(f@H)YKfYc%+gkdZ9Ax7DeH7-^pw zbOU#OB_qCm;_o;I2jN2W(t?oBRzIK52!~+_;c1_7vH63+WP_f}uOVtSl{z5o9~6rQ zZC&hY=>$)iiuWzwZc%Yna7`V_=&TkMA0 zUv8t+lH=XjC?Q%?Px}-To&gBIqcK4i$!p;hPj);#y&1h?F0j^Mo9C;BA1_Rpp|x! z3LL9U7ju7Xi!N=Q4wRK*mwca8!MGUHg*b7S1TsY;{y?OtOM{I@Zh5-DvgIGx7V&Xy z+hijZQ*O4kS$vGUlA%E+8^#g~{ipE!0!Z;O9bgx zh)NkvOr)aVW_|&>**~_@{H}=j$j0w@5gLd}+G}sOmm_SnOEG^K87S>tX7x+}G);Cm z1Xt>*2}cNc7gD6V9ujd8aYaW4akk0lv3`542Xzl~K)lb|(R;1O#@LJ(IC7@40pSb3 z@)Vq}XVX?Sbs%P?F?dT53g+2)yIIOuJEv)-l2gP>$@Z95=u&!7RoAVqr9EVYgd12Y z)eP+#auctBg#Wa;A6>ff6ERFAF^&24zN}p;D!g?==p!>M-LaHaN~@z6etERc`-_sH z8ES~+Me;i6N~g7QM%8(VXX*JFye9XcPQUx;QZdlkKz(qx9rf1F;O6#Y*@Q4-uYP7# z+?>trZ`DLDEBUu`6f2fawmB~Qzx;9bZjV5HyNOB`+)ZQ51-TNQde3vf%Pl;bY_$QsFp8QJ0hTMZJ|s~C92aXpMgjIiqGHpbuj9lC75QF zs_=xO*gt)SP@?>^9%-E>Uwd^R-le#cAV9+MrftCMSu^?5Gn{j>J}Gz+<%ZV0aOb1a zG!>N1^hs~04jjkhYd|**9taou^}xswEBmk~M+Id->cavdr@zCB-(*EumaUyo zGawL{6N=ICKV*q%@LK%Wk-hFU*stpPY6*=8nBMc=L6fMrI;ZmNjcy<+lo?fymt$%M zqEn5ziU?{tsw5FDe8%StJQ138amLO_`e$!X({r=qdvZ4YdDK-@fek#N?kJ??D`qCnt@!nlikO?VI+hNFh5Zvp{RxAC|rc@p5;KQf%U55vjQNL7LEQ{q zA*Nv4Kop3kWoW@?s#2>)8t;=3WX?`MwXc=H8dU^#F0gBA&A28DPD|8PiY9USnW_2Z zgx;qSCB%-v-D#x#m4H@*qL6HCq5FGtF_T9ME5+q-7V# zHBtkGe73Z-vZ>-91O@`=@D0(y*jRwP{HtW0yALXHvbjTv1n)gN6xr^O|8?g~qB^UE zK#;t9%G6(A`(4N4WTiBVV1+dhO3D90swiBZa!`sb73;@L{Gb)-T@P)K1*`Ark(-{; zsYk2ZOcizlMc4j}4c`7Nu2(}9@1*q^-!KMJ4>p41e4lkCS6IJ@$pzcCY}8n69o82q zddndFk>vOkKm)=NdUA@kw#$64Z}^4-Ae!L*%*KmcHR^u5O8<6!dcGCg=j*+v0t27e zRDhsoWHTATsSdwZzJ7yZXGA2(xIx$;i;lfAPo=oqNCkQlHUhF^rcB*~`jIps7)No3 zh*FBGs>-WP$)O{!iVVz=3=SecYAnYzN)$2@-wVRL8{Q70+CndG6$PMl4Ddn3ON>i% zwxveDq{&u$1C>BmMO|3rVN!FSLgqAQ?fNm2Z0>NrcA;1izX3ITjRx^G6=Bk%0Qv4~ zah>YhYkbN(X z_^cRQ%`(1s*E7HU>0ay7*IWn+6%in_`z&xR=#0pP+w0)A7uEqDJkFydtTS^~j$uJC zYukPmkNwb{xN>;40!Q~J;a`1aPiyinKt0b_3U5M{dIqLt(JFp~bZVIipxJcPToEQJ z&1$6S~31S(K}>?=OP8j^iZkyeL@+O-qlu>;eQ`i`BFMy3~BYdVV4) z)&GrMZ#cg(3{BKwO>bTkE8K?U?+}#d>tYFLwTJ-mL(?0khKAzec3`J!afrE(5j{qL z|7yp(!}TW16gJ@d-Hxl&?k&&2n^)_|L9RQ=6-)rkvZL%eU9S5^v6>za&ovTf!G*$} zG^zWofXNo}6VTp>!3&=ExKFIeH=>vO#)+Gv=hz~dfVY>nwMDtzImSXUsl$}u#|C>u zkZdM$LN?3IMo>7Z2(3C}cVv9EYm;oF#=K4GWQ!k%d!~`4V*Ai2^(NWDf#5)$T1(jS z_UaKaM7Cw6`ICtvix`6}lJ(0Bm*Mk0t1x@`sJudUF^grm7Y~3^e=P$VMU=mJ<;ooe zQ{tjj?zpDwl2%C6t(=QozUhXE4y3(=NVE+vq!w+_h(S%EPyon|s(SjE2Vt_ZPO5Y8 z}PQ zpBOe3s(2#9arJGwU&SU74px-00;X{f;nqts1#~ToalSY=o|A!ush3R}8Vd=v6{%bB zqh)Lnsz~Ij(>jJB)8(qCc_vQM#KGkaJpp!bDYgZ>y7*8nyYFUh;;X@P_lijJBDB=+ zb)`FI0$mW~SCpnxiwd@WJC{Yt2mm2s#tx--cvL0(ET=aL_mTs@dXC{soS~A7slIe7g-+`>SS4hBA&F00{$G3~6}bG74w{c_ealAlwd}V!!6o)cxEW#` z0qDBABQLBd*>;OQ=95~M-F&`Vz#Z+{XV z_%tsEPpif$5`jc8cNBbkR)(YG@fx*)5Ku8MiURU0)QqTZAE2bk7+8KK*p)u^7MoGD z5c-bYzYwVn;B$%XspJn_chE`g9`4GwUaUH-SK9Qajfpc5xoKux4qOyMpem}th^E>? zT8JGQT)~`T7ihQiz%ExMD36bvHRKY5kW`j|&G-j_3=yVpqw{Z3A6Aq5u^#($D^gd4 zN01C`#=W>}1R>MUSFM1|qJ(HIH@2yUHT)-h&FJ*4?Ydz!@IrE78YNa8^uATe3DSTI zN3g91(#itg?oY>Fk;~WcM7j|Xbu&=XHp^4rUUhMn8&zmC61Ln_q$QxpteVzlMf85> z#zyIDl;D-A(MFkZ*aRNs_DJYu6EPlY05dP<1LYl1!N)-r-ukTc`pK$IaSP2vmsnU1 zcg;}>Y1mIxZ2>U=?I8SMXJ{v+>;$w}lS%V5%)|CZz2!E>2cUdMM~g*#<@FeVk7j%1 za3Ua~1M(E^&5ZQUO`HE>u8a92-R+6RHNdP@L`2(UuM+1!fYi;tG}h@EikC2{N5G5V zGY2T4>?FS}vIf^IjN=MCxfhT%TPgutuJzz@jKf1Yqi+{i>Stki+<{10eTn(y!63NL z*!o^;-WX8TlaLp(&Q`1oGJUN%fe!pE;384As-4*OVMcrr3HoHq;Q=i+-A$Z6PMa`l zu}SKyx1X2##m3?gebTYCdfu-i#KK{{Sks1=_!MUAS#)oIYk^%#dk!`UPoy#AOpyu0 zGN31n*yHWWiq@shl|KqPW%g(`d!p-n7L+!L>5p>ctsj_)Vl@ehpvVGo$RS-L4l#hc zdw=`B(N$hhXNr{)5eTWE?;nLtY7l2#-B%1sqP6HLg$(Ek(jQ6X4t1( z5V=^ZG&|cm;%6yXyuj+rM?|iP^=kEdd}f@H*WC4Bu@~%`ysgUJpL=QS^=C9jLGzdk zFB4~}_wk3Z80$(Q9eVzd_c9c8Jg){7#GsMo`DInR!y8YucN)|XmflOK#jMlEa` z7S}0(F&ttts=-(Z@d-JwW3TiY`Hn`6_RXdHpF%7aag#fBLnCM}*PI_;TC~b3mfJzVJn?CTL1^Oieo#Qm7g9}lE0A3?NN({z`)wp+Fp^u5T3E%ENc z0b>IX^-Q{BNuDNUYfwd)-t zm{{D(-~fN8$NWj(4q85^zk3Cf(M);*&3=n78UYl>vouE$Xnbd9w;iD8Pd_JqUcT9h z?+BO(F3Tm-2SJ|IeWLgA$+;1NVaKmiS&@O}XS`tpCKLyM3tfgP04+e$zh@-}=MWe? zYQ4&94IaunKD?2IK*1}pp*f=aFDt|2c*TCEzD*DzvDhGFaS}?S%30F>?WG+hGN^VjY z8L*;L&BRKyATT2)#T~<ygC!i0;sx>@qHFmA}$iTTc1i++=9nb7gk!ydfiA{lo^EUhnv{r&aiX za@`oI`-sM_i(ta4yFw2@GY{~yqvYoDW+}QYJ#~{%n3Nj#w#*}>&L0CakNf5aNYIU& z08EwJT;${kQ0#aGAiv4lk2zCFA6gcs*W3tQkWlQGr9Jj^{EoRSL!FXKAYL=Eo@JVuaGp zCs+DPdUey5KTyGhj3FeN~ve|`71}!v;I^&x!Qb~5e zJE%z?-&+R^X+rE&IOwk7fXAI^7ev2(DtJJzKMwo^z$}Il-<~e;va`3LpbuUO@qp|$ zi6f@0Fq#eY0tLT3_)Us2ENH}mMsy~e4j5Kfm@WxN7)H=}zTg49cnU}!uelwia^zXl zZMM3v;~_ZCVwo{>7q;cj#k-&VZ`3f0;I|OQHkrm-ZqH)kobt~@^T8CkXf;kQ%EdO` z7Qkd30V%lRLfsFs;P|SAW`QY`c$eM|BM28!=lCmw+J<$bGpk8|Js* zo-t0>G%o&9TDF?^I}pQCqmS$Ut6FUTmj!dl_3w|qzX(QhYign zr~VC8rCI&tHL>=*a}j=v10 z)1{%i_Ta9-&*i;%O1)5wz((ADgtEzFt(-%my2~p35Gbd#&OHO#CJy8oq=P2l1D%M& zY$f;1{aJ<590<}Ajq%{u57hY$A3Jlo0rTXwqVvVVjMPssI{G^WL#G;_3S4G~j%CR` z*X${O2-_o&K2_wb6|^YMD+%LpBTDG8wn8*=`6iz&w=QPxz6o*U@ZOe_vCxS!;dA=2 zg))xiRDSntLwE0x>9aG)4ki2%8|~wBbIvlu4~N8+YOEC&6bBA+r}FY{nVB>{qCLwCN3>*L z?^(sTl47YQr4I^pX~3!!45h%mrsJtW4fL)^oCYD)mpdhVJ}|u&&%y2eM;c3m%r2`s zH|54+bN`U_#a`G>CU6+kX297-dI`FRN3kFbr8P#><57NI7~I(6F@WH+v)So+p;+b7 zzJX__ba_9jEl-9(I`X=5L$zGzPgD$$M$lzv_Z}BtxdL^_mC`2HO1+tUP1V~m-k`!NTyTfIwV2RS&moD@52jzC6>U=|iypYlR=CSd zpSX$*4=EQS+tNf|?F`Yr0EihBLyKE;9i&J@$$5nDDa7gXc|U1PVdJC|OcXj4j#jV9 zGQ`E2;+c0*yl;hcCz5&L1z+_WYz6yLZWf;LH7`$i3?DjEyo9gwLJt1G1m)MPq%FyCDQ{j;1$D%+>Ob-)MX7T(Z@`q*;$J$M3;6 zW$5@fJ0@z*CCOMfxDk zD0_s&Ei7_L72`n}Sydj;ZOe=jC+fU!4q^iDJ8K>qt^?szk1R)w`s`A`a;U&Lb?J~a zT4{5#*GWTYaq;0l6qlRfGA?qoHvbBkkSCG_+;r9xo`{@W7qR_oZX#RWr$$TLzOuKa zUPNw6(~$vJ)#mq4qAm^g{NWjRXDvBOVdyDZs(wu8dp}>uW6u6it2eXCMycYWtmAJg z5{LtEf2ag1hy(X&+gI&+&s~#uns3OFjeH;$-7|v zmD{4pg=a9z$8TWhYf@3J)*WR`;pWQQ36?Lzn2PU#^H11M1mba`g?1ixUeJ0%+X}Iz`Cq!(t z@<2t`FlErf@;>M21lpQ}s1x}g$D+^l|GRYj zdq`ljwhU+%7x9|+p3W>A64SFDpfsq#gETeHN3YM;0Iu zlYbOwV0I<6w2B(xR95K?DS_hBjnOKK|O_$z)d?zP|1<>{2ycW>J8N!uazV4DFoUvRTlCy73 zK*22;Leq%(GSS?GOofhnp&!;J-UxJj6SmxD#M)+}Hn!I|nj62qg9gj>e&ZC-55LRJ z<)CF*_H8$+Fkb1i>%xfsU?6YqW?>8cGobK6Kik|Vh>*rs3?!Y3za3<^-K||FKr3cz zI==-gQk#rNvHl%xMw>>26k=&%s-KVF0!an74NUNS5Z|7243 z=&~P|du?-^iVX;LdvKKTq?^S#h*~T^{K84=T7GwI9sb=K+D!x7^Zc(hRa)+E*Zol< zxp1sg2-PVniTxd9Nnq z?gYP&*U$nW2jjO-=r^LAOg$5V458Qow1Gi>ZIUIWs#3Arb2A7->6$SlzA@S@`RAyW z;EU4t1BD@Ym_X<+rMykTDgN4RC+lQ-9hOwhfI_|`hJJH9A{CvfTBcQkv}(M6_9V)y1MPJ=jO)AKZb8_kQx|c^`yRCR}lcLXiDdNYfr<6^j_hm@BBQ61D_I>QDAU-2fBZzsMKC@wty z#uOY(i<0|6&7nmiSvHAGo57B{91d|duj7$^sN*Q-A7NcPw9Z*K?#G6a zVT{LHiCS{G%LzD~@gGZc-l`$Kz-tBgV6Y<6rxE@>vR7fgbW?)X3{NYoZzb39OJC|U ztq+xKPvVXpoCdFVql)KFRN)h$l)H)aROq)anKafBk4HnKqN=B90RRpHm9NxE9SahU z;38L)m4YJEqvw&w~0NSy+1<50J$H~U9e;2AicvMhmi`0y7x(vB0YgbtOn@PI^n zZQy#=FZ8ac-}X8)QY7j=jm%nIv2`E?4a8f4y`RU~#`0{V--!Lnjc|~vIO5BUkj}3) zy2K)fV++4({jjJ#TER8L$t)$#Et`3&W!~`Tgv)Z8xgwka0qUw`S`6Fy`hEm3i8-m^eh?<|YqZu?sn#mN5fYqY#3|lDxTz1S$9s3kSQt^nIMbeRW zun!Rp_hT~jck}tHx8S9%Wc5r`TTc1Vul^G!{S`W)wDfcgC2oD2xkXMgAagH&2?&Dv zuh=(Bnf$6L+zT7S!+&5pdQnEFJ=Rre{=vB6*n);Z$Q2lFahDy*eSb(DRDx-l#%V^N zNG?#OgB7cs^Hs2o=AZ#s0@XM(x>%Q1^Mv{;?yA7Zu+d^=`_qMKPkPZV6BQpHHU4Eo zz_ic~QD*S5+}aNm(jf!SnIrd(k`A?<)-Bk zUmtpehDh){d{xq(vsEtkq8DTb;i7`i8;`S^YxybbdKtsFOGbJk7o&aA_5h5Q553(} zs|$z>0PLqdpiR=6Y9y8;d(dF)0RaRoVews`5R(Maa8PxxfG|MX`?IOJ#+5(0Fc_45 z0CDVe3?G%-Ze&##l!C${e|VirUzQP#vy}*kw|vehqVqjjyc%TlYSded$ILyOJqsWL zcmy-!i!wjQ4Vt(AVSU(sgpv_wZBCb5_z(6L-U<*D9+!v1m0AtUMWihPo4Pxa7;fn2 zyP4=K@4shYA?^?rNX6@Q^k`yA6r!;IsOjdAL>yT9@*_nbXSwMYFXQ|KZ{}J^<{ItjSi$9-|yl*q26RUqN2 zH1I;#+jN=^RjX)>BG*<#dB$Giq-cmQNtpB4vaJ;c+DRsyt7@V3c4XxQav%A~ZeburcoEPpePmsd5Ei z^rW@t)ig6nz%fYG29o=Ug*sJ(Wz6+(s^v*m;z|j52vSA_5C=t&%ugIt0&Quq>kx-= zx!xZaTJ@=P^Vq)eIKjO+y5WMw$j-owkP3T6{Nh14h}3@=nt@YtI5}Iwj+I0BmIduo zC6{PyZ((*^2@qD?OI*l$kpZ)w7vx`vvdq1Bi$_()UztXp<&(&tO0SvXJk9WbyC946 zt+VM{8IRkI(}$drYPnGwvYg5MRg*;;a!gxkE5fRdb`_c)?G*WmbR5@X`w)o{cpRgP z`LvD_n{yK>fJ(1O)J`D*c+-tRRV(7s+d_hw(+xcP?JDi zg=o(={+RoL3dAM&x|7TCkL$EXowRn|ayz%-$Q2G3*inenXWmE83Ry)>2V8eoS z=%5VS3<;D7ruMwDzYji{jQm`fMH#1L{JQPigMiw^759DSD-z*KfZp#tqF9zp+SA}x zQQa*75|$g%U5T!a=1pQm&x`Vzi+YL39ta5F3U2ojX9JT8-Q+zZP9k+9mZhjRE3ri+ z8QGIL0(AfRtB*>pD)f8vA-yZT_(?+wG+h~JNZBlq9r3pPX<;`&2_Q&0-?P36VMP&bJL(ZZfK(<} zsHq+&wqj-GB<2;CVVteD*F{NHqF>{`nO>O0+4jv*d%(G|WLYxtiJSn)CH=*cFvDNAO3By4FQ%A9L%GmP{C`#zZ>*0o9x-k`Ob_J0M?*gTc?)q zR!9mR>_Ye}m`J#Ov<+}S>@u$2X5fJlsw~7qPAaOT(J?C5q0aLJz-UGdM0$$;MLR8O z4P}E8`{Gg#f(aYtCC^{1DOu4YAivTK7!LXCp>ZLJsevIAe1}YY`F^`Sz$C{VpX9rY z0cAG?u2a!x2R14T`|G-#B-ZresA!>H*+)_;7fN<;Dcbs27ioc)9Z@=ftQ+8W-Y))} zDJO}kuooUGWtBt$AkpC_E^4)Pai6c?dX=9`)_^MF!U_fo+57nqO@)B-y4xpeNzZF{ z+5uEBGM*q`a`w*6xVj5!LpKk)VMzdnb_k(ACeK1O+K#!tk~o!w)k@LSqP(H$5@?;9 zm}oL?Ut9;-VL0ZjnW<_lHUC2ol2uAh-WR}g)=CuQ|?~W>&q?+^!ZhVG%cJ zh5=%;UKFVsIt0agEp=Jkc9{}d7hDp^Kl0!J>2-)15sdbpR5~4L zP?nZtpGu`C3tYC{C1Ki-#oc*=7aC~Z`Lz&>KfBW0KqvzMlvV{6!24 z-z7j4Ot2OE1Sgrv6T)8|rZwy0J>cmxptQ@{xLjQr_?=WlhGpW2n)V-ORAR3e_XCEd zUmGOUOTcq?<_o0z2I)sAYSJ^=!Eh{|X!ES~^fCRqM(41qlI8YuG^%!uc{CXmliNXN z%wAI-(^q%m$`S6uhqgn^1p1!>E_Ie4jVyZ10sCBry`Y~1R@WV0ym;jU zOC)l>y5#chK=z0kI&Dc($7}0LRy!?M(Fn$&IS|pY4JHBh7Bm@+Rx__u^Jtc?1@c5C z$v17@8PzvfqfF~{k*$M3 z=fmu;K+c1)zIs0d>Yv_;Yi7D<{v(|!4m2;%lVAr$krVm+m#JP`^xECmi$e(DTTSpk z)dfC`HTNFrUBk_Mzo5aMw!ckit(Vy!fbx8PHkF0ku($J}3@)D?p9n_YC#Qnlx;ek| z8b~CDWqE2fc~YSH^+h9K!1+R&6NwLt8vH;_ghK8#Sz>!8f%vUW2^4h|v>PWIoB^#X8Q)h$AlPJ$0j;Amg^XU&uVL%zj9**8>l^%pa5x z$2cmS`t8mnXCpXlbt3~U8CW8aI*tQg>KWxwv5|E`$7LwG+%gA=cz+{F<=M3SQ~AC_ z#MXc`>!#R*n1-=PFrl_JiVCUeWfn)|w7>>1WeqsLMLVwPPYr@Uk8wMim!LIDB>x7@ zbe#?Xp{(wstl!5MoGYqhfYWTqbpI4abF;*ih0J0PnaTj(qvbmc$`jJQ+4bp+---u@ zctk|hT;qJQ-Q8`HSY}E$?YI?ykV!3z6S#UG-g#wghN?@~ABU42(^N^HB72hwr=&pikw_pjVK4;gi>ED)1& zLmcX8e|Opcx5vmw=OP+*fHh1I?1TG1TCeMsgSS1lUV&NS(qA8YE4Pa!#(4oiG*RL4JcUL>P7V(B7a zp@bi#WwP7RLwML244m&wEkIVqb978Za0r1ypgjBinqKkbXy3NqTSH-`NtZo>U(_4C zsVW>1>Tp@>yu`a{vR_4OHey}8=^kF#e1@Rvq=JL)CLLIOoQ`9i zHO1T)&poavx2to4?nm$;_$Db49dsH=P@z7q2)6t z+}^P2+}CTEjb{8(NG4w*!h^?Hc@0f?o|@D6mfX@wW->C8EBae_1TB9NcrKU~SjYgW2cjt?FA_lj+RoG4c+sPV92 zJ5*=alq~~5M#ePQN8YtQCsR#Md-tn|DR&n@-oIwfx3h6jaWZSVpO_jttt31_f|IT2 z;Kay(TaAXRU+$V`wevef=zFw%`zl|5}4uRTA^ch|E^>MMAT zxdXkWLJg8620)CJtjPRU{7e%#xLz(-iO)>zhTwbTnqG)6E<(4~z;K;lE=PHmDY_5q{lkiGFkV?SGg zK#?@b@B3zt-Xo-f_*b9X=k(PQIwwpxJc^_HeX(H1Z~aSq+3>9A@rN z!zm9`M9#pfo2_c>rK`4Ays8^~3d87p7FH|!Q>6nsvUq<5PUk`4Y}t_HiNhsjd3Amo zqa|0#3kLll5|L-c9@YzsKs-8bajEO;==W>QF>to#zNTz4r$Y=0%^ZcFJ%~9h@e_|8 zR^)q2kZKD_Py{gDJ}^n@bFlNB@f*E{qt3#pVGYHz#sd`+dvp) zByQdLHN2X|rG#3f+&D?f>~A?e5Gg-*Ec_`O^dAravmtZg#)+EO(CM%uM8v=Gk{poaN!bqJ z;g27y2Dm0E+jmvdgu;$)H94I$%Bk@?G%`K5aIvP*Hz>W+kF;fIF`S1~1fuU)#P*++ z?myfHm-yUa1TITX7UHmdbI3!8FMuW{3HIhicf5;9RIenSqWW``HKB*9a8$&@{LVU8 z0QE~O{bd>5C{9sZwv*$NAE73NKCALm`Se?m@9_ zi@wFY`g@b!fKUCHT$xl*QzwV;D610N9#il0rGm9sOh)o2gV;8*zaaB{O{%}6 z!}26xxmj%4>@x&Te^WXs{19%>S}Qd{Q^Qi`ul+*<#eaHN7%h48Nm=u;FF^kgmhh)G`hW&RUmXR$v5nt_UyFz)Y zwb_~HN8FSE2%DjcAdFc0N`&$fg%4Nf)0%np0_J3{%aW8!QSayL-v5}w<(LmJFdsH} zHojr?7Z#e!m=g0Z^^nwJRlLJ9V#}iAlA#s)dl^wS=F!g^ma$WeEWat;JGw+Dg5Ly} zb4zu5epvggeYwd7sF4RYBT__ABgu&C=Ytn4g_h}qDIJK7l_}*)-8_3NCIhZ(0?|?n zmXnchI{R#Cl8_IW&`}8U)r>+POfY6oDktsVl%z;q{Bk$-P0nC4lP_8=-KED&)V&o! zS2|M?y$!OaOUYL-B)B~3Fb*=_6lzFJdE}N9^3K#H=`mwz?3mF}`7eQuKHlOGn5&eM zI9YO}&}OSU4z;2?QExD&0R{qql-~c6%4n~SMcKK(4#vO%`Rc6?(AwoMDTD%fniX0FvGS@ zLeW1V7STCi*^ft~7^Qz6#vxD)%gnt6sNELE45;(gz2f(mU1yd62DbDIufY%7F?wQ= zRMZY=Be5TJeP%qGxsv~}HdSA{>5VumQFn!NDP!{dQ0FX)+edp(Y}7_mIG!J4G4I8O zzA1X810mXxzajV|dzSaH!&I{kchUfT588SD*gI_ekCw?L)j*71%qnC5&mEaSMkpl_ zXN-Q?WFF1&0(03i!lV+?9n0#6&i4YC=5vfpZoS?AACLm?65^)L8&1a_l)EgsJS0H1 z&;^~3e$=_2fUYW;@>yZ=J2?s5utA%pz-EXzsat`J(Xz$?-2(G z*vYW$`n8wm>@p|i1&@ht#@io(2*hc-IfC%VFZdq*i#S0~7n7ss z$e16E)g7&<`&<3ezs}GhykQOIZi1SF3sWM}uUK}^s8pW}{!BIqvQ$1}CZFse!oq zmEp1b>IZO1vXgpS=jNPT*LaP#?=3Z0HI`#PBAI6LqI$7u%u-Q=XqCDVm}ef zg6Dmtj*Y1wPKL1L>#^~tC-{&&DNrNuO+F}43+)g*wkSI&R3psE?eA9Fop03km{nVO>K-`38^TZKeWv=S_3dB z;@Didg)>KVxf#gTyn|PN{5bW+Ddaei)%vnYY#0!}JHebZXyp!rAsq}!%$K6S>F&h& zHk2CPNR)E@Slld+PN);xs=7TffuO2hQP?dN!f3Q>$N1Y*rge>fHABHlvC+iX>u!mZ4^jUR;hJ5CY6qou-g108gGNP&wSH6Kid=? zWn@OJw);0Y9jla2|2VZ@eDb(|Z4$>ra)(k}s0`KftLYVyAV4yK-C zZ2cw>e#^Kahe8=9V+*x&o}(S`cXSEIxPSF%f~Mv<7zMacQ5BRMSC?=s`JOnE7?n#1 zN{+#4ja*4vz7oY0a6D268#dd3NBU$OEY2BXFIo^RV6cIU!(ijcT_8_StI}e9&w|O* zAW(t2Bc0+lAD%yUlJE7 zbG@|AeoDyZGF6WvoSLV^?UqDb#n63x!_up}C0ApqrepKht@2}jTi@|>E`m4CopB$z zvTC8_;XD?gTO*iAo={!<_Ke3&*2za$d3&;K zn;T+KY^x%G-}sve2OZi@!0Tf8NESR`;q5Xf(NL6{Tn`SY8T_;C_ujlv2hisR@G9rYB$(guR#BYjdC0^D#Dq7Mjrp ziQ^m911?OXXxJQ44m(&`%cwHJ{rzjsnParg|Ek)oKM0GXG#b2%WsL`^@%RC#65ds~ zYWcip6`M73HQ<_P%nEq(#uDUx=d4uzPPWse6xWA9P-Oi9#-`Y`KfZYg*(P0yJ}fDYkh%Zlo?#6euR)OCnc&*UgvC*V{r-JKdmHH%>d z2DPn`X(Y`yd(BIWTNZNjR*X+7H(=VOrgOcJ$nc*`+@L)OZ&z+p@RUvA^h1K|s@fjz z`RDlDi|j!XS0)|=3vq(mr9kliX(X}As`DF3%v_f9eX-0dcH$eGX8QzXTN>$W&iQO+v0vGk+-BaHv2S|%EKxx*6+ z{}zkY&DtUWmfq5;SCU-S+ZpB$^P{S&JN+Jr4MrnNnkrs0M!*(iP}CS)19l!bk+2td z^1f)hvp4w`QNOsq6+?+8!G@(|e8{31gu`6oabxr~gT%1bpAHW0=sddcOZp*{#>@;~ z#`1KE-T}<^=G8Bki!o({3$`}@KXv4#5avaGy2Z9dK@QQOgq>{!UK;uL@z;>vM3SZ# z175+I@k$*UmFqp%$wq+pkxwGH`Y0&KbdU>H=lpnQs?H?nr(r$^w5aPs);wtq|2Xf= zU3%r>d`7MD9f`-niTy@{2_k8rgLlC%+HzfSEgjFcg&o&zd$64Pa|&$=#;Ns-GA^0Z z?ShOfgV5c8!%)AVq7c-A(c37c**J8aeUv%%%ITo7=zN$N4*uoV-JJys83W(Ate+A9 zgEBgBQ~f){XkvC_A5lQ%023L#yv3;Xdt%Hlf!c-pDPNtIKj>LUX$s)ua5JVW zX{zZoYBQbxZ^EuF$YLu^9TGKl`>U;b9sflH8hobq)nJ0tWpA?2kqG-@Zq|`~T%`{l z@6B@CGrGs;N3wK$`U$*z0X$F&^^g^lJVL5#VPH?i$`7A5vVhZUn^9rMBMqn1m&U1L znEckAUr{eH60%B61l%o3gZ-dh18stP%wo9aNs#3HVuNTsu<15_vwBJLVv~YJ##zo2BeI$=vh#+6k?d&@*Vf*8I|>+ELxBnB|KWjWG&@**u~pBj6Bx z&#%vJexNGAr5NA8wdUtyBoaT&po@wvt0^jHyj@7$XwxijSyGn+a*aLDpl9knU2!I0 z=7AatfedT{6hKN8kA)Alc5OO!yrk4zWauH>#CQW8QtB-x#cvz|1rClYfa)1c3%i`5 z8|$POtA)PNYaOqAt9~4T&8}16Bld22-J{!~Sr)5qR9ZrILZtmx1nSuHv?hTT+ z1*l5wWYnsVEiFbwE!BD_-<8o#^r5y!yYX>kjgU}?{S(t=9<+C<6ZHV7GwZ%U7iU$|Os@YuuW?RqeUhdY*M=iN@HdMbGM# zl@3mWk&C_KjUfb#R8z|2uf~Dy=2qy}{W=|TnFUNi4UEjXKmyX#od7=0j0w)>4 z)lMlorvMUlopJ%fok~N9UusZqqSK#^(n!r6oiWXjsI=4caKWzY3IL7#4`~w`{Wy5l zS3ttqxnaY)XeOPKMW$S_C1B7jT1G@iZsCJGOEgg)?s#>q8bL1}$=3B4q>I)*A&UGq zX(Un#QSIjnhEtpH-ZcYeV~xpq&6g+}WHk>F0pU2kDK{C5WI}JkdGutFof+lYWOKr0 z0uUow*sHN(#ls-F`C9k{fD{Ai^ojI3iYDwTmc;OMxG&y zh*{gNKmyJD;Wx|<l6}B7F@;d!2`QTp>60Ji8W}c3lL4KpP#P5rMT$5Sko`ccP&^9X+yptB0eD;E`$SMoYm)PXdv)^2$!+*%v z=KdPEXq9V(HP|`A)2|YZ0Tpf_0SIC&E5?Gjqf;d0;MHOQrK4~}g({{OaCmeT2*+0g zg0w%q7_C?oZ>~8YnW0LwCB^d{nt@V1?NpHl9ooUw?A>VI!`<*2)(Z%UrkTHG){2v*-js4<{up7r}-lNu?b+@^(p@gW)||47w%u@yPrq)RvU zhX~fyFTdezRsvDueNDPtLgLlMSdU+HYu_#sWA-XQh>4n*JMH<9F;+3U>xa|RN~LMU z$Jtsq??h~N;rNej3bSCyY zk6!giqh*g_GM?-2pWMKQS42Ld*`hjU@eOGZPLrwMhzJq+D>fVL97%@sI?B$Ik;RX5 zEqyXH`)uxCmp8DNW~F&Rz@S}7FRY>JFEv-+ES_amy&y!Cb_@x2Lo4HRc^X+e7U563 zhRX1k!R;DE5Ea>41WF%6JF%>V#->72CHp*`!-7)Xk)s z90XvCWLs3VqrCx9c&~rfor=TqOPoYPL}T2lvA9pIGa8cV;DT*vsuLqsTx^D2M*218 z-imJS7)l~Myf5HF?WRcA?g-6v)C!Xi=if^5|LmqtcS;RN^Bmsd0~*hYyvOa>@SIvH zXah4o@_ngB#b{sM`mwC|maUgniQ?KDXVppFz4SxfAt=@S78(>8W)f7SrCQ=(!@sua zjCdMa2bEDm=JYZbNT^oFoqDx0R1ZYJgC8g$*YUG(#!=uk(GHOXBIhdw+YU?7-Z|=M z#V0*`Y3=zx` zp&ypUdR*=E2y+MF7BgbmN&Bj%E!2k61eE&1pzH>gz_SnkBh}Dph-D2G(B(IosmT-!Bm*TbsYxx4 z5JmZGWhYVa;cDG zyj7?T3vf&^-rEFCD@N!tY`h=8&7S;Xv8z6VGq*b3u#2=gnT(ta%cq#CT3k28fiPbX zbq~q$URO}=&c7Er!e0g+vs%=))OFHiQt#n)gm`=q zH_VRFAZ98IS8F@}tVP(+o7r{wBA|~Kx<(8N?~Vetc2Sl=8q^YoBy`4}#8t02bMnM$ zTQ*wmdtzP`2DL_4=LcQsGro8X#BCoQ9OC#dBJVSJmaTx1v}(`oONvZ-J;CWWYhdT! zZG4DGC%juasv}Va_jHcCdnNKumAT);m$8Z~#8iP6&#+0QRgwm^!RG)sK*+yHXRXW2 z#cvOIbtlNz$>F$wt4>zU+dtvjX^hV5X_@=9=0{q~1*e4&F922QKW#+HBTi@qf%Jx) zuC#sfVk#TCzekM1y4lIJ-e63_=6#gdlBj)HltfvA=1yCRKN?QqPLYKJa44!i5xdE> z6(P9;%7M|!2#Gj77JQl)7^)bd63KxuZirCVp5V$B^(Ok`cBYXpbB_0{Jax3FJ%j2h zSy8H}zDzIlCdRLBwWpcLo$nTN?=&pszyOAdf&L^;9$QDgIK>U(F`aaY);=wh>mtO5 zPJ9TwOXTmG-VJUDAwfk$PZR%~YmT`N8*v{jiI!Bk3V6u!1-aXj2cijM;;bg&ga)(8 zitI-u3beM^YDgsefA82<9w5Hxvc9`v4Tvzuf!WuY(}_7~elqvqD0DrGfiU_J=J~Sm}Iy3X8VLjjFz8 z0Ts93bsG~DeJ#oNd5R`N{)X)%oJQcw@EtlI%c0WL|T z3O1V0b*u=9e9(e*!?O7$0`=TKDYOGC;jmm6F2!WOsL;B@ zN%qF$itF!>T6Du3GFYSK*Dy%m#0%#ubFo-Z>gkhtAsEvPqKV?yiPZ6L=Gy^yA!7RU;QbF$zb-lDU`Q#S4x|r%wIb_LYI{m#fPT3%nuPw9 z@EmW^ROif)34SQ9jUJ->}ZX?Rpj^bLH8_yKAPZ zU0{aPzsH_zn!C4h{YHuVB%!f?gyg*c*rL6hm38ijrO0KUS3;dh3%KTzj5hIInwib^ zPU-~aZOz%?t+r&9|~Y1<=Q~vA&-QB$Q< zVRuhByBj(gW{@7|m4<$-{|1);wJxeGeM-QoR0fcus-@AhKW~q2NB=>vU4!J6BE$=e z3sm(K;swb%$E7&7pjKK3beaojp3aaEOD_7Fjca+drB__$zb5BM$_)p@ka8S3ehDt; zX=W})JZP+0B?cb81@&43qvN4IzF(*f)tvV0F=X-wWFK6e7X7&9{9u)egN^V80A+vr zD=M=4z);iL*WZ?{`OK9hMUwe7R@s#FI~a-CdrCv!)dH0eL#51xQ&2wjL;Zc`nBA!~ z3{Y$u9@b(#ib}>tOIp%HcO=lnX@oQ6_lP~Avnxqhz5x(AvSLgcJ*KplHRwJ+7=7x0 zPDLEBuNPs?KV&#IOdRIrWlmefbnl^F*g*z`GOlL&`z)z_+B)@ku$a3qb?i6(h1s-7 z0b2fO&hBj!crC|Ons3f2x6;JSEhEJHs*wE+exg2Lv=UN8N0tX46UHK6gZi$=QEu79{J^oCr)lBGOj!*zfAx8* zP%~r7c`!;@|C$uGZz3zES#1LBuQhHg?FRHl?wePdlYKQ8+E{*h(T@TI#YD=c&Rl#x zh1g%sU!#psWkBo7TuF@IWr<>`;Sx}&Ef2&T&%u-%NA7j|2nxuX@y?Mo-huU4NpOfy z?>e&hXDDBqpX!8@bdB^$kc>A~I2*Rul6&(=>04{P;*(AduLj|@dHBSbo zE@|HV11`WbwMQ8S<`7lDqbxtiiyDtBwi~k4SgzwFN?3DR1hSRkcD=9FvpNu{IBBiX zjYrGX<8G6)`fuc6vm)D*w%@1m+fkN8Y58L3q6qJ_w91;go6{vP$>^3%M)AC14uy+Q z3Ebl_=(kmNF?7$;_WD%=Y2WK?U~<;p!_c#myGWAwd|ZT7w`Cvj)z!&*&Gu;>K$ckw z!@_tNlI>82CXtU-jJFf{3plCTugL4Vz(dn%@l@4ee>V&AU#{Z^+W4prsi>XAcD5m# zqJt~{!GU(t*ea}-GB|?yiMlTm0We797-zne*WnXxK74`{Y$WfsCSCY$WLDjr28bRB z^?*3tOL8wRnZ?KGafGxL=>nAgqfpyi*$TFG4BXE)#B6I;c>^Rruuc+{Y4yntpkyfmZj|&5;yg}7yCXM-D zi{oV(*m@c$6$cT{#shr($Qw2UWsBnGzRL)h+YIOrum%;=KK^Fl))yF13r)s2oi6Xn zO@vnci>r(6I#F3li9&kNOEGObfA@m5LXMBi-n-@xInt;v4)Fo zC10BE;mC2adT*-ES(0`O(08JjZGI|)H>B!r3|t+!238NkGE(IpnGJQb*Q-(4GKMw& zD@|mR?U+VU_;`Xc4D;}F7?leniKl?9s11LXm{Xj1$2zqS+P!~|o2EsD-D($i+vR4P z#ByfKaT|9XLTEV$R@myVBQ|`-3njbz6jK$=TEy4S`dmu`vxG64N$~> zH82p{a0Xoo*&6+PJI4i@Sbr#O4TybUMD+vl4x+J>x)*y_rfV>fg{`0zqHp#b$z`Pt znI~+V)YqL>yC9A1+3YjC|Ly`MOTA|V?Q2@fRv?UWV_Wy37I|j%q*HxK`P2|-wU=Z@ zbBQ6Qlmv9z;rM7A0gaPtRDxo`8pavRIv+j_t*e~+_))lfjy2_f&chtAa#92MUYS-Vt8+= z1qIJ9!oYVN?Q5p+Fc3M{3m+Aq@-ca1Vb9`D0WEIVFg50};#JYs z5B=m?6UCnd^VB*gW&n3|2U+Px z2og6ehi5yg#`PpJ`9p)?Cf8UN9|on`R2Z|;4Bzo>0l?l+J%c{-qrw+3y}QzZwsXKk z!#c!m1TP_EafN+;gq+mw7YUI(;o-))p<})7$v>GQ;D2&zfe#roPbtF8HDkWTMMs|( zAUJLYFOq_{N9KzA$^za=F2c<0!u=*T;lUiHeo0jw6EoG`ey^U>X)hb` zYTh*T!gKm{qok80rA)%bGq`+s24Bx{ZayCgPJw1-bc3mbbIA(({bpCLp-Ws35e_K?zRN$Bf z9l9DgHTiU!o_Q^+Zd57vNvRH=BbHhPkZ@~EC(5wNAdtgCQGig&5R_HcKj**>DP_=?NQL^@417*3KO>e@WQw0fCsJ>PWv1}3A zLZY`<*+^(|D`(x)q!w$b0)>2Iemy%z4Rb34$0rnO6XX~xz`egRj%S^g&$mY*60J+XFwf9!>&EvX(}ln8G^Mp%7oHdP%& zeI$vV(C0|MZ*xsR3sHT&gy+x$pnsN?{TEMR_a)ny%Qd0k;7MwygD!iOWi0sM+s%#I zKwTuQ3k3zlxbh=Ns={qT7>TE4gQMNE>MD@7k$e{y19BiisbHDb0E_Idp6OjBibwsb zU~gY)Wxum`?p<}u*WaC!m8G-SFFJ+ql0&nmuu3wZQ$Yta1^7(FQ$CS~k400h2##zY0H^;IUBBkWxKiB}5&@(%f>cF7TRknETK|wi zkV>}h|FDaHU`V8_qg5(rpfFr!y^LruSVG`5_=kh$_Vep1+5$)-!3AADc5D2usAZ2g zFmlS}=yA1xy^|y*wzC`rt5YsjoNN;Xh8t#1Qq?R#P3SjSfAe!Sf1{=R59|D} zimX(nWhtz7Mkj3b`xhYB_pI4#FD_kQ+Nc}87)!*EN#t2R5U-W()yH9ytc|Cu z=L{L@V^AVu%@ zM=KxNMXo@_|67Psf8ccZWHbqInfEv!`lijoL?W@-*Ob8;#6uTCraLYVMVx*^)fKTq;%EMYSW3cE87#uRLs1}!Ui?#wD^v*X zoSLZlJ2nVzNW&0cHv-adUW_|bHz2e?R$|P&32{3t#)}>W!OQ9*u?a7N3s1usqq$>)(rvhEv?!(~_nKVK|}@Ll2p^DTc^RcE)lNwxx_4dY`E$;ljzkzD~cF z*4&HF za2Gi%O{9YBL=KVH)Z{90X+IvF=0XmFYOL185x-0##6sos=d~P^okSeywAOg&P*fJZ za$QucCGLviVQQ7l@#d5uCo?~17!3{c5_M!0{94MS_cD8zyK7cf2`>O*BB;toZ&+z_ zz#6S+$O68s6UIfj@=iKva006c^dJvHk2-syeWF3+1B`efd8N(k9R%ltb%EDUR&t05c_@Z z7$|^gvA{1H9LebgZ_tlu%H(o+0^beyilm)jnqCACA88IJVeZX>-Ko$DD}LJwLsj1R)rDEUl-o&I0KRul5{s#p!qSK zySW`E@w8b~oKCkX6jf6nr*3a97`}4_#ov6eqtir>G0J`lt0lzBdd3?kbAIs?~#yY~sC&(ro8Ek+)A_;8ite`tUy z*t_#-R#`Gk?{33|elI&PsfL@6m~kOS&R?~xIKlQ?lUouJW+i8R>M)|Y8s+r09`AU3 z2Cj<9hXtmb%6B{)&a+qWwNy<#RVu=sqD?k}iN_Xm#kmt*-P=bE*eq*qeZ`S;p8n5Z zw16JNWBIF$WSIRjP0Ta)`Dcg5_x+tJ^a`h50Slv&@>M;nAm+cj;e^DhzI%ja0s+cng?{YWncl5Crj0qkq^=6B61K9gm?4G1* z=;Y_Es*#cuwWSy48f$b}#JeFOCu1p5EQatX4t}7dAv39Yj|z{-K~Q8CZQ?pUBU1&q zaRm_vQpw)Tu+hJSi#+Y*sZ|v7{-HU&CX_2bxo(bQUr!q}`76^ND!QrFLQNqPJl4g> zZ83>TmeNreQOX9EbgSed;0g9=fw?qoo`b}$md-U5ut z5mk80jU$-o4JXM6oKu|7^ek?$(>PwX45z(&<6~w#}X{gQlUw9z>cI-MR8Nqokfts zv=|VvWP231GU}oSZ!V?3ak!g2E}rEQaklo5szl{b^7{smQ@yzDdiQUpa?zUK3_FJr z#rW!<_U)%l9(3$yy9Gr<5ePC5-$${Mm%9hc`c~vAVvp$u;PVfGqCr* zGf%<(o3(p2L6`++PQzKdjrvTe+J6fe$HO;;5TyKaSovB$Dw8|RP=|e8C%2u(9JcAQ zSuTqfp#PJ!%Wk|X1IpNfkSx>Nh8?=~j^bwv9M8+A}RHO9|Ld6cdhTlkpt} z!StkCtGM*w%iQ|4LqiiMfn#waaHx|VVfQUy9A$Ft`ie`Ls||6xL_R*!Gft`*6e|D&)$4Qf}@FwFI7^k|m8a%+L# zn!aJwI*|S**&G{0%F2)9iGI{+&-&#p`0z|Lbw_r7J2nJubaxhZ75GFl(h0M{iziWM`%>oHb};atA|+&-xxi|7A6ar3bJ|b!gFH)+BbC zLT??;AAo7+jHO?wXuvDVUR_jN!|l;v_M>knG3sY={J6eO7@)4OjU5{DAP*8=!&YAj zZP{C*!uYiU^zF6;k_EYPw;N33v>D>+%TQW`pg(|}5RQ+X9^7F5a!upi-o|QVZ`iEZ-#neF-i3w%Be{GHr=o+xS=DuGdXPsc! z#D7^kLpwND=##c>=0q=s>Elw8wfF2YTxM5Mc-v4fHm=w2FL1-K?+;x^R5xA2*G6l# zkJO}?H#Rf2aG>Ux+mF)oiLOl1V`IpP3zvP;t7jo~fr%lY)kJjE_nYo2$I7oe2(v_* zl)m0UmpG+QYE+1mj$_<=1fZNj=0D0;>Z(ZgM{pOb`$3S3DYgZ@>j@sP)D#yI; z2k5_dCG>4G(+4F9;=e?~sA6a6+>gVW!I5KdINjBymRj~C(;?J{)nV#$aigMhcIah` zcT)&}gd;w*x&UJJvg>dYeTJt z9!G&RjrZ2b1<-2h0gDG*0hjKt$J4H&J5H(b%|_Cp(}Mx!LVEPyLA7X7OVzyTBTg{S zBtIlJZW0#wheKg)3p)d9q$YfKEsI6S8?T(_eNwss#3i=7VM5eK6As5qdnil9mP;>I zR8q&2gk>N~qPYG^`6EB2EcMa;>laf<`@FszX`5Z3cw%e+7goKV$>YT|8zgEKgcmL( zWc=S}U1={!20{_QC+-f;XSrPq$RSZT+hw549-}-~dM?Pq$P7lmc$}kJl^7Y7Ls}H$x4@Vow$6|hrF+JXp%+xn4bQup@F zbbBp>o&+=sxx&nWHKYu&V3W9>V{;p)`x=kK9tcn+i%Z^|KS5Lg~pBD!zB@jz}{xxkKRwaj|CgAM`T%PGxeDo<^fT z!a)QNNVG1Rn8C0vakQtLqLUB0%RG!i8P*hBAZ~^hWV2U!+mKF+tVJDZG6YZqPWG%> zrw11$mzI$|*ybQ*E&h{+NCKV(CGiqo9P?KQD=e7|V*4O1?4 z*gb;A2;+82T=+N7isrIanM{SRGOIn`M5UATT%z^Ej!Ww=Vj5&8k4;Iu-0-URw0m2$ zyKwnY<$dL%ET81_(9iF7TptOC-7n?i(3$S`xVvyKuFFvdxl!w=s*?r0 z#P6B(9o>nB&5osK^CGC3?i$5(g08uR)RmmGFnvYT6l{U-!MqEp{<`g=S)_U~UwkJ* z^iFjUApw^3Alz>4d!fx!n1LkZ-wfw09`~3sc@ujuzT0>(A3Qdh?sg8s(QP2AJVIAX z?jsI_`;I$#!%CoxAMNWnM3bT=yG~eUR6cKsX}}Jz6~sNHTAHxkKEd|5p43ku1bT25 zPuKjt)zDZ4{8onImp0zI&H-_AAP_64M+T7QhhI+xK#$Z8j*tU5g?ZF7_Nh{`C`y_< z(T-#fMjv+eE|0;&ha56(=LqEhF=;e5L>CybplpctzN zmh)^wH8+iAdaO??nau|)EV9(k4fO2VgHAr`IWNA)G>R^5rLbQB4DUFA-EL|hb7FO{ zJWfE@Ay*sj?)woHq#gwf9q)5q@6k1Vz;n^>{z8+KGKvbIFy*knUh)37Rb3iMBGWwJ zom4k6TXX{UwfDB-wi=?NGB$Xh^$v-;I}MsE<;g>2{0&DGV{)06#~raCzOxrO1Mf&V zII&%Gk_>%)-N2$L{K06@K0ueYg=E}2$*QxezY|ig?hUEN4M7zgWK0741F*yd#aoP* zgcEmaN`{97WH;J(Dk8=knFSH+M_yM7CSoi@8}buougB?ANvp}M^CDHzL5?CxlTzPztsqg3($=~H zai$1k?du4n|BDncECeu)ri#Uy3H?4%gA{x{YI+QhExL7U%>PumcpjF|+Ej_Jsibdd zMfU8NtOh_CK{_CMrXu#UxIrey-kA>`3oYn0zCeVhm~Qs%H_*<02Robgd4h`G3Q8o6mBBG))#O`T}j$S(zHv znY|V%b{N|kPrQJv!AVfge9VKrM%b$BSxreOAgSD`b%&`;A8z4F><1A)iMn-I>nCN! zEM`$nC;*KUv<+)IHG-6-GODVo$Js}mW~E+>QuY7EBQG%mBJ-i6|7v;^=;NT>Eg)Py zLi^Mkhij}9WIc)&8l~ZaZ&*lFu1Iml61TWMBX-eCE}E$vfp|J1hyme^!S^9vJXMCW zd$LjFf_5qCQ4X^<&^}MIoa`GRhxEwrBn)>#2@Rw-_r3)ENdqX|Oi|LE9Bm<$+A#k$ z!6|PGi}wgcZt6S~jAznaZx>}A;!7BW6bQsP-{)LX_a~&WigXDMw;wY^{$8L^x}5S_ z_Z6ncMtG<`=U!JVd@7nm3O}S~+> z=zrs_pryckkXU>gomEj!6|>e3dD*t_W>7nMs;0aQdZ#V~J|a9{ks3>f#c2fZT^!oM zwsUv@gARIC*!y&&r=A=-lGEci>JE$ZYS z_Xid@jRoG=`d?xspf#)S+^XCKd(G@rpB?S^Le$E&)3O-WJ`7AHRy0& zL3_B3v{Mvd3=lvf&#E0SW#skDs-Ln~Vbv<#Z@p0LVPYTq^rTYFYe%hBP9zI5eFO!Q z9Ed+Afnn8ysT}UOk0(T$PBmmnZaELUEv??OXp*8jKXRI2;O3g591T)J^lYkTNO|pt zuL0xpSqo8YN`L?5G~#|Q++os>cBmiNlnOF){MzA+lLmr9_}4xLMgX6b~^2H-e3N0kX6?sz3vuorgUF(u8p1>B7nl|_>7|)V_QVgu%?J77KS)Msb z!)yp5lCoh#qnTofojm4Wkil((fjnC50ib`i{!6-D+@QPllj(pHN^%K7h(`pP{xYj+ z1B$qPl8j)D2I@gqWt7i1U%%?dwgjRA)JMx%@@kdBQALaHckSnKi)qKz3G>i<-@VF! z=QJ$B0b=xCDNNY+1gp-d6GN18lpOv{%95<)GUa-yr_g|pbBSC1fTf6x2<%aw&O*!{ zD`6_#U$Xr`n2$O5=K;WY+B|?%;Osg*Yg85q(}1ZN7bnCZOjrkTNks^T$6I)mkFQKB zekX*~$0+3gqKIb~;QXa&;V3m~P~1An`Fddpp$-TR`U7D@(jMoO)}xZD>Xvl8Q14AU z^uV-D5oC;|YR=RT0DS7`7=lEIUl{vcfvo$hR~5^Ue$C(Pzpqth(IZN%TnHa0^MFS$ z=Fq2_!++&S3P#Zx)rcMtkJ7}NRaqA3n#$?ffq4Uh!V_6nAL4Sv zk5;vp<>#F9|0=6aZ6yc0+d7G>g@TfXSt9izria0EIz)>%i;Kn+|q?@SUAsZ@q<|o42(oQ{)FKB};JABAl zx(+pyewJ&>>8S-GdSYe8`@+z3jqK=+48o7?J|amwHmHLo;~u84!pXU83mRO=+mO=3 z_ere5^d6VH->9p?$7M`Sv#*5e#p34>Mjf?EJeM17KZ(SpTa@Y7&7+M!EyN-R%>$Myn0RzgTSm>t#5Y5`T3l$qF8v;NncqtSsZDvaq$ljaXJ zM3348c|;ufj1(rRQ4e1jKyyZ`33U4ak1w)`;(+FOeg)Cxh^QvSfI>v! zarg-U1Jibr^r|zn{-I023&);2ShXNuX_a`supPA$(1{Tkg#1Gm_62hC31lcSh}CpK z(?BzrL1*=rk=F=&JBCu?SzrusRvZ@?+JwYDjj~qmSXZVFI{_VcqJ6pP#Z*gD-~E7H zFeLc;^nE{empZ?}^;kk+X?*cFuch8NB}y!!%hUiSq@IC#%8;;$K=X3` zkyihJeEjhmlwjpi>ms7So1mKToT@}}yTAsY6@Y&Ss5TB(+})m-T#G{=E>RZq(ivj^ z2(47b>Hf;p+v~Pfx^kRmJd72PM!Hpt_lc;B zpFZBI23Oa9Ewg3Si*42jUw}L2^d+^yyu%G3NPkDzC9r52fKI63%ZCK4uXK>sV}2_v z?L)ZDBLeWdw(tJagea~&>`$a6Uf1T#UIuZH_i4_QB5Y=cO9WqznhlSgwih_^2~hXi z-^Kp;DLlkzuIrCdXOJPf#V|5fI9u!*-5(k84ODncy3bpJH_ucQvA%%$?{{Xf!C;Z8 zp+Lu>iTHqt0qEdM!glE@#kuqjWkt@s`vu3EqKXg?0IqPv1W$5tONb?0yBXsB)O=|O zgy<@=cVvbJy5ek zXo1>V6~_|7BHDSh-TOLS9u=8eaczWaU`sB`m-$Pzb4q55%|1i^8=8vLXDSIOF&yHl z9|Im|YRyWcLk=o2!@ko;?^QWglO5`F>W_&epkA`CHK1g(M}kbXWm2X9gSAL;EOIYq zhB6>b?6hmwf4BYPKM$ubq44O(*g^HXMfj)+!CuN~+2o@#;zPGn08Cn>_&2OSdfbm3 z*dWDWLOcMg4zN=+OZ{RnZqtU3)OG^@L!oz4Y+^3-cCX%afm5u`2V{n-XCl>d<#JJD z*ZS))bGr8$hO1YGjX}rAp`cQlC?Lxrh?uPy%*-Msb9pD=rtytG->OYD!WWY)IQNOR z7}yMG;ausy?AiRgo;9put{j|bFhh#N8pX8bT(#(qBmU~&A$g@79Vhs{ayb~is_4f% zLO$c=qeMTSuvcbHM0>7=s9kkKmZ>ymAZY*4oN1#kYBlK zLRGSBU;G4W>$7U%2okOk!6PI-Hu$v_O&SZ}OBO_EaWD;O^!6l3;;7GXv5=y3hg9^D z@j@~4zM+?@N0QJO^l(R!zDSM&2I@|U``hy(G2s|XC(ibHo4((wSjy#{q=iv)ND)|f zl_Z&vle=N>9TAi^(I!flY8^Wz{L{{~bVOdUT}Aju|R@?R4^Nh1LFKrW5NjriPIcq`e8*ER(?9#K6>*4u#3We>C_a z^uWt&2ZqGHjOK>YY|X&H=lRMfUk}?&nPvZ34XFEJROllRU}hRf1^@fIp8R@3WyVtd zhjnQhSFq0SNsai4Qj>@VLh4}5zG1J1rxV#ZCbE#v9yTCijv8ZRP$l3a9{_nPTnb&A zuH?0y6xglJ$?GVmN|T{vF|+evo30M94t4$eoSR!=ky`fmMen~{0hixVQNN|cVzlxY zaj-$mtsyL=KLlG;4A!gRYw1*~A^d>qQBE(zOX!VVnm!IC_ueIe9SQJV9+NdT%v*Ovre`tU8 ze@rdO-||KqA3(uBP5`UPFch}h{aTmlI3m+Q-3zWlfI%>Hl<>>M-Obvq`Edu?EyWhV zkZ^wl;weq^z1gM_5F3F0@#c8ktl7NGI<{M>auPM-$Ir-WC#Dy7W(@c4*Ww8`4Lm+u zXqpBq-CAW`>J%;0IyMH?eT@bm;P}R>v~?3A>d9s_H4XVID(%Ck)9JN&okL6Ww}GbR z4vuxY#2xjlJUEL$_@@^(`fU@Eoi+8RkMe8o&rhO#963m$NmcGx0`M+AOU z43+*X)8%Oy)X_d{4Rvx9yf8X{;^6*yHjfPMrlj1bWRD;FJ!3bS3^97GBKO{3MFdC+mOriesNYj%>y@evZG2HZYe<4cpS0_vVd4C!r6%H>@D z~O2yZCz8H*I z)KuYoZN$r3o``o?2#dE{QJPRtdJ8?E!TL2|lJbgkK7H%3Y%0#e9EN$^dXH5pE^l^Y z0W(q5#9@$-)mnfo{n?>5xUx7msO2JN4Sb+MTZQqO!F(6vZy3v(+5P{)Wn`YYbZI}r zUU;ACqOsjMqgJHXX?9{-y7l|Duzajz}I7~2pl{x%tm`&giJs* zRGIf{^GLP5j~l0Rf{c>Gf?L%!gp$M(_XvOkGkNjw90y7T+NdNgOvhYn#6tmc4$JfJ zx4?Qc*9ts~tQX*Kxr{nhrwQ49(~au8y+ll86Ivf{38h2Ge${~l?bURZl|Sv z?S!1224PXHyj{-`stejl7?x!09?&R^J+B{Mx06Kfq8y)3yjNHS-~cT$CR*=zqNzigL&IYkm!P+`xvfjpeO60STEwBj`f~{8IR5v3>5oWH zI6u-zhhR?$hQyQ?SFqNo^NXWYl7=M?3o+4+iWJ!QqnbaTtC=pq24{-KCkbp0d1-9t zwIXacacp2xGHh37?+K80rBgc3|Ls!vV~tgB3Ooeu(zKqNQ4-#$I@_973LeDiI9=jL zH!!~_6^D(%we@`G2%;nTYs!e65}lue0>6J5zr2(&GAA(bo12}boHL7B1v?;>W)Bi0 zYqTU^en}snco_j0@TzE(Nt~S3X^W5%?s9p+^sJSY(~C&Z435qo;XW8|)*kGJ-s?lo zAJ%J-T_R1_zUbBmt6aBQg(rVuSm75>9QdJawO|34^m-6_#FyV9AaH<`f(w50}}uC z^$$^dJZ|&8va6d0dV!|Rl(M!jSA#U41G#m->1-jpTnX?J;2_%YW6&GSuAt=!DeyWR z!dKj!&PdOm)yMcYQWO^q{!ll%6t~mBL!Qi< z7&HzbeL}$E7Uoal-UY!_81BgQC7g3AG>@esGEGv+C!kM&2MF_44Np2{BEki@D9T4b z9+pc(b4sxI11uRTajS=CmP|tKPliHl8O&VH4qMujzQI|+F~K6AeW+Dd9L5eoNp#C6~JArAeZKmmN)3b-kj53PA-EU!JGCC~HI|{nn5ZIl> z198NpcuOc6*!e+O)#R;Z=skx(I51xN+TNRs@lLx+L2qbM?)pON>7Ghjr8gF;4<@;j zUjY=Q8S9ueoSxF_*HMlaG8t{fKT?F|kGTv79Z*;lN)npB57s|xypqUaSES1)Z~j^(qy?K@+8##4{^rmzciM4S)R2=lM?$ zj{g0cHPQ1dP?0OTqf%YBO$ewmI4sGrFy7rQp#%)pALG300(h(4f1@XJa5HnMullR< z)@2&`<`KBXB{d6EMqkOWu6A{%lP~sPf#`XL^aX^L?52e1iZxcX%WZQwp5by7_6ok1 z_N8(|GjeeIB5&$fUdE8>Y?KV6jV3A^Xk~|rY7^8%pAX!DUaeYKMl4`yn((pFN5o{2 zWYMw6orlOaOFK*>Ydd=v)F9B=Fc$?SY6%@vfbY1u5e8jJyJR~{kh*#lqm$Ixk`YB! zR+<1iK*Yb?r7)ioa`0};`LU1_{D%!jg_S9~xqZR^J~Gp&L>9}8R2a*=|4C2O2BR2+ zhAvF;Sk@?UjGw8^V7f&ALibDCtG8#FKTDCE4>4w8!4mW`3PY|h<*bO)c4r=a2G>#~ z`oK#Y%?FRFhQb5EvW2OP^SDel|2vF;zRZJlNj%2kA5(xO+aH*T9#l|kD@^^N zkrLd>Pv52&I%&WI@)rS4V8pV}xS0xL8DAtsEFs3KAl$B~QV&vAPVKSddsO&!^+^7h zU*xIHGjIw30mT@p(?v_#K^>-Q&8D(zJd;=Tw7X#Ze+?_Wj#H<$Cf1CNtD~M;VgWXU zq;rA@9T^wZuo>Wdild%Xp`B*@m*v88A=K8|NoE49Zimgi= zU<=E$q}vUQU)deC$4}Z-!llmFJQf{Hj7ld4eQ+?&=>jMS;MsWv)!pX5o}vO8?F+SZ zP6jtueKMzIu4_NMAUXK)^+q_G8{c4&bi;?Aq8%-jDEmx2bkR=Ac%%@WgDggT*ubY>kj-Jl41wI5K!172u;%;&qM&rsyf$-=e47| zSwZ_hZ-V9b$A=;T8VguL_v%V{J3?SxL4fc?q28y>A|~N-B-UA$N$N=xIUiT=ktwu_ zTC(*N@(>1(p0_ZC#jQu8WuOQ4Jr4Oa;NnB;T?$>QBtS$oTKiLfpA2hgjAE!(Hdd^h z!fBkgN6xzIA0t}qqNSdR0?xfYg=3VgAKC?~c%D#FEPjLvU{Jug*m>CzRa)ABXZ6Ni)qZpIr^gKhFb(1Z8kF?`bIt-f_%Q7iQty#p*pfiO ze{v`q>W&{4wc2!ZrxiA=6A?amnIZ4|xjyoSko@YMMT9{PjTj@erK(W|~b(|~uD5j&7P zQ844g$a|!o-VwTF(82=RG(%`R;*F#YHqU<8iI56(w4ql_b2k4uq>u8ma7F6Nf~4~4 z&g-R%)@AP1Oli3`0F9V3U5Gd7(Ct%gyt%#yGk)V}XI!5LxvS|97V=Tm%$7r@Z8JxV zhyW!+&To?0oLnO}-#8OBx4Ei+ z^<$e25Ed0Qrlu!aIdmn>8VYc>4_38-mYMx?{UhkQ;k0ZYU6IHOUuj`sWv zRjr}-4pu+XH=byVdeq6vxm1io!-@z>3e-l>#a3`OkeiIyK6Z5WDb_jF-3d+U+_7I z_F3CbSAuQeOHYp*Eh+8{MdQqd(9B^HibSesNs;%nkYEXd$rngiqIIZ_v+m4{V|O9*QcQcJe_P2%!r{GVW2nMJ~!;di^Wxa?xfjvCwockBU;ZaXyD z7|J8A8w#}Omj_5^K0i|z$MDho&E^JhX^BLQE~rvf5TcCS3`Tf`_sX((aRcdMdmBtx zOHtb_oxty0z7vt|`7K`@C;79Fr@b#!{DY6Lftuh!QTvK!II#v@hT}sINcK3{N8cT& zcinRLUm#3z>8SG9iU^(9Nz_Jfa9tSc8D^4Vf8EFH0)FH%AiRvHAo1tPN{yKS?~B3O zBHwGAdh;0Hg4~cVL%i=%HgH{z?<~coftcB#dx(M^>>#^M*#HPy6kuR{FAQVMiG8oMkNyErZ>G^iK;nd`%J zyJp?-%TLPu=;h7Uga?Sepy#w4Ovv3Yrxm>oQGkcxFzkV^@w`Mn2Vn}RP#zSnhrUM` zSCtKNLu&UI6sBm?!w1HPetz{b^HNgy`Z@&Cq*4_j;S|iYN=>_x=H9lX7C4~DbgQ;0 zN;z-j8UTbv`<2&3gY8?TRiC$gZZcQ=-^@zjJX6U8`ja`YJV#T=^gW@I>jrsmbOs`R`#l`nPK;<4H#(^#JRBL z-An;eMZxa7OM4r zSdNkL@9`G|LT^|#wzcCyL%ctL`EC?W?Ot1eET1(U|OY@iNC0izbN!?Ps*&^wxY1v{ue(nD_gb-YvjP2|oGPEbi^7!{F~i z{b;hl|MQUT8YBo-{ilKGudx8wdaIRE4KY4ea1ua6{MiYy-v85-g&NV3T=>YiZO<`S z(sVA+-?ajxe4K)YJQQiZ&xzyMXcv?PWE;?3g1-ZmIS@tS7tK~?;ZDqXegnFL!lS+* zb)?yDz#2{jB!#c482-5bMPWOG~mh{+H4XA1zYouUP)s+n9_thc%ZcrBsy4CcbczS`F+A|W`@>jBVRy;suu*m{?RG^3P+Qkfkv2~f1=`PmTEo(Wgg?A2+$-7 zXt$it&ZpZ$ZjCcR^{?#A)j>sb-S<|?h`g5GCe*dVqSKyhPuWPEC-^SAqf}$^XBZ1x zMs?LuQ6iQ9u$k}J07dzTo#FE!)-B^`GN_WGNqAzP$v%;Sh&L?y{n+jPjBoBf^Omor zs6X80H)p^dIvVsle35>{4;JCh$p$bqw(zF$v3;e}nX2#8bz_0{h+m zK*;&Ffyx->qxi6z&~JpiJ#**XDi*P}I&LE%t#EKAW2Lh7+Kl*mynLA%hx`R{Qf5n1 z)GS2xm=?EW^9OidV0)j^7^G{vEIXhNups?!I8@p<%07rBe?#*>Le4h#fhO9YLBqu8w!UdE{c8II4RCFf zxllS!p@R&qvOvi1TL@IX2QpV%e*OvLg7{kDr$9TTcy^WIRxniEODz`)Jn;>*CL5dv z{{{3MhAF#>I!sk$D*O2;^pwz>At8nIf>tL>J1$#MU zI%5~A5>OB`AEJ{(hPbN>H#}yU72+b-Hs6tP7Iup@s5=<(JCAZ5>K-_3Zk9Q^@v^y+ zR4L~uN=AHtYqALn_tg*I3E=zrp{uE_hnqGcAAE&YrTjA46nM~}HQRFd}2gW_V))NZh#6Oy5yh$2_C$Mf7?2rCxKKHcCk%dWho6EEeweHU=~Qqezl#z}6Wf91_HR7oCVd3-d|P=p>`73#_i*#CMcK|xEpf)YLRJav zwJ_gqB$h~GOaq(IyO8b{z*1Io+x~}dV>s&*rZoXa_%dFDJd@87vjYd_M}Hb_w_DH^ zB%G8CPhNuf)=+XHR-RTq0cd49>*>4vL-Ha&Aia%Bb3(I}cDG&a-aSIAU2N&aEg zS5B_J2GzuMKf}Ar$k;r6$6}I-@PTq8C>rsmPCp1UF1nu{1eJ*2jzgSD>fiiCy6us} z+<12IP`cuWJA3dOjFdy~h&aJQuRsyhS`)&j(QcCS1W}G(Y4(WAFhueo!E0T64cRsU=(X+qeb1dtB-M0ivRq`MI*v4X?kAzU9bZ>d%!)`J z7UqD3egl=zP$nsZlI2$xf|C@PedeoW5RN}flz%)Vi4HTijF9a%0aI_)kM0O*!T;CQ zw41mM5kWULt}l;TX%&>TFyZrS*giu7N|yq_2O|6InFCs*wbOfRQ~+ zCTTt&hewmm@bt7i-KoCk)2%*d(51cDymJM(!7~7CNTOYNlUOC^zN>~??upA?E>j}& zsNj!G{C#rp4?(uuCTAj8ott6DEh~CyR>EEZ>pM&aE={jirOtZLBO!%)NQ3wKaFh<~ zvt(8T>Zf(O?PuS1J4oo&;ncgy}l*TJHmNp{X$Z~9wLx{!dQjZrY4A^H=5~ixQWSKxYdo?n6n1WhiaHw- z2lLxD2t}AaHs@e~Z8ot&}UIP{LnjZ_5di0E2OPM@5a ztm#%!yE=0zz-qc6JgwS}A z|G_37=ZSGI4QDdvk`HvPd#s6i}H^rY&p1HmzNwvuBoxr{@LZPsC%8Zh4eI^ z@QgDSB@$%J+6}z^anuD8+EAp)*o|UPVmeGWSSis1(Z^{o>jyYcK8d1{6tunG;o;Ub zf)id_bTG!@8fHkI5R%ArCM)Xe=NFB&)+ob=59|P*|9S95hJ|gdUJ)5SB;Rb$PpnHm zIpG{z@+q9q4wfthia4E)O}<$x_ukNK;6@EdCp6$)+atL>N^O(Ps?+zL2@4C%8HH8v zmvDmk>!?0m^;FQ?QXkE(SpL!#?^Z*-zBy#A`=UdzwDU_q=(U31+U7Y-y_aJMWN}Z+ z>>ht;<$VvqzyH#q#bsDgWXnwY5kmJ^C9}YYiZ*60f!CVCol{%(_Bt=ngOpd!PLr8< zAQMu9>B-y=Ww}s_E99=po|wv+FZR|c$V6%kd@4){qXv%(%b=K`v!YI9gYLd?dsJKz z{wiqUKpjS?z(IR@#}A%1T@B*>uH<=RpWQMbd~+-?l$l+V#Rc7ns=_|ii4}j_`g~3<~W;~ z%7e|*?mgr6z9+k=k{AGQZ#CvVz2ADw<~zTgtkE+Z$jh$WVd&-wx&Gt<`1MnyN1~8d zZZs#$3dI2%%o;{6Bq`33ikUA;A>9Of^19Tq=^iH{XTs>wCoq2H+#ncSWYHmsj5s zSyIMVGELi@aFHUAlQ_L4J9(P$RyX8J>4riy&cohBu$Xa+wGRLmlcm zV&97}Q(26C`$2@-%vxWS{oOJcl=}MTo8Avv4Ag1~hsv&ry81(%iX<%Yd`iZ4dSh}@ z0%8`s(YPX!$KkHBL#QGBnD_9pTmX$t?c`RziVYutcV9IoBT_Wa1bZ1j!9x8Xv-v?i zlMl4A{`X$gx?o*GZ!#x|&ytL?&3*#@QZr7`( z5!z&r+!)+-t~l9xO9!T;L{I2u04Eeqm3z`SjhUI6j`Os#ioU@X5Wp3`TeXWYtD+9H zay0kdXg&8pqh-_U;ldecaT>rG7X~ypp7b)-wAcahS3I`>ceExvLdXMZg4m?U3mq~z z=Dx&<0+x~ zd|cJ>%d!ukYun7r_#&oa_5+Z<5uJc`vW@!XwBk>H1%&(Z={VwWt(eqG$% z*H8;?m`7wP5r2U9y8Vdu=?btag2`CmCp~RYxxZ>ppF)aMQKaY+W>wQ1*9 zx+b{ts>dJlT{D7}*^^vn@QEYlduM2RHmq42mDwTxg?XpW907&4L5r%~SCP8=J^@b$HGlr1#5k%;ED;+; zL#CTxYCxe2$dhR^x;*704bR{=S|hrg8?gpiU=o8y!WN zje-Ap&v}nSCg_0mH_met-({iwAv*p~??k7T6IIXk=karEXN-o9i5A8-EJTdQC>&>f zF$!K-<>k+I^igma*g_IQH1HIr()w2R&_oKnXdos|-)_!s&7$8I6|Z4*KvazO|iadekgT2xZAMpX(eSWpo`Ok#k%RmJ-l#KoTR zNf>vn+=nc0zt;i9GRd&AZV`z-&82G7d&*H-!g$j$K5m}cpc2N=)rz)Fr56Oa?ZzTX z9z_7oCn&TT;J=@ugp;}jC8;mLX{}^#S-2slH9MF|%ukPUMs;#vHwoTt{=fIg%oHy@ zCX`+OYgQ*P?DH+g>9n=Frfxpf*YT8_UdpN(g}0ZNJ8@ParHWDZVG0$;=vOmoD=h5d z=R$Z$rD$knum6pK{Al2Uy<^!kcadd_T-szPb0mBJkZ_Vg!kE&h$x9*qe1KNEm$u{E z>SRR%cpUG=NrAM_&FI|(CQVwW@N1N>I2CMvO%*51A6woqlFXHYPljgc8HLy^D6xDR z-6*&^mqxxOc8#F2)(Gc7jjwC-v#w2{A6Igi{Vnn@bFqbu5QhM#0jr04Ac$G0{;H}~ z2k>e5GRVyEJO4Hgl}(m7Mzip557LTXSl6|)cacq>0YC3xmxIqm#fXBl#V=UVYY`Kh zPL40{AR#j^8y@*1-4`k(hgQ!TosG(c5sygH-iO(J$MUTtVZ>nYIWS-JmEdu83)kfj z=U`$`hSh=v(NOoNUe`Hf!@6~`(DRHb6VM?|R;Tl)(o!$Y1TPp`R^Q^96y8twvY)5y zUJSUG$lW4)9Z9QyEHTCyY}c7r8l-AHUk%EjV^h&3b0BfTQnJ2fqAKXZC^75+N2`=c zKRAwJ*mi8|Brw2Gu{PXktlCp|ltcR?mdA}sc4+*v`#`i^nTA^p?#0Z%d1%(ti>j4E zi6RBTb!r}^KpM3d*ryJ5d@>}LMRx~+0b>Saar&3TzWvrn56Khzoyj0$@@{BzQmoeN zPWJxX3#G;~{QZW3vWLz5KFvQqq)M`yjtICkz$V@5Mm@dBP4A^|YD|h)o%y0{q#Z9+ z)2rRl&H5V7_``B|1=N!6P7K+UJ7UTow2RUa++K7M2mDZ2b;vz^t=XMq9-XxNF=@{E z(2L2Upm%Jse6MRMrnzDwE%(fkUk1-{kYjo2%mZ>SbIbXKNUjO<6oc;UJA7V`DeBwp ziUu6)tbly+fzt?ENigH+YqbL{h$52mxc{#Ai?77?IRBN5eZ?O&E#pw|M6?%DzBOh5 zc^9R2QqcrbhlTb>yB$t!c@@SYR!3XEXBcUR1Nx@W#zZJqU4QL;N1_9p&ojo>AvY~R zT)y_^X#MH8E-|m+d_m{Zk|!kf=MI-~yh8sTq-R`h-1HwdN6=k8c{WV%bqFe$tI43m9F;68@*(Qi4?DkeULD+CuN3EdvSU4fuoJ3h;TCY$Jhj z+Yn+Oc;G%;X!mq-6Xc_N+V@R9RiUx5IIb!io!#~#;)oW9WQ$u!RB2bL-Y!cgA&p0B zm4zOqkAbql@^?5B`l?Zo$0~!pH=w47sjL3r{M^vYm6jA z{g|_qHz?7O-TrR~(ka%`S!#+7Q;;;(LD8v+Sx`6_{Psfbl$}QnCBF%fCxWxF(>fv? zm$;L_CRuD^`uBBy{GMQm*}@)eYSu-PCw-V>)*?hJ9kV{I%5zHQxh$i>Ds1qCx~`F5 zTtwMF0dcR@q4#P=$?Xf}7J}xWaC6cNqs#QnAq0oNuYq~t@JWFu$s%1PS z&VawOBFu#GTb6iedeFz!G!A{Lr*>Yhm8oj= ziI#O2gS5M8Mn-UbK?3BzbQF?|Of@Q76TZr|q%VQeQXbXlA2Cyw5OnNIQDnF^MR!m5 zNZwm<)~&pKyon)mIB>~|?g_`9DMelQuUdrSekjo&za86jh#!5{hzyyFSVrm-gEoYk zWV&FkL)Bo;%l*}`S`C3iZM2Zg<<|uH*g0o2d@~JL8XN*ZeCB9k5vBki3ZFMSLGP87 ztK#VeW)l9K8DB4ji&tk8Nw_R21HkpzeOEUyWR>@b{>3TuD!79(!M)8U>KmM%GX$K5 zpr2UZnK!XGl|BPB(3R35i~5Di+?~BY_ZQzZW47HQ(JS*z1dD~Ii0@UGD) zRoFnooc&d@-Gz5@-*m?uF1^$C>C9cw{#~db+A!lS+4E#`Rk^;|zIb^Qla#AhPDdqZAp8#Z2b;8cSFmBp3WRI>7gUvlhDE43_r zVM~OyUqa9IRE6yl^Z6=1aA&K7g7iGWPQy%IaEhEIs-3WePkmd^(CN{gk~rIB@Ageb zx*@7#2W#Q`_>-b|(XqzAsvy+@w)GEsIXT0ea5;myeGGzb3G*}ZfG#_ z9MH3i3;k6ad$&<@G3@?>(V3vPat>#=A1feVW8tVXi^#17*@^jTA?P##jkPHtjpo9W zTIFw&9QYAHZz+!|M)4K$Vm<10(-j$gm&gI5Wp|!{tY))`ZT9JP{+G;MXZtR@wxl&*9`_!?AMifd1Y?R+Vbu-f}rB_8c|d| z>PjD^N-`dCcIM`BehyXl`cl7;QO&$6#ylbx(}4J0>oO~TEIuCwB4~kA!g3xSb(;3^OHM4ETp`_`8j@*@naYIop=&85@Z=n~g*f8)-LPWL7a z$0+-t0TZ?;$Kd}|Lvqt-Attc+qQUn)BI8~ zw9<=SVPp%{`nk_YAdVuvb_*nJII6z9*V>TCfo3gUkJARjKUF?ZmtUQm+kEm4Ta3~w z#f3hb!$(rDl?NFpXx+W*F?duY^nyw!q9^m6_(y(toRKyxImbg8Ie6s${uU#uxdHLg z2~ZrIp4_}egVCH5>Q(#4cg~|R;Y{%j_NHKH8|U7J^kAvsDGc z=6Np+fyaK3_cm}{A-Xwo zv?nhP%F;%+ggW=`M<&D_k4R)ib-YB?h0pW|Cz7gT-{e!(0UC1cY_wfb44hGp-gtkEC4R8o$fJ!%$+Zxk#7dR3H~YcUXadFV>hU}CGLrK z+$sGc-aaZ|a`86VF4KP|K}#rT&#er|AC;#FFG6FP;RguxBr8^sM6Dvx<(&Ssv9b*i z8}-5s9aQB16E^ERfq*6jN-VwB2pd*irFv3WRUoGhr1+`q3q2%nrS9XiSpT3GIE8yB z=4l#bKYg~=wP~oiyLJohBWF~C>#w7dNL4;qcXT$FH zD?QLqydinBI~$7%E+8vLvvZ|Z zO(jQNX5@E-IX=?-4Yvq3LecBI=!UDOOA%N22R^Fu^bV_u7ROqz**O7(qx^{QN@RA3 zKXYX!X$o z-&s_H{E`)Zn#~XU!0IasJ4YM1{id);{OAvFOd{i3-+t&0&t4=wVIJ$fcnvC~rmJz7WjSD|XseT-l1K9ogv=A}$qlJhFUp z4qKPsW(=utc3u5b{9huixV5#e(%$-W|81+CzD#d{XVvT1OIK=1ve*v#fvAE0M#4dG zoZG_%NLG;vD27`IE5X-$jfGY5(X1aT=?SlVbdz>pLYf%5+-W=SWpkFFj^Yc+^#SOz z4lq|QHG|b^thkf6vIWhFAJ3x9K+H{an+$yWBc-iHjN|@I%$X4EO`5dEY4B-(H(WCR z$!tf?SR~!YDQ)nhD$|H5Xr&FXeMc={F zHkFEbFPFYA59P?uNi}T`Yvtheg!K<7ju$&afQ?jhBof#LTrgG!V^LLP4Lj1=dFbSklv^mUudk|Ja7-SEzMuiC z%GoMiPaXe1BYMM1nlx?}Y8*;N5**K9GB_z_Yo6J0RBc~oLp|!7$c+C4O_w%+o#@Y@ zNo>M#gPhuJ0xY!BX3*L?0c^_d^Q2ZNa*z94lTg^~d9?_$;W5@sr@=Hdg&C}t#uu4H=7#pzgs(QGB9lF;6Q&YYdcx07ypS#HcHp1U!U zaOB~jDW0l>FblUt=7l$P8W_L#39XK0EI;*4(SVoL;WZPyW*g1mAk1mVzu>z!3TK<` zzV9f3+*8iwrY3`Y=X4BXnvS^A-~={EBHR zV*C9@y3WgY1+{3LkN`=tkWkSG%vQfD+tgT&y~pY~gIc&fJ3-4mu}*iclQ z!FYdxq=b*0K=ejA;{1>(86BUwM9#8kL2LndSwqM0BjCCj4&xw*$WpPdZ~Eg!79^Zt zK7xe7m0fceQ5^Ul%I(MTcz|-+-lF&vg0-0VizV+dx8WKFvLtk6avN*p(4#`m3$-`)-TS= zzEaV138h)o7N=toT7zuQ?R^;SRb;~FiOxyjHuWd942jG+g^(DbDm>V$35hV%JGUAu z6w~a4tM#*4zlCbXq`vZK3Nkz&RHSV<#f`0o5yZE!PV?%-mwcBg0eBqxxqij#zWHBx z#3INf1x=zA)Eq`C?2i46MJMo18Q%L9;Ts(pQ~$K|)@DfAbogV*&>FH8P{%dWNvuZJ z$+f1bdJ}^Se8)mKS|Vut0MH}{>ESQP&tngjA4J9*u+buqM2_qk_c(pJv4419`ZJr~ zSOFQK{oIrZN^M^`vwXxRxKi$1HBV~_lNyN_0I0L~k7?Er9CIP>R<5Ugq2J%W^)JSl-eCc=gh-`Q+fMl%U zS~t`j!9LaD&znXtA_hkdG@JaaqqN0WyF=%!MekXvv;h8y@$Fe7@1!Z4XoIx=E+jx= z!a7m*({&|s+olZ2HvseEONN+&&iu(OHc0{h5}|}~=}H`eb>)?8_*|5zv7{d_N&*Ws zrzJ&TgENm}i)`mB^X({;^*>1L8jC3k>F8%6nr(A9v#Oj4Cy8eL(g|Ea9a^>Aw3Z~4 zLrUTr`}LE-_NZ@3P{#;g*agYL(dx=qt}_Ra_t)u^-F)y|rpY8RS+%5`HHmZgMSeE7 z35WIEdVb4iFd!coD7VM|OGJV*fULSTJ1_^Keml|ROn_F`gTz^*5Jo^>>32#zG?SBOdBq)Il z@ucXD{VV^(?=q7ysx`f!cTOP=r1}(dZHY35@#O*RXLxo#fuR@i_^rv67j#s3+HA|J zQJpkx8&bFFxX0t3T5I*+mY_1pgpbUWV$*yyR zy`IYafH^p5GCR>a(y5~T@>F^PBB zC9tvv(zJn+SLpf}q)PVpy4S3aB~U&~hL$PYOz7OCUq~N`aOR>~YD`nMD~qx@olD7U z?58o>AiUOQcOe~+5q5^`warRn5O8xSV{&Ml!YCnp?j%iU*q@=(>vF(5-HqEENG@Sg z*kl@1*Wt9Q#Ky#|mG1yXYznIF(l!;4M|VSpKq+Am+CMbtC9hQS)+POo+4-L}h>J#i zuSN%_&JJ_SF?yGQO3%W8YYC-#!&qc9Xqc)roxP^>oAPQ@*u^uO{$grgI}^7A!{$&( zXl{L30k#CBzIj#OmeNe|+U{J)TH_G0#k}MF#l!^pEJ2Bi?)jAu>$ZaKS(Gf@s=}3J zSA;J9{3p|{gi3dI)Mx`DH_6yLiaz*ASG^7Ml_ZUps(GcGZb`17mRVE6y!p53zpn?A z(tBHN+`&3MG9qyQELl5tJ_?+e>kYcgdKpWfj^`NfHf$*n-W(x!+Qfo#mgs)kHh86Q z(igT1R=1onoXzl%{#E4n%l!fKG;@BtJheaUqNbvtaa}z;@*}`?n%U)o^PSv1j`MJCvM`9S5)$5A{UAfK?V{w*Fi*p{WUE%AF|n&AU7Xp>@OOWd9hkp2 zYK3NQ*NbxrZRZ&|k0X}Difrd*voNT>f~3Hiv`!2E>bSRMNc&5?gUya_ck`mREE|{K zin#Qob|JJzq#wTZePOxM8w1S<)iR5~7`9V=)N33gc_M0T^d!V&*^=Gf{{wUKtF>`> zC~@f>Ru%X%rbv&`Rlw8rkMxC4XeD(g6e=Ra3^r$=LD{BX&HuPoT5*wibSehMm)DGe-tEYI?;6a*x2H_3r zBTz73KSwZ^eVi7Z;5yyS`L55Ty473*NTg*8MAuy2Wb;RAmJ{5;SA#3)D|-hjeAVg2 zw6P36Hva`O>r8s@sWr+?`VjNRXn*-qv$xw=&jJfjJ9iA(mLEJJNG|FX7~t-(SF`^) zfb!tYB+0qt`=dr$$u+&2s|}|D6K8+?jKy)O621JA%izAx zn(xblwZZtgpgmVm)j;9DYxO z%j+s91$&cUvW{SvnSJX=9xn7LI;FV8nWpPDwUOX)9FiZ^yCz$Ep5n}areQnn^^SUe z93Q$vfbZqnjTIOdg6bCe@Sj;Ligy8P`~-p5BdKWfPiflUMEYA2e`fdFnQ>2fDsSZW zk8Qvm6Zq+^-n9sP&a|spno$Bi>?*Xp5ck9yHl#YL6wyvg>@GL5hI55F( zPW5+$zEBwD57uRJiY1@cMv-j5@PGdcgF5DrubKldG+>l-dh$4mUwJ=_6azqY7@vJ){l#%y*mC6x7s?B&)5M)rUL~);VI52wstkgq4mJAo~)7@A}ffQb-+j5?Q z<-Mm+ho*0f+Gz(#0xnlFUr0NwcS_Er^G8r)O+2w{D-Y(8cc>M-a=h z2Dsr2bu+YnuCZ55am5)w{R8cLi`>9Y8N4x1Gy~nWAY+WDQf#J^{kG8KEXa#N6JN6d zHR1R|KBOhxRx#yVxUNlp@~zXg-tD`2gB`eMSVJyuR0|tm-KFc4>mZPw%MgNL5!pA- z@sV6HYgtSU1PcxisVK64iT_1{E%3S`Vfp~(d8{f|^)`+dh=L?m!#)u)9a6dY@$VHL zhDe?j7u4Vq)S)W4G4WFaV)$_gl+i!hs15d+osB2l7N<&(9L1>jF-18XwVn0ouwb>V zy)^og$&aGF_|%*f`Xunv(5WN$F!fwkn~dU)d;&=DSG7QVH-*z+ zMrh4u!vWwYIvC<>?HC&=10iGBIG2ZlNU6O`$A_kwvV^8c%)8MfH#>$B5pS>f>5MG2 z(L-spuZ#)1qeS4ZjMQKdBkd zb*{DGj~uKZA;kz+bxg9uHbx!X5%^a*nHp#&WkdM0t%01`#%mwcfPGuTiVuVue>n6J zm>P3{Xce{798i2`i00o1O3I}mq0V3M*dy_t0|(Y|4!a*lMLNwD;&3aGKr&Mu@X|7y zu?iRn|CYC^#8*6qde|~2n#8xSob4)@4P!B^UbCO0AU<5*jE*zg=*?z=Vex=A{cGtrlB`$uNu&nRyV(9t2*XX3>>OJ z3D{1HHWV=3&To2F(B@~KSC`63j39jWmo=h+dOiN)Y6*SIt6|?*}-lH z_u6L1Z@i6sx=PKQcom(J!*);^zR%Zod@VIUcA^5h7is;qq*`Mq! z@eT)Shs-+#m4r>>OhBhNQ>PMM+o8DONh{K=rN0zWARp{DkAk*&>$qmJ?O-> zf$c+!Nc~=USo7HrP3xTxVoDa2b84*Hdy>Wj51ya*jlxB#;n(~gW@sq!NTdJI==6Nx zIE6Wc!qjUShMFjmpcp1|v2kW#Zh7xA#*mQZMown?_+}o|Vt}JgCvycLN_1?L6DO(U zXM4~f4%}<9BN92M1q$o&lP$hM(KbI*EcU)KhVZUa`I zs7W%nd(SQ1=SAW@9o>Pa;@0a++<5h%=Pcg?i2_WluQ{BEV&kr>1Y{I3e1zN>cW{f3zt;8Jk4|;f*zuJ^@=<9Ej}GDpN_5Ojl9fMtieG)UhqtpCjLg zTSUh0BpnrXuNcQ!Vm$Pu#G$VD0={t9<-kDlGaGXBkVR_h1mFJq@gyPV??sp1JmvV= zM(|}a1mWlA$I#@CqWr@fJ0*vjGk%0a=0i6~Q(2qEFVRm63Tn&DEzl>!Hfa08yl8rY z3D8&scluLvE2N!GN*xOLX)K( z7!;@N6cX$~vu9vC!J1$n-$kXDOiTZ32hubF1tg)D$_W%B4Ek5(DwG4mt-@l1WaL)xoqGU3K)}DoR%3HxAiG+nQoK>cn81^(OXgp(`AI7{M~(kY zts%mm*7SWt752(`31vmQWZV;96bBy}*@?yE2@cdhtEjdosXj4xE`(L&iWhKf$Mvo1|Q3n7Qw>S=xLTx(-G-S?O=y7&ychHvpfA_dgAzo!%4*mVVVfuVYz7Ebpz9PJ79&ptX9k)%L8 zAJ*z>s{H8R{FRIqZ=}r=ZX21S(5^2u6(mS`a9L|+-dno!-L`77yyj9JJ>3X~=b?*s zhGhrpD%&tg`WoEl6jxW-7l_68eZR*aZ0YXV&8$ajH|&h%`*)%YD#QZk6XZV;QNDb{ z?qnC;IoCdW-h3Vez~Sj!S#--#60#*J6NOea90(f##FhViRJ4eIy-e<7iVU8b_cDLm z%SR+@7}R&On;~%1s)Fg`lcl1<ELGabK+k;zcn za|v&9;%+U1Tg|UXad-V7i*fwrp$7>4edp-8J#eR)L=Rqn^EQrQ4wG_ezI%WpxOaRj zQ2!^(1thrTVvskz7X#4Q7=D{6?Ij;=K*Z7omMzG}) zk}Cma;(CcDU3J!^2#WT++WV0S9OOPg=oh~`J~TdaWj&i`4VcH$1ry=YGGYZYZ+gJ< zlH_Zaolq6K|9FUMq*-n2&tz^hK*{pPB7h8wVp8W1hui3C>1P7I zD+Iig@si;pSj0E7G_{5BXhAH4y^_(O9Vhm^jGTy3B0mhFlUgu?=vyfJ!bYD?DtmS#yPtQtIUm-AtIy<;%ZgqvwE{k+rvV7C! zSaLD2#KO$Q8iX}xX;7U#Ysr0my;K+d5adUp)!muXlx`_yyrqx4(6Y7mdnXJ~XRTg} zU5cRJ<|RfUNAR4L-2VMhGRmJQ3q#3kKir$0&+u>K-VW+m%ZK4FKMRmrAg^Za*7T`g ziwq9WFB~6XG%@sLXax@XOxZ%J=+(2iG=p?Yq3{M^I zQ+f!Aa^u7wT%eDr@;ZyJ%a!wsi&nVap~-O`GCli%psrn`f&2I@X7aY^YH5&^=&w<2 z89IPbZmhn6fRG`Ee@oKiJVtNdo&9`r=uRkd%4KMb@AN~reT&F4&K=R`n~;+?=DyF54r@9JGm`A++AJRd5VnWG=H#br^*NE z)vlhSIyBo@Bv-Gk2jHd-^D{EiY4Hu>(ox* z3P>Tls?3oTGGiGdfPz{Snn!zB*J3z4?aGp^_OH{z7^ zG7CyT+sazSbj0eL*`MsoJJ01#!^rb}xif1s{Rn8c<6n@yYQaUSfoVgJVtdj(`deHj zO`F}rzg(7ahl&RLzwIN=n*v*OB}a|7z1jWF69-{*Qom*rU-uSqwwvS_B4-2w;~8%~ zpWj2@FUy7I(8n9^GQ@ar!6)0zx9xwooEw(ma0MyCTrb=nhSKv!N{Sd~MV}z3fYE*KX$i{cWx;vR3tP%HF|?WgNAX)F~3%8PmUl2V06k*z7r2RMf*J>tAQRWjo=r~!0DX3%Pa!ci%o?YuM zx%$i?4m-KNB^u@>U%UT3JqgSjLtbTnVa{YZJ7=^ zNBu5MXplv$83O1L@DcNICUy*gQ}4D)jqexw|2yQ9CH+UQG6v)eKmWB{qaEgs261Rq z5B-X;ZW&~Ej|wU9?Xwz#hr>t9W*O+pPy0?7&feFm4iQO5vs3)s`7*XlJo1=kXMi8M z)*33r3K)c99jF$uZ!!Vt`1S4UMBw9>pG+t6$)C^>AcX-!BW{k-7hk4UJZLL5DjudT zl&W4=yphr;EmHruA;){3Z%y#0zi4t_NEf85KgVcTt?uA^+rovPHIZ@uLU9Gb{F}C_9gW?$sRcs*X&+zz)YQR%9w46AJ1b|=mm+jj*9hnHlH?ScF#Ej>bHRe(r zsI&$QvdD!~1AXYQ+uu#tt*=XyX8WDQatHTWaN%)qYqcFZggOU0knxH;14&5(@E|GE z<1L7NK#9+?3O{3!QIC{wc(Jf@$WtbGFx)6D1v-%1Ntl9&yV4nI3|$Gh%YyfY41buINTGO)Jg= z$4;L`&v(GP8_Kll!9bY~^0X5su^xQ{xrB^6N& zB*w;*R0R>*;yW5;ETsUhrb$GI9TBC?(Y`bP^aeZzw01oWny$LLX@_FycV{M?mS$z0B1-+c%qy1fiekk5C^4XoNbk@ zfqsf(i}GQW!`*;c-&_?`dL(bsmP*^Q0MUm>PEL27(l>?&E^eM0YTyc9Ej~6JRHM)7 zK1h>vjk$Dxvpj@$M`^ayk!8xdj0#2sn9fqPRgZQP{-|d4FSVPK05;J1ClX zyz!9)^fm~HJ*?AmEkNanqh1`UJx9#dAtV_atW3zAn3)S)xOHxvEl8-a;v5+|&|#Tl zFnNP*Wym|)k8f@TQwEvJr!&!HK^%sJK)z~pb}~SV1LOGX8r8J7T_p-45i+y|Zk|B` zEESi@>MsmqwnzVV-r651cZN|=3oDS%y10WfJ22ZfwN6Woyb(}!E%b@Zo6!l~yL3IY zP@~(5$!m0FCm9^IjIT~M>~gITmSx8iAPm&_AyEV{o0og)x0x+%%{%+%bj^6p{`=2{ zo?7G)_9Sp)^c<#ml_F3*a>#4Yh_Z}DRA@KxhJ`OQp(fk8p5X3F&;LI2I{OT>&BWl> z$h4ho!MF)+-`U6qLK?b2ZN^d@_m$Ld+GJ8EpB4`LVuO9lGA_t9^J6tYPo<~Yt2itIt%&fQ3e!KkX0XrYPBrlF+G&wOY~v&~Quv&J z9lliovrlgm5~sT#0k0-Vp`mL~wD9n5KBumCF^iJfP9&;c@@l{0OSU&c5>E(?2mS2h znZAx_*j6oR5$0Cnb?6s2#2eRyI;uu3tPIS?hQPenNrX~&K9BOLM^cA{&knGwp>)9 z08+4W>a?RVeQ!{_GMl}Ncrc0OmnyO3H($KSakg_x1`Gge(5GK^BEPj0a8qg>@LPac znA?Cto#Lfu;~Z;uZ;?|^CidMkANEgi1JQ+`jw1#_Yr-HbIX(yBYVEa)gJRF{`jU^Hjl{ko=K`oA9An{YbyKW)u*#)9fguQeF=!C z6G?CBihm9UypuW_bH46^8r&M9W%Rp3{SE`~q;CtsyO*$s$E12B+II~0GRBRIK2jsX zYQp<(&v`{O5&!n2_D}+tJY^+VxuP1pehJ;OIy0a*laq)CINP8%abEQt6BaCae@I9s zVe-yDHWSd=Dej@qD#YBZhhm8D)7c*;V4QG0UCbqm}9zrwm zwcy?+$T+61Y%~zF3ux!o)6Ue@mq2ge3!@TsQWTa6nx%>5{b$(ofWgpGPbG6MtaLmx zqu67Ryyq0tmBps*?U{H+OGf7|)72gdJVNgr6L!pL>UMr17pcwXAI{7t7C(uKYXR62 zYfs0Ygx=P?VNMkD;ul!@Ozt5FWI;6_k{QMewCaNupNDcC_R5fSvgc~|^Vy1-_g4|5 zP#G8=emdId=Hb_=U%4iP>x4I!5GpQIZtdg_dmeSH#Y~;Iy%9qFa%B0F#!ueJ($jK` zWbj1a^~-5{;grAhq711$;*==y_$5;s3)UBTY=1)vUCYUqh6LxE1zgfp?6=V0Pz$k~A$&<{OD530mTXjv6g3I_D)ifV`bVi) z*VfEQPK~s{fK|PSEU=INvUAi2=`~Wv^NJXv#Tu(mz;0KUyrT~TFMWOs=tjxt09G(? z%*mxdv=gw%sbGR_T&TNnPcUc$5!0Zgp$!SG!R{3#aOiMxN9tjO{x!P4I2q}|ngMxY zUqSpD^Eh^-4-UG#yIjULNGwhR`wkWYDs{@PJ^-xA}2;$e`dy7gA^4p|I{aVyqXqkQ!T_XXK=RTYk`v7ZkJF{P)QgpLS&e-xVShE>xCHp57-t41hb zc@EDEGW{TP|Iv%FmO1u5OH0OP_^&1XVG)}wy%Ut3@mZPAvCYj8zNNf5Jp_$57b zj*Io@b^!B-TjaIrT0I3_)<~4m1PUS3xs1#nX;S;zW7NlMpGd=J3b9!}8y;k3jCg4m zIJj)REx1#PB42GI=GJC#Zc_+pVH~Oh37D>C4cc+ZtS_3xYpAmUdgqcbz#xP>R<&<^ z0CNQbhYIw+p|U|~D*spp2xAKrHmf8wV?%(4nc`7bQN2?FIzF64cFkMIU5AfXBb`0=TAPOF8GpszIEm5bsy5gKAqu4D_aM>vvKNWiw-l zYw4dc%VS?SAI1+0C(*qkgbXD?!b0f@@l(-fU9BO&2n~{8rGZUyMpvIAnKHUtlDPl3 zGB82jp;3%cOxZ6ycmA6y{q&JBIpWRBp{>@_7Cs3>29|bM^La%WTw*rTv#69Tj(tO1 zz_}u6$n)9QBjidwqL6Sd!7(iNy;W-0^Yz0@k@;$C{0Jp9z3W^X0C7?c*9}D7&_GAH z{bB)lLHLez`})S;4*uJyCl4_91>fK5$xgcdUsVQum-;21gKxzWG>n_m148(B+wCPW z<{OLc#hv5!K_tIhif3JF=57zLnd;D2&u&G!Lu}v|SP!n;s!LlBCq7pWp~Vo5E?rVOpb3yW zT(oS`NOYavz|F9>CVVsDcA1=%6mmwB>*EII<+5?wVwk1l;FD*uj2YRicbZhJK)` z>So6~hJ|4B%lftr$XUX@NhRI7pJW^aZalA*`wHU%jFM`zxQL1XtyWW;ot_=f@ug== z&e+(cM=n&x%(mZp=pP1iL4jwO({F;zT2X*Ju~_E-gHT98M>76ub&9UGxd_V-;Ze^@ zjX2M^*12J6U{y*q4E>jCxOit8dB7I3A`l=CLEevL#b(LQ9bhMZeZ11B=L;kM;p5D|wf{2!YyXrpugNlj3B{1u zXm}nr>#)SCsueBh)83R(eQT~GF1=7i)R|N2jxpLlfQw_1`oD?UEul)G&?KQ=M7d`+ znYghZYE8sMX?g6GH(}^kN)+FbM69iIAl6@z0XV2xEpq{nGp3+AC7oC7oYmIJd|uuL z5P<0fu_A{K811Kdi|Gy-$C$(`WJW-2re^=+6=*lIrRc$c$nF^84gTLgLx-xA=tPoBjQiYm7o;RABXGr3ti< zvITN45w1o5c)NJ_vQzHGzC|#h{&(*K{}c+~?~CvMpVgdbBHo%F?eKUtsJ3Wgz&@Yp zK0F)hk$nZCN;-nLQ*atB9!1J5YBRg5UAq_}<7OnyEq2SuFZ97WA0d!-t|~EpP;}5m zbG^CiKOw?Kf=hfL>=Rix!6nq0AcBx*mR{tP_SGz7J=m{J8aIO12kg zDC}=|>T0FcQc3^7U-iSNo5XrWuJ3=RM4dO7d@YD6irk)1`@I0rWaMw=d0F|!;Jsn` z6=6zH8l(R2ak#TqR2stYZQ?yGzf(tpG5^~khMgv9NzZ=fkmes1QfU`@U)w5w1Xxi6 zjViX$6-#;U=2YaW?9K%6tZz8*eCn47QK$UT68~a5>;!rn-+@6D>_=GpO5g|}a@X5I zjuc1HR3?-nbDu#g_e90%(=eZANdZ*IBf_Fm0{cy46z-{A^J#eW@J|O{%sP{!jfd`Z z(O%Y1jp{1ag_^tR{(!oE;A;PZN1Zuw88rUB@EqmWrzjLKNNONBAFy^@>&XeQ`1mtK$P!_df@P6%u62O`jASYI+=1r)KLt&4B`fN zEoU+nFDV1`f|G(F`a4%rgWFp>skVD+7$c{oz-8J9Uk2-Asv?cWh1L}tY*`lD?lW18d1is^GD@DIW zrUJXR$e70T8o_l4lsC@4$F)*snFL%<{Z%)6I4e`NSY@GZ_ipK;iI~RGNRRDdIy`rr zygD+QKsseBk=Nny;RR;mdKHICWDwLv7UsOmw|JV5-R%d&sze^oPnKJw*wNjAnK=mk zo-;m20%&=T-o2D;h0#TY+Db55%eaek>O`)B4&jI2<28z6yAZ3`;owms9K~U2mYfpaXb+Kr zq(*Wd@{uK9?nJjPS8-xqKhsA%Xub0y$zp9yR``v}OQs-U-v?cLz{Z+7gO~GuSd}ZO zPn$ZcG@&Tr1urGB2Z+Hz9Gkj;iO_!h-KjFg-o}lr31}o$@0^0a59m%?Pk0*;0~YbN zyG5D69)Qw8zMZgFs5Et{FCeA+6qb9zU#{4HHH0vDW~K|JO^k-qeD`vdu&UQB{d?~W z|9N~Y2#%HKiDonJj-hwILlQX(`ul(?GTe1DH5cp%Q4#a_kZ_aLDlvSH4()5@F$U$lS!s%$zUDwT!%sB3|($zGs4rMPWa&Q zU@ZU!S)gxSO}seM(^Q$au(7`v&N)=(tCX z5l<8}RFI#PEA{PiS^*~^PN@9r^Uk-Nz|c{U$nI?^SpMjSbPWMPh=H;*Uql-hgOdjV zOsz42;~~$R=!ZGU1>)a~kBlzKQb9lFJ=Co*sbZ9JTJV6$L$T{(Xz2z!aME>iGwTOwy@n$Cy}rm+Mk`~) ztkM(5LIT#WdP3S4Ms-}tw`DLf-lG@4n3yB@AOnL;KbE)i;{!5~pn5EX`+73x3d$m{ zwh4BYk}%;o@mO_rV*9vr!Km!_G3diQCl)jIbVL{AGy=rK%87ZW;DMk-p%?w-YAFu4 zefyW!oN*sWFe^tZQjBl@m?~oqgu?K}7SYU!Vtkk_uZR%!&*m*m+RQ5|`S5x6{+y;Azk|AAsuN8b-eqXM|Zuj0E_qf+7E-$S5HGyoFt6*t8EFGMRgxbv%vU| zlyARtOcPE;J@BqH#eS@}^ik3H)u#>RTDi{FxDGnpu#&W)V<_FTX?qoQVm(2{PRGRJ z$HZT}_n$Jp+MW7f>MB};hs#BDt@Ri2dT$o6^cRD!=5*}N_v6$1{Y!`7tQNKXqw|5r z8DNAxupkzET<#JJ0mWl0-Lz=B9>r*8GR*_5TgwYh_jzI}5M1bLuxY&)rqlf$d1;h# z?2891XfmMLQi|5USf<870678bOQvEOX>xF3$5WkmKPPK66?+W9^ z2~t2y>9u7;AbQCXlOW?C&PGNM$*2c8_D{NvWzD`>ma#Mea2PoaRqjcEt<>m3AdF93DHn|X+sSe z2hRsW;eQgufqnuzX2t0`t-1KArMthZQ3$bG^;VTuNY+QE_j{=;Tq_sMBs2QFefQuM zohOENm$yZu(*uCxfHZPisLfxGpA(M#{afz6#8~C?cb`Aw^tx=)D zOXw%s(Zc2vmOVHB>84rNJQ)@7EGE)pC2*TRV$ggsF-msXGJ~HPj-7Wf3mdT(20;hd z*siX4pQ{&njvf0bzMOitGumzwV>K}@Y^ZUgX>bbxx8_7=q7T_bL*ld6X9yW+NQ?wo zoz3Q-I2Ci1D6jyzPvFWjF9s5zg3y_hyvPTE;u7CMO2z0$b3gC47g4$t3okZ->I)_! zAj}vV9wzFLHr62{pP7;&ptcd?6w_qy^`TTdOddejx}v;qgP8#tOZ>l&lQOMFK);4J z_R~V4{5f#8CcIqhdDJT3V1dhp0f6yspi>mAed*uaTgpLfTk+k}`LP$iaOHQ6B>PM;R*`b>Ryxz!zf8_Z@j*A~*{-JmJC-fNgYC$gj!@5op zaQgqndufSX>BLw56ZWdHtW(haMOs+u4V`Amdk9*Wer_fX*=5QPxsF$WxJ9oP z>WL|SPFlyxEg?8`xHj)kIm*X4YG(q}l*CYmNPH~!W?HKzPDVP;CbVo$LHKejmYDhY z$XqiTk%Tdf+<<87Z^JVGWWSttBL&wzyh=hF}1V+7iVo{lN9SYJ{Y0*Ek`p z*iq`QL)1((MRjD$K#+aCkM1c1mYkb`-lAsiMAxU@CG7cByCD~6LZ<#N>O?~k(c2kM zi@Xi}HbpQ5k$>zds!&S-O#ueG{v!Of;DY8Jsbkq-C&z{Uz^h2#Eqrh;6S}Po|E@)* zI*nl7gV?X_i^A~*AKsL`-YzygK|Wa%onp|9uWoI2Z*yJ>(fN$_5hJO;R&{y7hwu5M z3BmzZA6nNCVRNtvOg9{5t`NcIgI zX+o@>ytvKZ3_m_2bOBWC-^|YDfe{FmUW5(3)m4*eAbE<+sCBc$Z4Vp~+~86DYrK{H zI#P&eCTb8$ZJ+_m)+-cEm$SL8iPFD$6gh_Jl>6HYruJYKDWcdZEd(4@*1T$e=>NkC z>zxA=`y++yDCQfWD8r!)13{y1j*e|#PUbvA@%g5 z@R34bdfK>w-X>XnM!bO5FCd{b)gSVN*z=uEfiWH(G>xk{8iu4CN~#%K?B1P#W|J~a zelPb~hfr-eK|lGTPu6GMoO8cGSRrs`1wu)*c;T^gzGXbaQ(?+Dd}Yneb{Toxno;zZ zIUjD#DSv#-GC4ec`<&i5g+Fd2^hNHaK16aL`ED_ zP~_5(F4F|OEfk**(VztwBUXl0*-_2%h^b7v<6wao6Sgz4024q$<_#O1H9#IK)(>Lm#OGB68{iB zAuU3KlqA8t>(eHC)|y7i(9%G%TcEEnO&g)ahN5fT&PrfQOork<0A@%SzU7>ay4Gn} z4f{*~#b}QWbI$-*3n8DjHNiJ+I%W1@NLv3|D?>g1X*#-cxx|4D@0l3->6(Y`{mN=B zpyJ26nL}nAY(Lr7T@%Y&;f*LvzkI8ms~rP_@b$You>K?dh05*CW+WS*j8h335Vs2y zT@evpQRs@Sp7jH7Xa8dj`${8yQB_`b!H*z*PTRs^T}z7c&RLkM4+F0>{M6RHu^iw# zZKA}{e4sic{7<2q0yR*wsncBftCK2y2E2LWXpPF$=@|SzDnYw|>{vAjXsJb(K)D0i zPX(r%w(yyxzM3?+JXeb#9Q?E}<+G|gkV#U@x_Ie_fDYfxP8lRMLd;8jB^PmGx(NZf zn>`BY;Nc?^SKS*snH8>H)tipDc+vx&Mz@p)mtqdr1%?-ZRd~sn_>vbFTx+QH?vt|- zCr^mjf@SYWU%DB;dUHg*#$q6(Ox~D=RGiLXfa`UM^Kt&y$5#&3IL?>6kRdb`V|(yT z-lDxxeYg%FuC5Zg_V~1^(lz0$oY~g;Wu0LJe3O)Ur-Nonn(&lwi;Q=Ai5sUNBZg3n zWsxEr?J621nL7BYmE|in$hu+`f9}7Z;}<|&xmfn#p-u@C!8v_rxYZ#&j!q8RTTHV|vf8(#QK3hk$*Mwh>?*3}yHKd<>kB$DZ}JYvKHs#edlT)V}B(|%So85l8S ztcm1{5%O2;OAw*CU5Ozm2jFC2b;u22{?H&>KW|cw?pkD9cgk^Y{}2vF?{gY?3DJF5x>PPJE-Lk{W#Pen8S!G;8gZt5q+Hdd*<_^Gr-&WZ(C6bKkqR72Z zHS-=1qK=!lMNzvdi1NR^MJfG2w_O<5#7co`nqY*$Z=Ev4UE~|>QhU0|bS%x}4bmNn zu{lA4e@abS5XW=47I(pB;KV~HLBU&IzqNk37f7tt$CV64RIm8J#Rh~ipg$YQ_?Mll z3N#Eh5!RxR2fbJO<@cthJgzxI5Q^(BD$O69GIZ+4smv>v_I7|UOp*&5rA%8YN`bO~ zDLe0BTlIJ^PeF>oN_05*h6+89uIdrSRX;^47QEV&d9v>m+T-%(Jlr6Y7hrl@q_y^q zFE}n~korI^;1ym!7}Gsuu7h~UbVpQEO36_tzCdykmxJzgPYI z9UG9=Jvh?d!+lt_wEIarVqanhji5yRVz=p?Th`=0`q5(zeG}zmpV+AaQoxU831dT0 zbV!LvVcMA0_%N>Nk*|w^(Gb@zAPj1Y2A+Q6L~9xx``joV+*hpDWXn2;aR0`_jdC@I zH6q-_FA~;y`FG+O1JLy&$BgaWB~Ivm3W&{Pu&=0*V6SvF#-~0%LVw-@gxvfLQlT2N zFL}^n&IeeELrxoxewq;ElQ<}?+MU&}%gGGGlYosq#x`H}vN8>(o<=d>$dQ3QOW%|3 zwccAb#TO8qD5@5Qg)w5%AsWNp`GYL5bJf{uBa4ifW#fCLu7l}QPJ?e`O>=1Jn=qzb zkLov(7S8d(B&PEaAqhmvqMj;vwedz^Fe>b})1 zZ7V&Dz+=y3kZ;f7qkj&b!#0RfulVs=Wf=|=P4CV^R~b4~3(87wYO(nA4ng=)8>>Ri0zN;0Y3$nss0jmq zU(mWc_k}yCe;JOgb8-pB!L4Ud4n&v07XKtQwyzFz&c;829<}+`z)C(uG7Y^a7xHFJ z*_y>bq=&;7Zxb_YO@M~$)wn}Y$#Ys~5(AfXwrOVZG24%W-F=Qh-L?nC))_BHlZ}Wu zP3tENz9z1Igt)8w(>}EqPp$zg8v-Z%f`&-Xhb~5lhb>+q?3UoZo8m&!n(8m>DEuL~ zUt5@6(kdR@m*LWhV!AMpxMsCg#<4+9wL$&kVQs0oF044W^h1<3%4datK%@isEn=94 z-1Op)Hey&S&Re-w#{kT`fTnF>206f9QbHke<}Ma_(vql#V=EIwzhg2l@;}{6LZQ%{ zJaeU30%B#Ay|PBb=BUZPll=5D9Go!{t!B0bCz*zfk-DYZ&F+MEag z+oL$WaiG(YCAo6%z<;Sub>BYfTfv_U(~dNx&6i?Y)IxmDHLExc5Uc)z?~~M@MH>-< zZEFQa!^Q7&;o1?}`=>=!cmj0X<_Fb49AL7&So&sg>;4@QDvYiQ}v7!nl6E-st$JR=y~x-B$? z=+SFBjENDmpnr5fWvmX(CMQY&S#_L|Yqn zAsU%fIWq>cCZ~Y_+w1|@yPK#_#;{2Nxwer*S_bK_qw_P?h9}AG6OL-GO2P=_tCu*R z-amtd6$cvFehz>`U;IzBM&k(H;PUUyOc<1K(XL(=dpP+?ibi~QDPdh>*e#4x(a#Nx zi!f?>#*0dap8dAW8b3|hNb(`NTXU(Bu?#OiIgo|vc*GL+ zWpFP80kV^%5wiJD^4QetGRwrOs-Po31wic;x2-zrV}7Eqq<-gdB>XrABta%2X9uCDmJ?);CHaJbRS~oAA|0$(s<@ z%gsju=bTwEyX5&m?9yuV1NtSy?)l@x&t~@kcSSnXXl7NblRMx(VG7e|2x_!<>Ve#S znFdJ5cVt@6gZ49KG|Q+%U_3UGYkr0sj#XeE6cLg`4n;vPW8J*Xiwq+$0 z9aH`#8ylp4MphkaGIV+Q8c^OVa(@PfoaluNz=0I`##^xXW#o>^+C1n2&*4NEJLB85 zN)dv};{B^mX@{Q=;(xL@z_B(--vXqon>Ds$tJ`a3FY3TRoWp=+i7J_#(XL=B6^{;J z-$}pVq?`!rn%P1veLW+b`oe2Wl|PMS^V6;2sDs1YNTXy=Y78v&+uJYzZx_8PULkCK zqXFejykwe7AAAr>SAAk2^|JVULLQLA~n7pQ7->lNF<*sN~(W4?9-kskN@n5`dVK&ENk zStVjA7+IOO+?he%rP{^=v|d!Lm)y#d<_zd_o5fwwW=suffbJcb zk9%LqC9GE16mT>2%1u(N-Ps#N^_c`;g*^*of}#D@sf5otpp~k!Rj}s-U>M&G3P0m1 zLu)@mwRA2B4=bt)x!!&uRqD%wH9xpma9tR@P40!nl4)NaJMce))eQ{K%(=O>P>P;T zj_#^_{n}|_dypCV+|kOxEUSu)CKh`O~C^1X5^#0u{&+n2l?mI5ZHjwUokH{=pdDQ-RUq9wKwnz z;`w;MOc0zN$1cq{lKyhUXhUcZ@8?Hi?X~gKA^vSSsWUCJ!lIf=^qloZL4FVaXi?2+ z+B7mt587EjzMfaKH3AFI$95!bCA%DL2oJ-Z<~ImWm~L;7yLCXC(dS{uG_*S<5U+D? zUt})c91~v*U_hFg6hBChkt6TAJJC1M{M{{WLOOKP4&}{MXMWk_#ZRM&<&5AGv-R;4%ChjMxIhJ{ z1t^#Sch5_O1nN5@{Xb>6$+WNnhlhKP3Kz?oA0~AsZ|bH;4quDee3`N zrk=qaD-+HO`J?o<;3q!uklxj}Z{e*U@Luk^IM2r9s%k)Q6__^B2L4Q|#!%JohyKqE zIeq_i$5~IEt+w7#u~Q|mNq2{_q?sdu;RayJANP>XcWx`Nreh<+O~y9dzE3CuVXon) zF&@ZthN!b6UJTy7`04q3X}E1F)b}p-eoR0ui?sCZC(?~Ir1t#BU0cRY6g@YzIC1e6ZES%$1%!m2${s2 z9o7rA9=zi9j7pnItb=cq_r+}MD69YL{FB-z#mFH@mP|3~^c6g)?VaR}1Tgb@AkSoa z5Po9G>%Z|uVBfh^CI*X#GYed)Jls!Sj$H%7$~Q{oj0^IBsm+Iwr}(qE6{xa}6)0AZm5=rTRMoe@jv$I?Cmxp) z{51d2mbUoGjBz3o;!T1eO(>NNpU)F=K!O$A8+5JW&pZTF-=^aZvl2wun@9f^@QTUb z;7-T(`_lYUpB9Rz=`hKeMu)E0r5E8zSm-kypLHZ=wETf}9l-5dPh?QuUKR7o0A1|9 zU*~hYtY$4|+W`wF#@M-rd0X{RgYQYwCfL+1>Xfu@N4f; z-JG(N^6kf){|r;)^JUu8{WijiNDJ%8Uwy9+Ij|09OyMm}R1QO6r@IEgtBEq&*3hC5 zS)7;GU3vqYMA;Uh)AP{;&4USwb0qSgyUK&eI9uWpPW7 zaXWVI_UA$tKO!zrBIng%LAK;?7E|xru*El>#|ty~aP1WVi6^IZ=1`au!pzS9?E2Ry z_V?LOV5k-_O!nAJWbBf}QG1;ykk_JER#L|w#UJeq7cfJQ?TTeS>si_bE|g&lA~)O( zqhLL{hkq_~(Ht>+ZX2-n?*DUSLd7a+PhbOs(~)~3;s1H?z4@vYV?Op7`$Y5cW#yjv znUNvZA7&kj9OR7D#yg0N1le>vj}c`M8;h?G?uj^YzO$i$k3TDypkyb`Md3V8_w~dm z%<<6TTbT354Giwy!zG^6z^(LsfS_l@Aedo5SX$3vle`W@0M;r(rYUz)rfavcHwkRY z+$JDRg{v+a3a;516<%?%CZNQ+nUSsW4twecxZkriiR;-uZ%Os-s|al^|K&1?F(>$SP29jc#ryC{(4d$$3+hL=9x06?{=*nj)+xb5wFI~| z7R9X5xLL^hXy(?HeQ6MEPW^TWk3){bgY(jZ2gC41%QOkG?7}=C?na#~IV6v2d)~}t z8$)aHZ))c!7|r5A*Mu}qkI%@tN+cD7{cb{Jqu!MKM2-p^u%Oo3zs<-r?>rF%KscO{ z`VUDJr28`cx6fU9_K?w7uZviN0~_%Ez`-BNV;yat$r_~amOmF$JNFj4DnK18{JHsz z6cDp7zxQrL4(3rUMHe2q8v-%M)S2#2Bu6`)>cPeOwn)lL_nPXv6!rCRIw(w+rBxqw z+b>1S8YM7pPzLi*Wohm)*+?~$2<5Y|Tko*+Pnwjtz4M4XCWDJ0iJ2YSFnkoN1K-p{ z{S{^H#jq~tbuXb8+iA}>ZFyNc7z}4t>Fya4jtvKT_dzrM4EZOc3lngg4vygpVkDzB zIHtfxBc>rB)UYnb7g!r5lOlFZ-@LzvWF6Mc1+|LzSBSyL{8M_26?GIAZ_ZPu)lz-x zr8<(FABPxR%Lzxqbj-7J$i7p3#MIIK|4JrVf~5^4evwsG4qA^?+Pmn=;k&;(y6O-a z!>@OCg_c*YTnqnm@nPyoA~}3dcvNM0?~cYG%{SAPxte$1<>B#YsAj# z;Ja*k>%gkTiZpmJ?!M3dFFocrTTxpnKI=R}Kc48f(5qn+b~2?UR`kQB@}g5D}D zLm8C<*rJdTgNJCFx`GiS6n$bPhi!^ws!+9VC3Bq5r>X@M$w-G>E)+-6;Nb03Pkv*6 zEUo_(b|=dCk!Sn5y|Itw{F9HrBa9UnRYpn*bF&qHa>_#3(yahVK(@csIR#_cK9NHn zrxd;bXTF@UTlW0E*i@a?XwN$sH)m5{r1#%&GrPA^aa&Rnzp8tP&&}h}*4=xo=a8-a zfp|}mC9C!<4OWk1&*e=8%s;>jxlm)U7^e{^lm8LDn=rEgFLX%+v~P+Kc4pF1sNlI9 zfWeT7zrLB!4TdS>tE#HSSSOs-P%7Q&4+V2Djr1Rtgm{}$hAH?XYXQJKX{l13ut1G}GRxT|HEM|8XOvnaxWcYq1KqIXcVTdSQ3|qN z5rg(EY%?_ecW3;@&BxtvXoKE|3y1|_vA*5J*~)}9G~!EjJseLKvy{l@!8+|R2TYJ_ zPwag%CNj;nm)^!noz3p-wXR)*K>pX>+3iqc#sr9GdR)8iitOo*TemONQ5c~-j@^5q z*A77RE*eqSK=fu>hpdo^#7E+M0) zHw|HVW-A=kRzbT@L%JLasy%JJ$sB(jKGH2B2$UmEwTV!%D345!xsTF&-MYFf%?Xp)Kt9>JiVscZO@`ffM_su zk%8~>uO66x)_|@UC^b!G!;+{f8$?jhfhdy+J-=tLEtkwaaE6}8=M~~J;WwLa=3IK3 z0*p6~%PXoGMx=h2%tSI_bWnh5`iRSJT9)EV~J6Q5Lc|R9bd&c02}Z3ctBW1!T^n zH#4TOn8=yHLSbp{1r30!wbrbq5m`T$@naAmMpt3(x(XqdrAemQHjERe8)HMzu68S^ zq#S*L&*^J`^A47VRkdr}35k5Rdh6#;5uoR+QgEBR%NTZ;&Ecg?U|RhKPcz}YZORm{ zkYqB7lp;g^8f+{}#HK6_r~ZBT4w+|it9N5*F5F}fF`y=aOlU5&Np`WI&cj5c4uX*; z%lF-=Q_G#YyX$o3^D~`h*r<3Y4WqUh(A71$1V$cjK#urayAi=xTNW*mp?Ll486o@w zn5krUz@8i+u1V+u)Sc=`o6w)+ijIbh24c!AGkZwBXU%@3!yN5L4~MZHbQFtO=U8s$nG*ldW6DGY zZ(pDgwuHy;l^Fa-?TKw#Oh7%v~tSzA|Xgp=4hiu5V9C61wV?O?V9vqxv?yNn{bu@d%-U5 ze{FhDB2!$NHi;$H5zG;2iWpZSMrD5d z!_C_-$e%3Vw_6~4-BL~+I~3%iM|hN#wn!1F?~~W$1$CA#{YKP&w7=QO1i6@S8b~mC z8-XYuW?|$Wux4qYv2S!#DF_o%yineEB>bQW$?s9UeH^q4*ab-`Q|#wksF#nGgBV*z zZT&!K`!MtN7RcrSG!(L~`uMc9%n#FpuS@K0COKD#BHw4kdwe#uQF_us*yCbllBN{u z4-{t0-`Pxa@~%xe>zKa45z^)AK4pPUff4QIu^i4T<-CRv8QKI|r^ZaT6om-}jD``< zV|;(TE#5~E2g*VT&Wk%kP94Vn*hj>=>@Oqp>*CN3kKHaR#hwrN|Jz@+bu+Y@tq}|^ zq99Qzf99%j*_@RRZ+xU9aNs3{6X%9u?=Cr)m}88ouA6A_FblX zK8BPwsCszXom0BCj!$9&FVMC?RG(GecY_2HVHj+;U;&pe&TZd zW;dXL6iz1k_j#)HMczBTpCUedc1Hmo?c%HFf_eENcK9>)MRMHk89Ki=VO|xR=1%EO zLCzDcpc-Wk93<7_lYS!30xE7AtIB?|N|zU}=Q&SAz1~JtBolVPRv{|lS(sEO^v(}7*cny2wrYlMHc9y^vB|2Zgnuz#I9xJ-= zP2eoF%^NggQ2kt8lOU|Df-^HPiVm=tQN%cuLi#hE1j#!H9sg%>l{!TD#p0S!z7L$T09t;Kk!x3o%$HD{ib4n!jOxxxskzcIrlR6=&Oe33z02K zQuUz43h%8lU6l4Em)6u%n~Ay*1;%zN14I?;>!Xnagu^=5K8(1xM6z)(h|#* z;~Ev~e5mHZThL}}y}t(!3CqrK?1^=geeFaBC;rSGUp*S0?$VfBbc71jut4orB_WzZ z+PRDrh3)Ki_BM&p-VD?tTF#{CaOJtgJ9z`Ho?ArGzkbvU8VoEy@-bC};W4|wscSz> z3Sdp#okZ^yEP1W^z068Te>S33&J`b91*be^2%~d|QzVD_F6YPLtX-Zd3A!@lt!AsQ z2e)zElJ@=Kn;fxNS6N+~q(Dz)$df3A3rCbUQuOvdwhU=r5Gj3?)Ua7)WMe}}eU6HF zNjxX0^r=+NG`MU)?wi_g_zxx=9)U_~&nV(h;c|ya8>6c( z_>rVXP1U>c)8)+J*>dBjt9-nX4cns8-^g^_{N)%%Hvp*b1zwV;6=`W95nUVt_9K|c z)FVXk?}T0rh?W!0ZCbn|Ws8?Q5&ZqE(LiXnyXa)Wuvvt)avm`B_w496rl!=I!kLD* zMq!Do^-xEZ4s?0FoyOAnWQg7&0WKqj*+P3+E_WA2Q^mu!Rr|S|QAg!dyA5C{gr5O4 z@fvx7;C3-bS_lmLHDe+^FR*jca~Cj-vYPK9cXklc%sJdpwvxh31zrS*Vctd}X3@Zd zYx+`4kVehvmuK=Vr{pDFs&0(qN9U`WAt3=~W?UU+;{sDX96 zv|mZ#@7F_s7$#61j6yG=o2#nSlO~D`E>Of*s*8KNz3;ERo7S2P6c`VzB|@raAoKgt z1Y0Sw_asQLq!E#V6p>!NGm`P+EOHwzk5wIdoI|22Foq(N{#2E|)U>C3Np5;n;J6{^ zxZrc;XTCTn`%A=xK)D@>1;xU_mU9y^kxN8a*+2U0YQa@*<>}mLdiLrHE{B-y7DEB??h0$$LawSl5TDd3S#(L>SV|@W3n2wa zxZ;$dLgM+Ri#SKMk6)LE{L|{gCx{0YHChNtx6&3tgO=$prgNIfQyayBTi{z*hqqD) zzNoKTlBXF>sQvn+cGLz^Sb|xkISxFqUbbqRN!~xaa#VSn@zQ`gZk$_dsGosCZ3uNY zR4xu50(9Lo!tkFKmp-|%ONu2 zrTt40xh!-}>Ed6DHFXa3mF#x~9MPk0=9YM# zH)l%raixF#%Az+?vTC|PIGDY6@P2O5JVXMl#LA@pA!(?KRKeQc^A`wh)30A>^dHyQ z37SPL#lB|$j$R{I3+Jvc7%OoG0kJte?y%haz#lUQQMyzRrQErnW`cH|G5Y~gvhFXK z3Mnxuutc+A0=db-QTlPyzgvs|4l~Ml0vz3D*s)Wp<)(ITX3wG%V0pLCIyZ1`jQqD|5&W(9Q-!@%?-*aq z?TgRGA!4sVARfm+xlD&rjyg+U+o?4fA;TRTFp>l{lpuzcDQ#rZGXxZo?@QLO7W7^` zn(8GVop>xYO6vgfASkrZODvy~Ln&?<$7g0`rAWS!lkmcld2Y?%p1pjjs=vv|Jq$6h zQOhEq-Oq}DBZSq3wV{C>yNF{!jP-?GjZa7ZLRwmG4NhGnIA$k-=a@2XNoT!c9LQT2 zKMZDggH7G97m48nO^gPpg#i|*GKHG5lHuf7+dGO4$A(*`=sQ55m`-mFUvMMsX@r&% z2qx}v2)!`eGzD9nd`RhBI)@CYLx6ioeR**X-8Z_4KoJ-Ow2=Y$MWuUmm{<@#9FpZ4 zZaU$_n4X_3=;k&?)I$(D!+f|MaRuy(s$&vEZ>pq3Ck+z+Lz{PZt}ltb(}JJejL8iC z@Vv3b@#cSD%5s{LM1rPc%$nib2@JaG$HH@5YpsPfFE9+{3QLl>in=h1V|vp37p2v+ z5Hw9eukp;9D$)nR2|{9Ol%K@f6++er*DBw`uHZ_EKev)3EY28Tx8?Jl_0Y;wkJ3Q5 ze3TOK#QTM{J{R}LGKLJ=7fe5tuUmPH>(Wtt_O(CaPDz=FXmxcM?~4|R1G2rerUQLf z>R8h3#DXw%RV#R7I?V_#$4rlBZ`h6HWzP{cRn5Qx)ILr-)l9)Rpea7yH>wg>z!t@} zhHw9kvp(81DClcr>QXELzW6uYVT>a!DceGUk3UjW4%h{112(iC|7VhR44b@H$=p0V#rOmpMcQAUh4c3pdJt1`j=6e`MZ0_UV*NDzop~B8n&Ymj3X+ zuRVDKHL;+sfGN!eUnzhivdaF$j#oZ#Wm9lIITVA#2E;UHeCtuSpdJsO#Wkep(v_&3 zUQ&>K6yI_nmmbqiFI;uT=8oELp;%=Z&;KT9#+5kq45M}$AA1SIgWv?#sSXY~W(k9k z;s0L9vs3pArBMQ>_TIgg25PZtJR5+ERAPtFqy+c;H%@H#-|syO30RTKX^G3|heOU@ znM4PvMD_dG3iOpz_$|n=PsR4INzcsptrfi4b+F-~-`3@$fquc8Bt+ynj6?mWjs z^Afs$kaI|7+5{;#O4_E{HN~cbV#d#81;3S(O7^6m&^DT}uF0N`Xtck-$IkH+*{1r! zVLY09c@mroYV4brFYI}iH4mMZwO|CB2R%~H>u|XG5C{Nk{hXt7liJ)aKQV+>Z>RZW z4UCES0(`LP%c& zur{_CwVc(5tEppQYZ0o-Im1|=|9d!hG2WcRO8Iv_hr(B7UqLXaHU>aYXKWeob;_0; zn?QMtu-=10^A^J>5k!`te*c}LYPGWvwTw-UpQ1gqS)WTxp8YY-r~y1M!6v>S4#`LE z=z?(=7y*H~ecOC!+4fK2p-m1_dUDk^h`I=vLSwc>Ne!laqvaa;qp9}+`LW|Ro^I#k zX_nJzmcDC@&*I*gwZ`SC-Q~e5XqEh_ z%5ppnPDJV}ciyV{7sv?!tBgYUUKa2VMtbB-%*%mNa=#L7+R~~c0!VnqL?~`0Hu@?w zZUlUzlMA~56qdaZ-J86zVz)-D4ePB@a#8Q(doH;%eVU>l=1ZxvC^I5L20!5|OE--T zGh)!zHU*%JvK|ijUXFGaZJ9<*7Z>u2Vru`ypAAV)6_i?VcY2vEjVRrgoy2lo&e+-F zcTaH~!KB3ooj#!Cc{Wk10*mqw1H!Y06Jb9n`=;oE{`5g_XiFe&xLw9EaJ z-j6?2%wF)q$2s?E>EV(lh&BLTs_9A%m1tYX33@7%wemgoVy$@z-Yz9rCNY-gwLdf& zDr;t2QUP_0aXQ>U>S-;cCXWHkt|G03+)D6pGJ9;pCGB$hP)BXLMvjW*lf}_DY>WsD z5-~?PqS}UT%VR>m!#L0;aW;KHEc%Xbi^chHTQ-GpH>xihXDi7$wZ_xV)4~H1quCp8 z!^ux$}Noe*M)!GER)u6Y%f zyN6B4kJgPJ97&!4Fc~Nl<07w&ivP4a@_ZTk&xh7sAVfM4SfXd`4a1hVSJ#?%p=>&w z3&jb1H7@=z-)>6B{`qDFj6u+}TN&U<0iI;rQO ztOE%f9iX@o5@(m|Opb*r<4HcK?5%r{t}cl(Oq8^_F19MP)f=v>9^yXUe^*KM$_cBr z6V=uA<-RDezrf-HAW#O1l0#@mXRJDTkf0D3$ayZ5UevA3CpJocRSa#U?H@EnGH7H5YuZ>R2rU zheqDC9^iQ_UV}YP#Ut+oUG$BC2ed&wXUM7gRaH~DiEmHV&V*b+x9ZYhNYlCw1=5?_ zU%#b=X3XGI+mmJMpE1BNxEKG-Y7p~>-4I+=pR4NwBV}-YD3vx~l#DflF2fOn_;>;P z?zGvBP*R4vEe1EDeC4Z00HejKVzZ|ni=fhBnuQdLu4Ai})R`{@hlCGwIO*DWM~EXv{ft6$2W zk()&!8m#(ylhUMS9~`L+o-q^bBlE{h8ITsCiaHb}tq7jA35~5lz6yp==bH`IH%vpn z#t5)eY=G-l6J0@awb9n3yH0?2)BR22VLK|;UTcIn8#gae2VsHZunM;uSJDNiEnB%(wV02fv8Ju~KIQxD-KQ)t zh0O&qlye1B4qYXwAyrLPU@Cy~@}V!IV|92(&9KGDHK8rkYU)_@mn|e~>ws`AgGSE5`CqF<-33DEJz z>a|}t6s3BPaA36{WI^0iVw_2?o_>CVdL%h1ey1b_35>w5bn;bijTw?F_{Giw6fTxL zN#`&x`WMOF9&kyk8V=S`>^u>Td20Ugs6w-lB?P+;T|rbd$Sbc>cuc)8Mj) zVJd>uR{18F#m^UHww@LUBxwmI%7yrz#|EAD?T-_E+=?Fq04Ddm4(3KY5DrH%VllXa zLJIwbVQX>%~Ki)jqLhn`0Igy}e1T!;pDGwn2{lnI5iwaJ?1J5+1j!8XHfo zDGps!2TkWgQQ_W;$TnjpFno4)SO$~wC6*a;#&LxQoKY!N?Xr-D$g~9~g)J;kCoNS8 zPDG8ru+ep8nCreMc2P!#e>mcMKx_Otrb#ef4kb1KhS@b-=SCLHUD#Xm3_2$!Y|_rk zi$Z5pwH?nc;)@2J8kg8T0mTVg-khye3(=4$f3l8>EDbw|1r6@17d+*zgq;kw?;e}lWXLr zq+P#G9_LS@LtrYD`724Y{~j5^DFxmykVzzFpDn`^XRN1^$1IpPx7do-309;KgYH4`ZE^J0<~g9jt}fA-5f8eu6s+a$I$)u}>&|4k;5JAfKxRMC zPnI|2E)qYF-APW{KNt@iWLC>8^4gLLPo)X_p zlt`Y!duC{bJlT>OyyD-OZUt#PC%C5i%^2kTX`jYnP$SrDU?*PpYM_z>y5o?)R8+4p(-}=K(kjFA}?rLM>$3;J)6sp;g@WWY#!$5^C zv0Yx7N{U&f^XxmNAeE`=u@_5IRy^PYzogvLo@ip#*g95hap!np9i(@BBc1?IFpn_uTCxclW( zO{I0*YvUIu)dJk51i~()=`T>PhJxcTCj01Th?|JXzHVHEzm3U9%kq)*R1zu-dAc77 zql<74!g&4m*B4&itT3!;rPs7lXwa7V&{VDoMzu>FBs`sXG)FNtoIZAVgv+F+P)^rPK^BzaNMI`D#h0pk!s z*5nk_`Yer-6eKIqE?8d`EAbnG%NrCLNZR#*PjJWM5`lyNpXFVgum0EPsYfdt%u)OHy$#d6uN#JauoOMu_`g6F_`du;epk} z)$GIV-tz;zX~AVg&q6f8{B| z>MHY*3NgB>)=MX?L-~Yg4?q^0aUdS~+V&}3Xi}ZzCo{~!URj`2JC@$`IJ5n{@8uN$ z4yKK}P1z%T7p)hjm!e8?n2uGp{ac9eFqWE$$BLr&`4Yh`hscVq(pkjAbIL*n`qs$b z=YeS{6-v3aA5cWiXE*)b4)Gkv4#(Y&nzQcZ$0$(Qfjy3_0$t;4fV!|Tw;HTb0P(o4Wa;!p~Ffh#)lHHyDlLwu#h0}$GO zGVm;Ea^9E*C|}4Z?6HHwen$H-BQxe_C^Gs>(-p{^3WAz&c%?61hh%B~x3#~Ro=*nM zCB@G$Y_X|{@-_#*7=sJ#hdxr@kZ&EU!5v)hdNWvq^k zO7$Xrq+|Irjo(~}gVED$wOPuos4{}{+6y(v5T6PNrL!LvD>_^DI%Hgbz7aY=mpMRn zEU%Uu68CIkl)^rkYQ*OqL-#$*Qaas$H#?56D@G2A;;xy}QLT#Rs|X}|Wcj#0V1WsB zT-F}O6z5Vi#S}!dh;Gz36P$=NTF5J3`Ct_+VLEz%)Io$lifGy-QkR|$Xz2j!!-#Ip zV0FW5nvSV;IKoubPbB$(+y`{WY85m~Y=H(sC6DUmp;)8`MilxRRQdbYmU@1?T}KL8 zF&l+yWcY3F6}p9<1HeDD*D<1>(F6{fDd>y5ggWpI@-``*D{|BbhJr%{Bq|_Dkp#N7 zcDLtnHZeFHvJme5)>$yw-Eodcc++~MohAGHp#2@pnN(?MWDwq~LjJkx7yK2>6mkjY z)8u35)+`Y+WL$QqDcE!eTLA!Oh^~$ZELs;SH`KT=g08%;6L~{lkx_wmL=q^{*cwBI z@N~JD!c`eYHv}GW`0%w~kQkko{yM*Ucuq-bZ^CCGIoc7$C@l?o{4FMGw%o@j@$mg) z{gu1K`9|*(If-QfkPTp}5j>~TbW*FepS^igFK7U_f232ME?3X6 zxod(X=sOS&y2PU~MvEE3V4`M;`m2Qh#rUt4tRlW{EeUO;wcECv9F0%zQ`%yXLGSOE zyU;?Ad%gAygMjdd55}g*Zko|yNU8xZAfeiz)7AT0@^lsvu-PE{8qd}MZN(dBKmbr_ z6PxOVB;2q%k*s0wo(AnJA0VE2Z5M(Jh2Fw(GB;mAlMq=?Z0QF3S|Q}=#NSeiXxpZ# z;-gzhFpDPnSUoTSMo;jteyt5VzHO6ML{M_1PUq7<)0l^^j0iVF>xqiZ9Ia6Ohv?(~ zp5MeNYgP&*zP)}9%9#C6>~3L5=Q?os2eWCe(jSCAj@mfe8VUOno$wa_j7KEhpWHYfU>ZUy5n z?c$e_Zj$JAMO`XTs|lQO5kDax=QgfG5i(ye%_;R`mT#8kW4#+-7BOa47VjcY2sv@R;eoi|1`<%<_!R z_Oksvl}bFV_%_-FBH1R?(Ltht$3OAFv#4TI*A6y`K7J}-)EN<&$Dx_LsQScgp^tX zPaup^8)>ZWGxzP3LO?QqfrCCMwy`B&3R%hh!y@iPSfz@u@80Cy+ohW(-oGk1Z{NDrF^*@QFsy^ z=Q%kxHuMWM5LNjt&w}TwU^#Swvk8c3KIFhirv{*<*S{YEn3#Gt4h*MukixfO4;8$j zzC#24FpQ=}CQregX?Xgtti<_yMP!*q^nQm0}>6cuwju=u*ZY>2j?+TT@_8~!V{HG3+*cM&$Y17YTbw> zu+`kq5vG@_@=VR+FGGfdd^}^kw97j4;2)n8 zJ?!kMv`HUI+|6mu1+R+v^%fhQq3_@$Z`N_UMbrJwM$MmiGs-~V&Uh(~nOCx+6#M#3UHG$@I6Ii#h!4|(`7?x_D9tVZzkaY2eU5)umtK@I#h0_a8 z*F@9B%Ae!?ibuGSy}WIdkc@*G{#YZl_1MV@V#VgF1q)ivq1Zbaj&l90O>qTrkF2UJ z7)afZjn72~1p4kujBP%-^9sYpa}gl)7V|+8nRldD7I;g_}-)RUNG|0a@azei&pphm;6e<7}Juv$1g-kN{UfT22 zhg4;kC58;O+`wBeHEgLeNU$eqk4*XURl4Dh(E3G7G?{OiYF$ODsEx}r;rGFfb?hMr zU1$5{c_68$YhH4yaO)p4;Wyazef7+MP$4e&e;we;@*(H!f->iK91~FRi zBhB}9zNq)!4I+4zyj2{|unZ&jj0d*A3k6M6TRS!u4ioVn?t-3~w0f%GCqXPWc`d9R z&aiB|k&q0MXC&VvB4dqY9w?74UM~`kM1YX<~&krXm-WA`tv=LDfChfo(3# zu8*Z(pF5g;=Ou@1w&3f8W9nQZ5lZ4kSQx>m2CxQy70Z`$rM9$%f#eC_3L)p{# z;JBp4ViB9^S^3Eh{r6(hkjWE1D9KdF`-O1auIK#(Ez7>#M`d??1z-AhnvwOrjdE~kBqdu=UQhCq%}; z57sXVrV17vTsz^&C{wPC`O)0%vcwQyH?0QFTz`w})bHVdKae*mxzg4v#AaPalYwmEK&G7W5KaMQ?NiO&YwfXV%1vk-_)fN&OnAbW=*zL8R4PKePBo4>-N zm)z)DV(5mOL-$Tt2>+Pa+@+9l-aYPEAV6#=Cc&|XUl+2lJ+*Br5OGH{%&`x5FI4HB z*~h;}eXgWa z13R4u{?f>5E(+&nFa=z05JOsPoQ#|0?e)gfQm)C){KKWzFz>0rPa=Hm?d@#Am4omP z8Qu@xl#lEZzB4o}g}53M4UrOXg?`|yLa1Rt8QDI0l!c`9*VaDhFirpN`Dt?Oo&|uN z3|YFYkkPq$9$2L8Umj{u9Vb-2kEhQ$B#taAqfQImb92FQ7RFSdL==LeH}O-8P8$k# zfu1}0`6NQXraT^J&ooPT7?ioG&C=|6s|M$b+qzB^GQ`waIF5 zj+oqt_LX$pK>SKf64wk#CR}$IAB5~t=1Q;qw8N%8ISr08e?v1L9<}FFU@L?BIn@-N zVcG)cM&S1D&C#r!g?#{GMCY8jW4HCSOr=PxxaZwo_0n_3p4#vFjC6li(d@j32x}WS zM#A%W;m(&tY0G9}9^)ltUK3<}X(rw=S(DUQ4t(GEhY~-xSkPXsu}#CE-h}sP!=RCx zg&?8On`k_S%(sXQuw_jjJs!avI+InX3g_TB>gcY-eV9J+H?4b=yk~~f5H9XED$WOv zbFBP##m#Uu$qh$>ClF*LcEICuJ2pSHth=4=oT!%vB_Iw*>&xrzAsfIZpV;kB4*I>Wux*lJTA=qZ9YarDq%NB+d4(V zj4Nl=WrbkO=ZE}0-pkg0C$CN;X=wBE84G|5To*&Hn&PHyi-~+5A6~~!xfMtIY{D2Z zMPJ>J)l8!oAEBM(6jl^kBRQ)eR690MFF|r+w{E-o!z0!edz|ES;;}&QpbCbumP7~j zT%_f%X1_mJ)|x(k^biFkM3vRD5ko^InOEP)?wNEp@de#;K4C1eJSq^ZeKWvF()Bra zrxQ;V&qA-#Bg=?Fzt5rMGPcQNs`Ch<$fyU5?ms!`Z<$FA;W9cO=|7r)56ELLfE;ZJ zVLc6XS7H>NDC+)+n0^)p?Fl)V;Nrl^)y9fYR@k8YMuUzUPe)*akx?f~ntF#UPp$su z%5ng`aX}fX2F#7$IH>BrV@yj2TJ6Zr!8BRc*1ZF~s-Cp$rWJ&W-olaIs^B&eY2WX# z&y_T*Bko175j{qC3y9w`q4Wk_fn32Oi8iER4fV6m!`iWr=p89iuX!P%9dvmG>LB<2 z(u^V3utkU+j>(w_Y}eW?bp&-4n3syCp-Wp;T|3KW(TI#M~;( zXIfMALgFWW$Hf!3(l)ExoYM?@&!A2xhHHYa3G;wPc%$BO40?mizjK>X)}8*nr~-hf zV<@7EaJfYt$yAzpY*tSI{ku3C-&5GSxF(v6F6ZhaH>1u{Eifp`R)K9z1rfxJniPF8 zquSn0{r+NxpeuP@wK^3l?L_IuziPoXaPu4&05n*1rw1pxa3ZYhkjdE?$Mp10<{--olOvqQPoiU!%S-$0h0&Pefa)I&x z?M{MNyb!M&FfjmE0IH@ofoR^{9E|s>RZ=;|S#gtsCa+tRmHw^xSW?8xSL z{fEHVEnyT>^>i{-Ae%{*U4arxi_-ak8aj5!;#kMtO)KNu(P=@$FbyFRuQR2(cvGo# zx>WKwq;5PDJzMV^AR1FKr0mye_99*>6&1CAHDpgW%Cr5W>i-6Wil{9=-$>+Y5TWVF zGmr|KkA+yRapFZrBNXil93(ObJw`2*dOm#$@xIB`KL0G}WW*hx$6nw!?s|cw!zdTF|FF1J5SWDyS zDjyr6Kb}$%^tAFymv=VgAv<|6!j6?7eDgr)7KNw|anEPm#rz=){1{h2h({LH2)CZ( z&mY27*&j;XR@J2ym9zcbMZ zG#Rw~f=$##tA(?Q8l!`IVIp#%`%)X|Slv)xu>V@lAyc)D9doEeD42vA85V9z2;!AbGM2sw@S$D zEZ};wjU0#Dd)O8LU|4U&*Aq*mLOFe>!zY)KxQJl=+P%BR&p8d!YeoTd8gdZCn7w** zjG>P9y=CW-On91s2+HM^d?9&Q$tkx;&wb3h-d}ti2}x1l@C0-yZ|p?PCc;`f_zorN z&!#f2h{fv$9eM=CYJvAO)U;6L$I^RpT=E>NVXzhX9I>rSE+9Fb_Ux@q8~zd4V+8OCB_mM zhgf9bLs9n57F7-SnNz`S&dER%S0Pnq*cVZa6HNgJPP|3itdR@0ggCo2FCLQUD$-9% z^x~l_iH;~au(E)`v2+2Yorm0$7G|q(Yk_nH=gF&^enH%TobTO%MS?~tQK=1y4COXQ zKhr5z3qf0Nu%5?2BWW}wPR@ibq^WUQ1T_Jo`L=I+(iOD7?{CdBog?b&CHM+#s)*aJ zoR)9S*_wXbQ(Cd$QT_RsIF5K-j`*=0_3n_=;i!A;8a&Hb%;1q(CNZtUpNwuWpRAxj zP;LP2UoLM)`$JHj$|HK}zUT&=p<}z+4gpw((watRX+J5F+t`kZjXBtqC?avky9VUR zhiamuF7d{3hEtf{*VgzgX1U z+oiz*!J1xA{JL93ZLybMd2wA+VhSvL==oP+GUn0@N&0QYEUj{4R& zcS}<7U}|)eZKo;)x>a77Hl;q2?IP2$K@lp2C7*REG(n#(3Bzv6zP)QDVrGmZI(iY!%S+-16BrlOS z#N)!6*BZBnnG&K{z}?y769$&v(yUqs0BM7)Y>QBC^-Md5v(?Bbiaa(DIzxj8uf@`Xan9P=cXy_1~$zz;d%#VYqRdUkBZS zD_J`8;4T9rl{F_Yb~0K}#385Qf1f~>_kuoddrGs=HNbm8{XQ(%uz{!T>0n*LZCYO@`Lce-PAcvAFDYM)JpvRK1 zclKPt-3110fMkR^2(XvAJ#gP>O3;131w~F1oQ!|Zj5$5#q_6n3L4Q%^rp&>6twNKF zs@ZCA9stvQ@`x>QN>U=S*T(X3AR5+5z!;6=$NR5%RqK#0iF+#6a`i+GR>$ z=~AEMm(?nMlaS}=oADQJG6*GZgxtWp3wi)JKh_o=u|Hq~&(-llbl?E^)~n;-X3+;$ zM@K-$w-$eZf<1^yr{m#Rh!E~Ef(sH^Sk4}bW9#RD8>Dlp##&Nx%d8_rggxrbr#O7B z_y@qyUXlTHJzRRQZL@9TUn-nlzD7{#c6!yh)$$;^j^{G0R8ph4agWLo?^vdo|2{Wf zFlV+tf&iiA|I#uS;FR}TC*B`E9G-^K1ZJIt^{TvyCC%Xla8YOW>31}%lKaGM(< zT#PUIZJcd_&Yn+=Y{OZTw0pXm^_?(e+SS;OTm%QRkyhTOVF*~8FKREf)~8s>n3O^8 z4ysHZcdMG+&AuVLc>P_LgY^Wpv*Y})0+E6oRv~(XFa_GbQt>S7(u}#6Vd=!=;BRuF z_-qF?9X%egEn5f%Y!tdGCfKQhl^N9i$#Cqnvr0!rqV?im+g7K1 zJiBfR_}E>buT)_9r=Ah7{2|ZZCRw{=1>^D#;#bjGuUBRc0-C%&PK1H?j$zxf>GR1`hHs~AM~dOyuxU?#unrPiiFBP5PyYa#T6 z+a3Y|0R*`1HrR|EUX`mtBGTm1k! z2iOnw2l@adpuDF#F82*|b(vj>kM?RRu3TUs5imkXhXNRKy#dpErS4NMWAK*HYfpeyJW;n`J=LwUzuzHF^S^-vI6y;U!;fI*3EXJ_j||CEa>9Y>XNE;;vy%I+rUgd3 zx12UhET($`_YrmTl!FhQ5MP|fdvprMj9Ye!*ve?0@K|f6#el4S682HlQ|I-@4qKsg zOT@UciBjaBm`8K`)>wpuUv#T*9QJQ2Hta#IsI#Y-3tX<0HgG{B?i+XGFxib^zpcMe^?1oZ=JRM7bA_} zPK%YWXpFa;2#C4a2w0j9SC!{F(=~6ym7|neyHF#c4j@bDuM542#~^Aa83`@*J|r{Z zI^uW5G&$_iV5F}HIJu;D`uMR^Dz}kD%EPcsk=P<8v_F)D5-!yT2~ey6Cp%;8l^O~A zaPz(2wlU%h^Y|5CL2#*<=GHmHu`=L7UQso)MSF(J<^722Tbro z0e(z0{R74FdNKcEQ>jmSi{ZCD-3lAvV1hqBXPlADp;YBb>-#h0@{;l!HIeH<5rypM zRmVklU@19KsmUlSZ=xV{pbXvl#!KgrC(FS9%B@(tTQs6455A0}UdC3-A7p$@!e>{< z;;E76?#0)sr7S783Ar^kS@NuKjx z)``3UJ#UI5*78Hx&I=w^l@QoJp~w=Rcv0UmGIlBXGuH3j%jbQc-$tliCdq-~fRL*2frG#IO{#LfJ-IfNv!-h`N0Dm-cNmWK@)M|reI zlA9E8SrMh#xmE6F6?+ZWoql9q&CBHVlzt4d&%jZIW;ufv3}7S=V-f#T)dwfSu9^ott;fzv~QaQ@cxiBO!|}}67`B95Ngp;SEw4O zc$(*gj;VPC@&vWzmr1}v68_}jA<8=^dgq;!5tQ$-$ozUp(2@e94&wfiODXKzLKKe< zYrFnRdLJ0WiD-2102gBX@o>ZcyY9k(ddo*VTUNb64JW)@qw7@qClY+(y~;y%9BE)h-M z$3z)}^817h=HP|wh1PiPw;eEk188ndJOItTWm{^R;*&Zy=QC_|&MCM-ws3s`WnE`K#TQTH$Z!cwqlQok{Lu$V6X#Z<{NNSS{eYaJPvWhabl3yU zN-U*aUMwuuA{4Jt_)x0*8u+hYK zCT#&3Dx=OYRKgfg727?l>-UbgsbiD&hB^c|pW0~Snlzj=WTE~C4@afCVui^}FV*u6 zDJzDaO2;G`M?*ELq0Btz}H z0ZDH84D!38GV~C~8DxFUso%N#pjSzv+5qGckyuVuV0$x~fElEN;_ZisU+OjeJ5T~R zaV=9SU0AQM8x^PwvqN-`ut0-Fli9jk3*oI05w+GvrRc@B;3#Ge)g2+Y^3PPAE-7Fa zC`VmYf;i*WBscgtNE4yW-6G(5#`0)aDs2^r?m#Vm9vsqpB7Z~lPtY`>dq_*=6vjRO z;&#V=7o%^DxHk3wC?ioFbH9!ix=Et0jCF{ClLActxLR$+?KM_l;WK#+lzvImXF6i_>L^-Y(HR3H#4gw5+sEWr^;s;U=2DJVDfyGB;#5A1VHWfMi#4c>qDf zj3Cnl^(8~@pu=8{T4Vp1m}koCs&H04#$8AC>7D>hv;Ss!n9d3@CSDn9`1z=eDma8x zL!RU>HNt_*J0)?obVRVo>ZJILt-%s?xxtsV;F+FII~nj@=m8cdos<3QM9s5hvQOd~ z9_7t_9x|4&*yE;*I*yo0U{bJbF$ z5T_z#E+z}a$ol zn|#Nji!U$y0K6!wXM8W~W(jg>cv=><_Yh_ z7k<%mM4LuppEG!f9zrq}q$PS-s1K8DTcadFfxz3i>sj@w7%QBz?RHl)PA1|}e8|mQ zB(D@=9#C5Wvlh;RI0|6JF}nmF!TyxHVQHYF_wS8cf;%R2-?2D1!@eI%V3~Y$t!SCl zJDN1fRM7^h#~g1^GpvseR&0_}yK_W2J|@2WC}cErI2_d|7{UJ%OFrRC&^&x*h%Ncq zs>9D9fh73cEyXgGI4UlQT9}|;xH}uNwEJmd{EgssQ~Bzw;(lzfPx~KDoG@-eg=a^x z&e+Hon`Km03b*c_WSca`Ypk`Pe`_yuZXL(spV^|jI*nrI<}jJJm#63E{uoV0mc|V> zom>*$zb8oRy5rRbGV({;^(#^VCLJI&Z7-Vmk3Um(xEENYk2eg%S5Y>(Pc6m87j@i> zQRb}oBJX5+gumv4wBCvO;F4HH2=&wibKlrmmaC2qA^#iC8@FJ+Ki7*xqN(1r5nUh6 zl|`L}HAtE=4V+ePyL~MU4@ypolHXpA1IAR*T8|-?LdlXXKk{NUA(41MxnR9t*L*>et90~_ex9IX%BjB%w&hID^lIm8t zxH0@^910Q{Dg{}suH&Sh2DGz0pnu}lGBSvL-49!iliOYV%Ph^(!2}OjI+6BKO~ov;<7B zfBQpk;p?Z;ief-uA|SQDKh4Cp1W~c_UUYutB2|awqi&NgJEBRj^{>b&1WhI0!*J1K>lUJE|tr_yHcw*m}^27 z!E_n$ja8mQQJ*I(ajd$e4I?C47**pLiBV9Gw}jpN&P`fOeWbDv*{7ZW4zs_StW|T; z?sQqhFa58N>f20$Ew{?z6Ge0ya?UIZBsda=K?_i%y47fz83iSb4lC_f7wgr=`aLK< zyl(Y3qDU?tL$a9^_EIBW%PMP=Y~ZJ&SXCQ6vCAX*6Vm>h`&&Yvd6=n05pc=f=o;>o zRZO-!iwhyU&OR>hsSc<4aW+eA%NHLVZ*osY??-l`LurJR8yB21@O~|>q){qB#E~MB zPzbzR)UP!iresm5H8B2`@Hi*H-l24hM#s9`$4}=F&*)QQp!7ihHR@*FcZ>QBObZ!Y ze%?}rn|Ev_z`+TIvid!A)T{1}^<+EAYdQto6*pUU%S7hjbnhn237Sq0}^Uf>XIz^p92c`)Tl*xd~YrA3|r~30T#0L|M6*PLpE1A5$ zN?D&dcAsppEIs)!`1*JSun)xmV ztGp$C{-e(;<3QokXoa7h_S5T>MUb)juLm=i8W{92p&&O<&s+7r`}pUYRvF4)?{Jb z=#zY%UY-0uZ6Ni&m-5t$fPFLI)g!v~Owtl*PfCia%?Ude*yN5b2-ENB4Gv)Qk^yWa z;ZF+gj!RGhkRKa4+VO$f8B(ex>i5B=_IqD_u=~H}Wzlhl=ZRsHQ{x#ztSgDE{G+R= zy71I*tKa3q!Q#Q%N?J)+*g!E}*KC22vl;3?CeCs!0|(OsXv@fG33<-dK!5Of>D;}B z-liONk2X(yR3)A&`(^!w=CPa?xgKvbY0g4KP!cB`U9oGR5xHDO-?z>t>2!n#xoLZvODa0F#9wZfJ?@)#Q;w&S!?Qa`M#15cK<#mC(%$OMg8dK>+nG59o9 z0BC@f>)5qbir#_BTaDU=s9sGADkT95Q|O_f>NWnf{~KeK>DaL-*eZw3`IYr<>3s~B zeb)>vyGqOXKGQR~&jaZnA&UWgRItX;ZlwuG<}b{ctimK#eakaGIU2xn6DlDEW+@!( z(a7n;db0!@)AM|8&R*Z?nxa+vtPhW@0|uotqTPC1=+C(Db-kaF80G^OznRjbRrOjW zgz?F*LmvV@nlVB1+T1xhkOS`*vC}cp(Pb0bmEblEJmI`F7h2)|9Z3j z#DCBc{b=FC@vxAtQ(XfX1ndQQ`%s8TKoob$vZ_g1kP2hbMsrxVKElAKe_;M&HDygXha) z9NfCg1RC?X(OF~%+?2WcSTr>|NYDivWyVHbc0{ESr(dj3^O96w782P=x^%7<8}Uc zZYborbiEon+1DHB;tQ@?3f(7e(0%~8=xbP7A95($M%dArfa?=gJ2sX%RP+qza_W=~@*a1`URgi-NSx!yp^wv;BNgi-1;JODRS z@c+kjSs>kXqgoo*4NFuwcAD%*x!!-$oJEo=oJC=Q;->YE?scdS0xu9_urMv`GO;j4 zYP^|P;lmn5KdSyyU)-#$*}@}#JUWZzCu@@U!Y-eALf7YRMradeq94>vGMHnX!o90) z+@e?364$CX;{}$uikjV&G#YK0)$n3zj>O!jQ zf?2hxo_UV%2ew3_UG^;eqcYAWvWnbusea`_S9C6qh#+vv09^5${YB5?+bwlkEMtOxkyV#ayP2D(u2%pT=b z+2r?A2ec z9Z3B6zrxs02nUu$GU^(jK!7$t-qe6;WK6@qTGmdhxSq!zR1+V$9N-dAY5m)p0*~xz zbv%QF;+mm=ZKj?~VWkoI^>su(3TVMky3S3p2Mob+Friy09Em*6o_Xth#>yvt;6bSn zxhW$tQjie%Q^}bQYWwN@7qr8T`|d`7k);5XAOfry({tsMhH?);0O;)}nKMg)edrLG>Q_5W>62;u zMIyE}ivKhXAb;0WI0WH5We;c`4@Y@ppjo{Itbr*ElLNw1K%ti>ye75!a%*vC@tGD4 zXA{v#J|0p47XWznt+xT>kC)V49MqEg>{X?Gvd2f__+JLLKLK)rQRh5*R4?V%Xjfl) z0brx*B)gl=WSr#Y7;6XKJrGsKCBo|Wl69_fHvFN3V$gT329}wf)#OmdFI2+kKq^Um zwX0R1+o%(dl&r&LM6iOEOl=jtXk_|g(BpoMF<-1H7p0Z_wx0HV$RASnkp-wm(POG1 zmRR?=VW^BWG0s}?^;z1c4MdSMW{;!)k+rONr_avo-%Q1+d;+tkPDG^zj=ofaji+f& ztBSbRbhJ3cLL4$AyEgidKUoJI7>hmJVWvebGlW>q)C! zpp7AT5Z*R&YXPc@Jw(s4UIUGPIsIf~{)-M5 z3vc__%{J=1k)21r1))4PgRJ8amj=Ohx`D=m#wg1q8$DZB5{4*J@+X*X=ID9HhqeB( zUO?#s414EDwG}YX@cs8{vpC>(zNkP9F;7ac+Dz=qe)K*fhhiX;Ig3?bj%P+j9>AtQ z{$XAkCIf4Rg2YNBFI>1q&)-8!XfIKktB+<1BF9w5miLdPul0U#kR9IO+fSDrLM$)5 zF0Z4_^u#3oPRl)nub{CI&78qkxKji^O_A%-$=&N6cVfH9-g|+n#gVFal7g<0BZJnB z@p{UH8pjs%Ko?1jukM=ZD2XW7ByK&YdhTo$E9b%oP)r?)K<&j>&tC*~1-3b!ai717 zhQa|nG<_{T5PnM~$}FP3G4ZK5>*lm#=ZjBbKC=@vjs?-=o+|nU*k@^Dj+WQIxP6- z%Q8s<#exT}S9YB`Ve0qE{qbyH>%xNOpNF{U>b8Hp99iK0JtgLl5 zgAg-}<`j3WC7ze%yRmS!@E29j|fV8yQ^X zrOc(D7Qd`c(DyvLWH{ReeT{!MUXfj%RHki*inO9Y4p>&kiSN8v zQglg18eZ4OKlOb+S$LbS#lF{N+d<<_tSp<;qXZ=D!Km-^_yaW7w^KY32R=v*#4WC4 zi+wp=N^UDmXn9Mif>msyEn?I&E0c}zyA4tHH1$$C!eq$@9U+_CTka3e?haU00rzNu z7vCu&aSAm?Db$QVCkaU8%aen=6OZqeumFsgn1^y1bi3!~+g73pbDiutU0PP`c;zvg zAB7tgVL7y(aOGWbr!DZS-%}Sbe}-9-)U>2rlNcbFE<8VE( zWymZ(uo-AXK>{H$AFSFzVB~y?0&lGskbH9}NDAp~$*a^RLXvF8^xD}mrRb5D86eTv&i&{FBn z9wE4+ZpcMk@Zce<^~)GMm1b7CHBJCrFj;+8NDt|+?<9jCbQ7b$HqqsoR-iO&eSMj*jogK-~MyXKZfamUgvTP+{+oh5C-Jdq`dk5*c5qTy{@ycn*T z^!2_Iq~C&?;w`+q*N3wmBk=!x{|_#m&_jOxGh9BHA~76%ze_@kjdAwMtqCUE&{KTzdGo#Gcyz%No+h3%n^t` z-GGQ@mj&%I*(vAQwDoO^!=l)#g6Z(w;EP97l5g@;%4M#A0C0b&JVaIz6WE0LQS3r# zE$Oc5--Y;!pwh~QDov%?CD#M_7xj%iP>Y7Hi0b^agmULbl)RIB;b*KZpL)N&02zM zBIWU@z8b628`Y#TrC>%LS{ zc+Qw@H2h(qWV>>W4%OXCc}d4-HNf_MEOljIrxn&CAC@Ab^I5RK>~lCojyL4}f?71> zOUE?Nx!CfWP_Cgwe^*BCVM^=X5w?tUo8W}F_w_6rNWg3QtYLU&Vm0O=jlUSh^fzs% z1+p<^*&@JmK$YQz`!{E$vt>{I>b!!bLcaIj?C<7l1Z99={L`u1=n2RZugU+B6l6!3 zY##S94AUh^S34phDy+J4>$m4w2=A;7YIi~jkRcSq{su`P!uSxpWF%?7UWez*`ZlxCO zr#Nta04z6tHDmy^fKXe}XQAOs-XmlYvZrcH$`|2AwMsP=2tKM>3^+@JfqMblrQ&Kh_8@p)j3oVs;u2WjS|* zqaXK28xT(t+|(Igfjx?~ZnBlGX%&YU`;~~{&BI8VQ~7)I=~Sh`2y_Mx5U{%pSn3g& z9fDR2<%Tsa^@@vWzuQNhz29>j+ym;NVJY}sYUlVkJs^5;?`>#0r3lnT?i)z^?j|;X zXgo&a&a-JGFT@p7JVs)HH-Roq*cqQRO&rC;*CNGPJr+b*mSwKatGHH-8PC;Og<>1~ zv2Wv#zXt~Wzl%$AXEa!xB}UWm_ciJ~mDuqQTh`+23m+6I$Mdta)%S@rwLF#T=qW~R zYl9|MHcH-47wQoCN$4SebM(6}#(u2z31X|I+t|LX`K77XwIpcA9j5mveQ@fTsmcpR z5qHewk{nGJd%7*Z)EH)~OFVhfi|c^N@VGZeOEQ}3O9IL}s4^qusr&8RGNMCPV{W?0 zaV2MyVVNrfw^Ud2$>>VeLL|DgHu+k{kb>~=VI_7~DyUIUD+M2Y3Xp=DjRkTmCXtdN;AI2f4!ijz`IbUx zApXc%`dlEVuU-Uj1NN5P*BG8@Fkh7W|8mcswVXY2DGG6XZ$(1 z5-9HgsQVOR85VUY8cfR7m_tc}J!S3y403z`AlR^;X~HE~o1gjU z-Q%ck(f1>oQNXfw)+pmrX;1!?zn+RpDWYe$i}LmJ3jR$iQH2d^v6-lgl^CZ;b-D~g z!j%=~YoQPu4YN$QzlE2(>*L#>R2cp|C!>7o;`VH%tAiMBr&OY9?}_$i>~jU9 zxzX3H7mb}8uD7|xS*c11%xfYwWQe&b)YrroR?K`qqviqH+NP~=PMrsOA;x@L!3h|s z8P-(DfDS3M2I{%z^`*`cNEh^Fe0UJU-)2;+7BgwRr%rGW%pJ>0EWz1*Kpq;6Fyxo1 zuaSIMqv)l#cdHU?De6)UJZI!dt+iSR25_>n`9Q*MzlT8ckEo_*Fix=phL_@o*J+JeJcDn|O9%~6;k%P2Jv7(o z3NI1(-hA@4|Ey2BKPCzT465Ej^q^r4?{3pMu_qT8F8L_D*b2Aa<{B_TQNY|do~R?r z{nBN)?tzu~j?4(|62Sxu6_MXDkAb1Uj>pE!+_xk%0Bj|^ zI~McNZP^9b?Off0sx$Gjet%D{IugxdVxsl@BNx@{U;tfBe;==->aqb`obk`Bke3vj z%Pgi!GE%J^oF7!*M{*_wAY+1W$+|-RGFODdp#dLv{!)Y%0I@xxY*clhaG~x_YqfHQ z+tsN>WhVPPj~U))4UEXc1+v}l0ZM8C5% zol#~kvs(EyI4A(1cw(1_U~cvjb7BsbVjfi-kmh@`hnpX~{UkVr=YV~}tS?asyt`UE z6s$QyIR-=-Y&SqkyEPFN+GCU^wtPE^6t`iK(y#8KE>7*)`KA)m4Tz#F+!d)g5vCJ3 zJdlNl4{U9;rz-zo9FTD+&NdR94dE!TgT~V{F9V{wb9Go7qi6Q9sfQA-|MVKsKK+h# zvJ9H4+=CY1Z(SJhIf6ksb#k1vXSz1aA;VR~?kmoOi$4Zd0f=wNIE{mFL3Z6!iCL!{ zPX#G-j!qEaIms_iky^9D8k?MtOXt&G<2kS|8+fw4-q50ZnJtfFg%z33FP?5>OPqg& zfF6MmqG&3$LpDTC)doYjjtygNjou1s6hdPaGH@a`s$TLYsEdb(6NbH5dLlO+C=fir zwnI7IO|`qPCSzYMZ`+DqPITc|@z0v6vPh4Shwq?|JgHoa1>RQqf+2dIZx};H>AvI`Y3sWXZjg1{ZWFntnB7UZnjLj-o_!LRPc(S6BJ%_^eh%E`rU4qUPdm zdMofc->DJuW>`eHMfly~-9SlR4iP3dY?yZ<7xyX*Xmdoe%nT1txmTx*LoH`=|GoWV zM$Zw>(Ymf2_t>576PTvjAC{(aGW0hVZM_)*|Gsz`HZYM-y#D{*K`)hhvjVq?JLa0D zL=I8;KNQ?oGH3LFXhmo*v5`Oiw(lt~QfRFi#@MtRFJWK8sU`S_H#FXHMWkE zf81iK*eiJt(8c_DsVuqNc*vPL0_)j6=r=vTU=?%XBWq!<4;@+Lh7i3Jl$sWUBzU2o z>hQp8l^Zym8^e*ig?qJE???-&S`2TiJFjW6-rj{aH!X9m5atz*x&q&DIPr1!r;N7k zHv?<~EVf7YtmJ`CxwdxIA=!E_LM%CC$lI8RH0@$jWBbwkTf}Ha2!jz`F)QQASHp~3 zE?YpgbFrkk0^u=flzy494}0s7$QLVS8`gtbBJ9g{JnqP&2J>zoD$^qt@jO=PV`yZn z)#fH#09?LIiaRH}=A5M|)!c8f)C5whuf&acBY7rDVz8@!Fl+X0<%O7*@+&-vfdT_| z&exI^3oQC9T=NTTSbFjB$Q<8lwbqW7LdAx}nhaW^yrAXG153S1wibZ=^o{)+R@YICb028cc zM72oJTtdIt>5#s;oV5-cLq6LU7McI-8dG`^s?$5%^jXuAuaPO*Kk1Uf9-F+8ed!l$ zyLRT`tgm0$33cOIg}z7rQ#N%DXb&h07;|jGw(cAK?sYaoZML8C&7{~NSZkN5a4j}m zL?8#^K6-RpOp7G#SeinE|}NzT+k_T9D57mScmdqo>m~tt^X}dR9P=N zU9eML|DVD27QQus)vCB<&vU+|dIK3DEMlP6Z)86^H+j!^ISsX)0uDEz`;<4t-;1V~ z2V#fT`>u}DFuf}{r9WhJU0A=*Cw60`Oiu3)GqPjMW;KU$@4NsBc+bkxVbOhpR9iX4 zT@%I|zb7sQk7I10-v{s{q7d34Gi_~HbLo#P6(%@W42yJNU^FUE?+1DW_n_#1{(uJK zpy5)18a*OX+KAXg&obu!0$*RLiNEU8YJjAq#ySU1{(61M=Ddthy;Wk|9%c_Ymm-6fQCL10Ty zFEd9W3O8sylF$PpgxvdGe@PEszB0W`$DMT(pcl8ib#$?E*igxLghM^n;s1Gf#?Ekz zSJ)I_0Go?zyLhOXt;q&B`w@-+nP;=gM9no6=+8v6PcMQM?xO3aKS)qCg1AX{EM+}1 zEn-`tu)df|N7&E+99>NnJmjo;J`UM|)qnWiB_$cgL@PO$uDI(npl9UL@}9x|KM{ZG zpw)hM_8SUJaRXlW|5xtmBML4;Jfg3I4^%B{U)`rh>Q#Qi!omm=DrZJQYwLPXW3Km^ zHPLP?v)5cpkf#SgqW3;Xo;psvj^jwm9d9>6g*cBC6@SM4Ba~W4z6A@jLKeg z0PS!;|Lm3)kvtvLnlWX(taIGU}F(Bzkea>WSr7F*MULVw`PM zJm2MYqmya=Dr!TMZs(53X5j#l_{5VShffXtjwE5~;E(FF4z6wld7TY;iLZ7E?rbd& zWlhQ+2Sb`&lcW9%J1EK0{ATe5W@)uvW)6+hOr-~1e&^3n*+U8i?vS-~hB}+L?b1d!A$s0b=#3Fy46wIs1+wIYn=H`#uHG$)P|=N=^8 ziy?+axHlSKH@DbrDK?IYj<>PYEJx{G@aa+Z-xaBg=`3kb1k_9dIGe7gW`ysxrsV+V z5V;MHs71N?_?oPIZRFonDR}M>kcpJZZK!JB`iPFZ&1o z3C|W@G-H<7r6X&)5SdOk(dRXg?;Tk% z_Uf*ltmqttA({P*iV0gUzB=*4S=r?Z1AMLn3V=yo~8 zrD+bZw7=^vJGF^yIC2t4XYu5`XhNbi$}lh&GpQ6@cgWmj_7-8x#YJX1=?^y*^J87Yp7tO$HCQvP}xAcCr z7wSGp`8`|$#Ma3ed!wJ7yNu5ygiW0N%aH~(9INq2aNDB>f&w38ub$5Ky(RhchWXqG zOd_>IAtsRwwSlw=yDLw~sH_RsZo#Mwg|eLuA*R+;%L#h+jcueE2~gnn?vYn06AytC z_K=GL)%Zu=&YHt9aXWZV^*8{i)*v_ag8V7h3e`z#fE+W6%{HtC47TmZ~8xp@R zkwkpLmLzmGl&r8O{2y!=qmC@U-V>}O;m}UF2?$%jia#%KeABy!LBFM@78Gfq&V(F@ z??ZVEhL2r}12~EwF+pb_Vf?@@jOT$h*II!tO-YwPU|9g3%(S{JVe{;YRsWvDHlBL# zzBRc)&)d((MHs-Bsjez!16SDg0_6T$l8a&?*G;amq0mbl!~=D+N1sB_kpr88BcKY4 zJ5a+#P+#Q`z?g_8JQD5(x;D(fPBIM4(mfS1&iWteGxNUlWV5g`=qPjlitihQ1uX=v zn;zmJYBk^E@IroK-Ac;~C!-PPBGXubny^X`?hm0Ryhkupc78gE zn=30=?reKn_2_4z(wq$$xY9#`ZTnUOOXO`@Wo%rxvhES@Q{^(h$zdbZvKRl`t4;#MC{>E0E=y=GMnOTNAPAdlpnOm z0;W^hRCNg`Pg16=HNNWGPW>qoh_++WwKjXWm8>;zc1XJa8VW_gBYg z$e4ed>7aHNWQ%R~LQa-=2a()_C}3NN$->W&)}V(`nmaSvwEpggJQbLgcwf40u~J9f zk|D9dBsJ#1@7|L(IOJ}pUPhRW8#WOaKzYj*8uIC^`K9Zc?(bt^(sOJ9cjmK1sLTfL z>Q@IV5^Ru`@D=CWg15;J{4Elji%`a&*kwzr6_5|R)z-J#d0wJgcWm$>@MNLv$2ZK_ z3Eu{#FYjj)cACcSfm?Q@OzpL}yAU?sE+(U`K?Z})HwVldgXxMWluR||Wq{7Xe@Iz2 zySTG@J+UA`UWGp2rQSpW>xFZLp}C{r&!?k~8yb9uuxA-@gF7HaHk}9!UXA1MFxei= z+)}T*Aiu}XyYCRKV*;!E&zXvk(fnseVG>V^?X%XfU zFsPh)mw*9~YKqHd>FoT+DhKbcvy-~jvn?t*iRRo-zlmbRJtlKzIpE3PQi!%<^E#CX z$9gL?FI-K|oV%`iEwy@(fWOeZVIj@a^OsF@VhJ<|Te8|6I&7tmvBei7$p-7kPX7K% z9IcSJhqoGl-VTzQ&Dn=`>B|n`s?HR75YYG;jp-uK1 zS!FmdL_PSs@H|;Zax1r6NUl1@)Ux4IQ9m3)nG}XaR|XIXEGy{kJ{)dpC>I#uU=K$w`6V_Ai7`f2T!35Z{#O9@K5#HFJgrMKIkk52OMWT8Ag|&*7&kkNTKTot8%jML8Ah3wJE&Lk zhkM<~A1H`*5L6Q^j?pWK zW-M;Z%IFW|(A$O4LlcZOs>($8*X1f0B$?#59U7Wlhny|cOxDQmE(Bjud$Yb@7JCWQ zO-=Lf2IAQ+GW>qww^;%~?tK8tHiE!`q*ZmvKf)4Ih>UwF)&&MwaTPh;j`xm+c%V{V z!~@_lYn7%md;isS0!Ke*ehfO?)ySA7FMhNql0kK;6ihU>H;asj5sTJ-X3*RvK7c-q z4qi&4hq>I)N>A*@{LW#;U?dstLe7e5Y)ikS|0 zNleW#M?)ZveMEF$qOKe;0?Sh zDtJF5B3=^k2EWf*`<$5p$+!3WzR&ah{_*p9oO8~;tiATy>%R9ntbVO{dlij@g})q|C@)Tl1TDK6tTStGrO3oIW#$onJO8c*L?V=G|$2x7Ks^b&vS^WrRko zdwuo#Uk8O8JrZ}-^vFr&3G1#8cX#{Kwzo%yPhhKe+q7A<^5x_2%~Dp>zfq;_wBfeP zi%!|=&8i8GDO2#B>crPOXYd&RA%+Ks={E2Qq` z=5v0&_+d=jaczR~o~d#-G)6UvS0!()>BUOC5GbA2y9x z^Ivh~b!n-*rI;EP_X>j$>%TH4-{9sNvt=H`~$I*l}apA-G$ z&dg&Pb zOnkR^f8U08o}1mRQQE-Y$GouX>&HHQqo{q&$0vpz{9r?FRPxDj9ZvV`b9vwF=abJ( z88GX(?e{7Nj;@q$AD+AC?cuEkhU{3m(D6j~rW0bDY`&V=^5US5Bb{ITS@pt;Whdim zO>3_k@@>PE%bz^-cG{_Wj~{;B_{ZE@LtgAOBI0`8w?Dj?`Fo&oirx@P=@%|0>t?aLl?Qo^Xbask~{j@ zHEp^0n_tU({QD1?u;88Gr=Q;Yb;Hh+Pb@ah3G2S8-g}*vD$PELSmgIzhq=W)!_n#UxT+18(my72xFzB>m0Xl}LV;|_tN4>Yaz=9U>_Lc4!z=xcf*rpCI= zmrjox*X;9gey!FmnAiGd$hOX>;#W5w+x%|*=SSa;{wCdZ^x3N~tXg5uN$NPDiYrG+ zm(#cJ`{~cGSH5z+)ry(Vy|b-_6rOPN&eLBQKPa>{Cw=ufzAu{*0k%H(=%2#_ROPYO&Xrwd(ia9#k`uwI)#mR z;;Z>x%$5aB&vw{*H{|&vug_lpxL+UN4fn3)*``Js&hL+S{@|x0 zx4k%U<`d5@8rXi|Pt`l<#?AbE^ReeQcl{{)!`nL+1neFe5;y$)4m-}h|5f*bktJip zpRI4ZGrwhK(`k*nRKM8P*yg3~FJ({oeZih>_g44)zSKEyNa!=Qy3S0^-`Hx$lpV^c!+-Q`|H||AJ{kAk6UU^Q1s&J8UiO{* zng6+y&JFE%SMPG;vFc+FKRv0yRVAg$?dp$w{=?^sk{w-!yq-JfvC;E-rM9Wn_|`AM z`n^5x^|;#Np%3>KC}j_Q_~hkipNB2MeeP8IO}f1|{9@UtZAYdoTe-UP-HopX|KV?5 zy>IKl&Qn_69HT#CJoVw+_O+jh?Xc?04<63V8`bdA(C&kt_^aO3N83ic9@Q*=3Uceh-LzXUllvm4eD6`DRFuog?2m z_-=#OB2qiHpZw;nMm`5VaJ_!G-L4t>;JZ0RYYjVxwPGOlLhxA+C z=tA=Md#9}`_;s;E-zECt=ta+#EZExX^N20JzMnR+rsuENQX}x;cbA0MXyVFUliW%n;21VX8NZ^xzAo%+u)?%?U(z$viQQLM~kkF{bb>t&(}12{dQ@OdMg+F zQqrULTf2w9CXdHf%-h*qQfexL7CC#%*l-EBwR)*GL{J-%Dh z30qFzUG(eJ*EXJb`JLzf-2d{BFAOtRw0>oCt!=@zzWucRvE0!~wkFkbZC3|B|J9f; zCS17E-LXCK-rd@l&;HT0_!0X#(x(mtUG2|JU%JXUz=#nWFXK{ykqmmGmZ*{7;=e@76x~n+CoQbuHLe zCv)6WwNmRZp8D{hr?*tEKlXZ;4z}>+om#*3b|T$!~#g45>1)?!2{2f9!I6_9Ia>Q!eE6-Q(LRa^spmJ5POg z@soM)xi;=-`slQn=a(OTc#b&bd18B?gw2!vf;*UtLmz=H4Z&3VGyVC$s;t=8E- zvZuB!9e8zCFuoMAapR7;|C;{UOyl0Zo5sYZPWafd{lq8zTRihb^YtSxyghO54--!& zCU1_rlGZ;kOEYionK|n2 zyqY89-Uy%9?x_Laz0$qer`I;S64So!Xt%XW8PL1W&;2J9T$*?Guid-*-YIcC_S@Me z-}W51Wl{T_ZvuY(>c|^AI{kjU^G9cXxL}$;U0LzO*`0guIZJm>{%!2H-SW)@r%0ReJQ&$8&ZLv0VIY z*z8r?)*P#~zVBU2jl%b=O>e#M@b)n~j-A=Ex>KpG%KX^3`_CNhX!Ff8?UlMO&v@;P z;B6Tv>UR87_p)wk?N#&J4PBw6Hf{S`LhW$ht@54hNe^`k9G2N<|GV>=WYjDhRikSk z^ZQYevw!V7;)UtKkF5Lpm*MN?@5$14?6C5kxI<}K8>E+i8Q-M!*xGft!7<{J1lFx2{>3Pjow7Gdopy-5CcPhnOAJEujTw#{hqeZ<5(D zG{6#=VRnoTlAIk+VjQ!aWC`4F3CuCenI_vIA9LI4W;xs3c!0mTG1|%}%#B9}nQSM0 z%(`Al_@8N(Yv7V?mIwMA+;Of{3FAn030FB3{PMRP%KT{wO|pb$SVH$(LUU+M!2c@q)4G89At)Q59C&H| zXM;zxd~EXZ_4jE}yT`gmedgSvd!4;?bswK0gNQK3p~hj7qlzRSFgrV5Ckz}tYJo12 zoGcZ$GRa92gh0-gilhBazR7ryZ2Nso@_rNqn0!;z0*jnx(XCB4$p=s#Wb)mPS&4=R zO~tLua+=9EO)Zk-Y)k7DlkKRFiD71NI|8kk0{2VuC6g`72QsIZk}v5^t+z{#-u_af zLl)odrohWAvH~+VGLn2qV0TGC(r^;xKr&yHZ&z_O%Nf9RpQr||m#G@-WAaTUfe$=H z2r$-rB;RBdNrAw4m&tZa#W>SF4lq8z7-xH7oC=Hs7~|chzyh9)ig9_&K+g)8xiMyx zfR7tv$nx4FZj1{A#u-f1EK^{X$(AiJKExPjF~$c;I|v%@a#H{pA7qU8dtsagjDr~C zL#9B5fT^qRtIHNbdGFa(fw36dNm4SETW!DMGbZfu7j zRkV5@{ie#-$)7y(C6|*g7)Qy`2k@r={45f6xr8L_K)xT@R0-lyoM)1gqb1!$V0RVb zMFqYoX1OHVq?>q{i6I~0LWmX@=88hd*9DUd;X<#&Qt^3~y%JG(gr8IC!Qy+DIr}g; z9ZDw2;+r81vL*1GC9uE}SY)yt@sS9PB%m>CCodgvaG3&As341=XodNvz*H(csuqIg zX5HF8dg||6U<%wJIjWlij{skYJ{Fi}&nuiF!N&76G_eOR5PP$X8n^{=2H*^U=zEEO zbyK4(h>DQP(^yw;fZ%Kbc-rKvNhQnh0q9WyFdG1edI3x#)EZ@*e3{Qp#b?Y=A6^(@ zo&@lW$yXB^vrHle4?qAs27sfz0Ag|g2+n3!G!>r}Jnf$HF#+(b$ycaOO#;mFaRTU> zYKp1R0h2G(9~d2W!Z*(n=(5PEmcZ+lz&oUdh|}9vx5$Sz(_xWw*>sQ>pzD=t()CWZ z=z3qr|2tCIE?wL=FywGaB)PADw5~A2EWaCoD~LTi2-lo{!uZ6WUWNkt-BH)peV=W%Ma(U$f+s$Md_x%OQt~R z(}Uo}g4C27MR+L;{-jygr6~CZ{qEtyxmsZc7aromg<4@Y7oOz8Whj&!gZvr9F|Ift zZ2_RX8}y5nKID^n#(NwMBo(^H(Lhq6dmI%Ucc*c{SUd?H>okv5z+)*qRuZvk`8jE0 z(M0bXiwf@>iwe~_1>84|i^oakaR}4ciWH$j_c-3@yT?({_L|dv&zxL5r!<~ZGLMx( z7NPu{G*S_!_l-q`_l-q`>YRdjPTu3B@HmJJFb<*bo|8BF?s2@)caNij^P1Cf&zw}Y z;yGpVSo_Itl%JC}R=GK8W0jkeHkLLgi*qAkY?jaR%+%4$@+BT{7Y}$q7^-A4RIpO_ zo2aueO_%;V6NOmFW0gF273B93*dYk-EC_EOvPJi6lDT9L-|vJ;@`B1W-gtPcLjgnJsoSnIt!a8B@*KY}K6g{m15Pp+_n_cdGx^^qWV0Bxi#GS0D}zqrF0^ zh)qGnMy`#c$5blf;ELP_b}ZqEAP`}X9Pyf|_?#zPgFQCM2Ps^G17<3|C?yx@ExyTY zusIMz^gzOkXbFQ-eCP&^uueo_njfYPA<7YjY3@|Ha)e)+r|*fq;NqE*PkYACB=r)= zVU-%4A(Ym}*QVkgztV9qzBW$9@%J!cC_L37DR_jYd`*%)h)>D6GUuQ}S8Q_$LrXn&s1`KzPc?Hz1_MO4=^NwcBoKbdw@! z=od?)TWYLx8b$=|pTGsN0^%G_r-@jn(nv<*|M*Jz+fm)yUMK@q&i1ktlB0r2nG&l= z|B$oEzeM=LK@4K;66R0@F$jIs1Ohm;Tu{RSk2}GDh=lr5=q}p(UN)f!JPP)OS)q^= z{<(bEWJBolfS`x{b>d+}Fd2w>@Ejnb8&S54IS>XD#OJj}yFG|>IDR=IIXafQpq(5~ z)wo1HcQOeOqAw}gB?JgOjKvT>yqv-8EoZqKpce39COFDMevkQ&uu&m^1(BHmfjHu# z1SByCWnt6?2!$DIU`H7y(zbgnGD3*Mh{G&0Vv_^RGZq+a;+a$6nOmktg%oikcF4nj zXy+$zxvuieEeaPXRJgI-OBZ^yj_1zf?witg=)oW4)|2B8{Zpbq{{*`Ie`u1_6uB5N z{jSs$NAXVb8aT#;Q+=bTkeqlX1t)r-WyrvIyg@I!>+w3hOrFQ<)SM6Mu6pfk-A>c! z0t_M#N3n1A^ypYq6fkLyOpdt5g%E_FN)WsWm4$%M=w++SI;COA9aLlA4AI1p^~4IZ@`;N_#w7Nw~MHmB7ZVm5}OqfL8M6 zFU|i%k}fdQ?R@^9I-QQCvCO0o_BkcTQl=zDkoS9?sAZB;Z8^X5HCmWUs3x`(zK^%( zDG3STih|d;F;q>1?DJ*9HNBRal2N>qt4mT-b``_U9uf+P9B@n@a+6Vvh>W7lUB$`F zuiL2(;=hyXL==U(6lR|!j>Aa=QHP+LqMlvF+hKR0PpB>jBz5N;U}QUX1TJpvVF}EI z_FxkUi{sHA7Wodeha@r&6}1Pn2oe@WT3l8S(Tj13-L`0>9__*cvnItRaSFIqRLdh(fSxD0^PI%%jLKchqN6CH-1iILH| z*?tZ2V{VA**@GLRe)hUh3l0Eo;4*v`AzX<=!qQiBQlA?8!Gkm1*+T-gnlQ6(eIQr z>Fy@|luBhgW8@pU*$wf3OaOjf)8l7S2!7rT!_RDMlyX$-^{Jaa3y3~IzuE_9{)RwCFT#WoAaBBW(L~TlBMgWUM)UhO#LxxJr#)9D z2hIO$%=5naV+vtj_@|Y;n|5zfwVS8Q%F+r7_otmN%tYl`d1(!8`DrAcW`OY_vZrX9*DOxu%F zoNDZtvn$p3RL%jKWMQhYc1|&7dI&Q;MU%{?Ngk)WLv(kFW;(|+JPo2k(t3HwKoq!- zD?Rgv!)C79!d&l7Y)Ryq>-EMiXn*X2!p|2z8gBVU+qN(_7Qh<=cw+``X_RBKrIM>^34}kGg?;2qOW-X_Tn>~QK!=MEB3uQHjd3?< zv8(98-`qOS+z5eVs<{ym%{0jc04~{*5R2|K2i}yB)w5vJFYq=4j{xupR;m_VL?&2c zAv>(J3xVld0&!3PYWcsLe0lj%>Lw@RMW(C%4Ts&?11F#ZcrY_=?Mf9 zVThn4WZWVFZ8#|k$vMLiruf~UT0gP*Bsn|aW(I9Qg<}JXdY`*a^}T^de?S-n2qOUD zRX}(L5Ju=JxphP-Ei5ZjHql83>|90B9@cotInsb0;Xuw|HcX|_^vY7&40uqJFy#Ox zSSm+|#@eU60F2-WW1Wb1Eads!G|SgGwnFR{h;RaXhh9f2;2DG?sTqz$PIw8fFrtbn z`!XG=AYUT8z*I98u})74MzXJ1Y968^6^KJj*@fgJB2MaQs=3!vbD!o;NSGBS&+{`I zK$^j{M`xwGk%kbOUl%dmi%8>0&dr8cEUdDeCWcOWQRkrjZ2*d*GLY-a;cJY1&?ZxuUarIxyU3JDpPq#KLc$l z`b$`q02)%P^JWztU!2t4_WwZwAj+*6gLjd82htp=+YzVT**O*Dlkl>-Q zcZn4WAXv@~hNGA^I4%pEcNBb_2Yyy0$LOn)V`7QqY*j9%)8hYy50DQD2arfUSUB*b z8e!Z;hv8>pBm_s24?`sEhFEq%X3sM$6gP_v@#1EMVV$`7){rD_elle7P5xy7sSbDK zjKOaw{Ln?|8kCMk7C!c=|PxA~{@r1U02$=!oO)WOinJL_?Fa+>T{$=3; zUgO-}9mYTak$U~$%PY`utxif@_fjxja@c^ilBH=>4^3+~*eIRv`sMk*F z1)K;3%h3_+$O9!69TPUZfzPaC;`zCl#w1>Q=_g&9lNygPTzfDH9i2a8okTi8q7@7y zEsn(xHw+j2(-aa)2qvir()Dk3&Spats+HC}slPD|#7R3Dm@G_G(Mg!zx#2qpfXNQ@7`oP>lI0igkCVdzR!0$U7rGss9{kg>!dDkfd27g`et zcVT#uQ0?iElQjI_6Rpd&^NQl(5FY07vf|-nv@T~c^8jvEunvPnW#RuZ)TZJ;BrG=t z*Mqq3!u16ANWyU3L)F6E0};tEsL|PDphmsM)pJ{Q+z{~~#?8~9T;-d8Fm9~YW1&|M zcO+D9*f4IP4jU;R#IU4`7glU3*d4MdGR~(B+&4gC)6k)ssAK_-6LChU?EsBwcU7IX!zSRuwPpZLXV_FsV zh>dA~8f%aqygq}Ot|^6(e@ydW^-3?Wt!f(2 z{wg`DT4WeUGKrdjgbyPM3Ue&-4K!8FBzbHW`7UeT9>_Ook|NAQe|C)THw6014Ib&k z63QV#>|#L^0!G&dik%(}loYjBlG=-|4^U||&;sg$0iw7I`3GOHn+~_MaucxG5DR^x zG(@(PeNJknnfe)I>cfSpPoh@WE~wMM15X3j2TmiNdfh>;=YE|t&k&1BQhIZ7CFT~- zD+~*{{96O1D0vAI0YFpI8(4S#5B2m()hCYU(NxD`JQX6;xX&LZ_h1bwE78k>rY~61bce?KpBh-VXoYs$&}cXKGBII4NQuEVJ_G)yfpH9#v3P zLJ^0E2hvOp=4FvoC?;LvS>$MXBiGSeBvN{-iIm=6i4-*_MDQC`OrZ$i zI3<~NUm8UP-V4C7(F?bTTq5;d2v1hVb4QZRr#vg>SNOTn<^b1BtSOH1v`-2zDg1ADl($cz+fp3zP7&C6&pK zgvdF}?OZ2S%&(lRbXDCs-3p3GO?^lwX-O(q&_rFm@_`DrJd53*VadbXY0=1;p+zf~ zVL5$540C^mCB8hT#R7`5o?9bbiU(S1y8in`n2BCw;(gEkuQM#KR+eG8f~*7u8%c!Z zzss;RuPnm?-lV>mAYK2lDEWZE%EBBPeena*D@jDy3h9-Xs29c~5bpF!%l|*UqNNx9 zA4;!Oa?-V&{rqQ%luFE87}g&4?*FkwN|I1EjliH@iIjT(Ng^d)OQcwj3NELa3JcMT z6DjxG0=+wt67Q{sNbNmMKpYP(@06bsAynH0VnD zDHfHUL<;Q^R+2=ydDx?e|K~}Rqm?C5UVTs!<-5v~C?b2Pk)5U%uTD)QQIM9Sx!s>Z z3Bu%<>gty1-%^q?DEWtIY2kmnGbo$>vkXeVZ6ppkO<&;a|DQprn71dH;neqklRE^#meyw~_sWqEh;)uM?{u;_m{8fh2l6*>%(-n(PaamlF&Tb(9 z;F6F;8dH+55VY6}MO-GRuY3wGWpv#ch_<8jl3ZwZ#)K)YlfhwfZX$-Io@VE` zC?zJ9%5W~Pm`k?AqfYVRhA1o|#I7f)O)f~zEwR+s`9&TzJBA9pMQoPK7^Kn~u<){q zSuRDxBx>;ow=tOl)B6cpuizjfmAV{Dj0Sll;CN$!K2@)+rfN~g3068&?2g_Ajm50;vCmQTm zG`jC3lTo+v5nkI|lWj*8r68rO3`Ij}K%xtdJxacplqu+H>3Sh18_W3+V2N5~42o3- z0D6T=**Ru_B}uxCNyK`z4?kj*ainpSakOy^pNwN-pHzl`@raKSz?`l){1_Ab@Y=QH ztbJ=u9iPOin8((7nEW=LapwXbpU|ZIpKylKm{3c!%cgdV%D2;rc6P6r#5l|(A7LCx zPKxl&gux^kcL=??rL;~s>WcToBSA}L+gZZO`l#f1C&=uaV3^DuX=baqCZ?+~AqD~j zG+%HJPkCH{=EBQ_CPAh+qTIycZNHbp8awdo|PDC(Y9* z(Q~`jbNj6diDn1s@Idk>NZ)xNO-I8mHPFiYtt(F?s3JB5t!xFpF*w7*hjr{6Cwu0k zM>{3b1GObV)$!Oou?F7#nUEnMv8R6!^$+m$Kac$6mS&#*hw!Y950WymScfPlGDs*Y zp8CBH|0SOObn-_4&;!2mIRl8rt=Fl~`}z;5tUvSih=0_-fp>o*7FK%;tBl6~sQ)3b zix>U5zXT2sQF3;=xn~{o6w`Z^=XSa0b^+aD0l`h&>MKuQtEbiLYAfPXV#@bCtp<2n z_2yREVkm>D5hBw_Ue+rTyh4l;Zov5=yJ0vN;-D5ikPfDrFnZvl5_pi58?^YyA>*}| zGt}E(@dZdrT#>a6ZP(+o5Xdi+khjTJl@_bwVx?c6P(|T)sd-rfz{5gz!jn2x2w9=B zAsrePAoO@;f=m?NgIP&MauH4OFm{VPim*&6%JnEhSNH-FUjsWV=mM#e$j0qEkqH%o(J@*E1+Uij>Pbg3?p-E`FT~%jF_~E-`;2{y# zI+9~*fbz|$qB2{FpS4|RlI>60EcCP1B9*jVoB)+L``k|pq_6{3#{iL*M z$7nn(ohybY=5K|J+3^fr!>77Njkv(;Tmw7Af^WQCRS}77vqiR2C6>PPs~e(!&jrgeu*H@eT1%11s&{cv zxTB#-UL93_ccWuNyvf)xnmYRmOaPTlNbbpY3ct>7h^1#4Z_eT9L^2DLBoE|?l&>MPvUz5{@JfVm@KuKo}0};Gb~?3C{9?> z7&xaiT#}m@BwJn*@fePrhK2EWi13;#&T|5q$%%u9^srie2&0A}R2)UcbGdjP^Bp1H zg?^wkzcs{D4bFU^5$O^y`-ZWn_H%Ssl=krcMJ%!4Lw}&=u6SJ$obr};sY#{}_iSdg zBIMHWwj20XxqPgsEIF@gc-O1C`94?@6W*{^-aTGa77f!km;8-$huspl0l2*_Zi8@pN8IXhi#br+VBFplw;@up(glyDfCL`z zZg9Ox!YtlIVGUUP7D-nUM9Dgk<^@4MB{?hsq+A@40ZQi^VulG=5@W({!Jr{4HAmLN zpcBu)wm{2z(NB{X2#{N3TsvWX1m7BMrTW>ya6uFGpgZwRc}Vz~$KE>>*l zkw|{8n3r+@ei(TqBtwYzNU??iBkD{=9N*Do)^Ix^MiSm#llLh>YC9Sv5!wj-a}^uf zG4;xn5`+SY520M8$9S${dYnX+Kp+td=A&4=p(7I*&(L_3{qTFVsbGLate}t5l-rAT z>S#Zrofs$)2Es?V4L3?#YOxAfImOPcXblp{O;-+bE0s`KSu7__8zkr{0Wc;+N$%}WH!z;P z1Ly`$O79@L(c?x>H^I0GrkfDlgwPGtVec+<6NZ~Gx`8q8EzwORZX)SsIBtfUoSOL% z{BU2??UDb`q&YJLYP!WqQdig--3QaaWzgnRO>zp}uc&5rK8*LQ@kS_)&;kjgyvLYa zP}O$2hN_Ii@rJl>W`r}wm(;VM32Xu0zo^>CB94_C^zN9<~H<|d3)QqIEg|h0Gva)dbmhH5!RD4Xr_r8j= zAqjX1!PElzWmAg{hFEGI3Y_cSj5~_SSPLuF|{xox==lvx)zJY5jnIA z#cNGgTE<+HJeXDy$%->d3K$P6tGQ{;4&peZH&pLXL@hQ?s4~@a`!CP!E1uh7xV23% zOs$6XnQAL3)5WzU$4_3tt6|(qgi}9Ihrp!Vo1h?igiknLrvWCuNw&P6@{ZOi8g;J= z>f+lr7i(t8DYiV{>`T5`&L({zJMwYUoOD7QB>p3<5)$|NxvWe+iat{DQ8IMUNyYo! zl$DP#rJ2Gx`AgHZTXJ3O%#)jB&~`wXR9)lz-p!=f~YN>`&4 zlx{-qCw)AZxGI)l$;Txq8y8|_mjb^@jb~t=-%#!M4(mH?zoC}Mev|R0XE-n&6y>da zVIhC6f?3glwfi`WCzH46u9Xpmrx!8gO{#+WdTeY4tqfs^n=ucKIaqH)JXOFgyp znzgfIBeW)G`Rt|&6ZWC0?NLkJ6TY+zrGKE*wc#()nPtjHyYE7!Av{)+vP4j0-v>63 zY|tIPiBH3P(Uc~GgukG#+4*D|;Xp~Og#;Yy62|_c52l&ek(xU@+NmX4OjKJ$a*G9+ zAGr!)7H3Qe>Dj6HY!spJebDu?{_@DD!I;-22X<_!G79pgI8ie|9@`c*P-~Jr(h%kP z3WzU6>=0yfPSLYJfp}SvdOP;GP$No#N4wvUr`)7ge#aYN;2}dbL>_t(n;or6-ac*{cTH z+m$DA8@eBfhZv*esOlYM5AsCW_{6Grl#TC~deQ^O$j7*iygFD?G9ymEn#g4fom_)0o~Dz_D`ahvpq1J8Gs{=9ktY%q zS2|-OgP7msoE4`0_jUo7>^q1i!fS-k$Wu{dZXw<$G114JvdkD*G=%>_9YT?7&XUL^a(9?~y24H7{8{LA zbLdVo(Gr*1`8W(63nR!1K7mxOTwljngVnh+B`_1s$+8RP;81WhJFzH5}zU5}tO?FTpq z8>$=S6UmpVVomGQnug0IysXJeRU>vsYS@x|bsOz|RF$0PUvnq>9W@Rpf3vV;O^6%3 z7C7A50Vekf%ruPc8{0^hHW=d3hT4+Xt{hrL{>)X)+JfA$wnu1n#4K*pn)%R#$Zx^d zfW>Qf)C?8=RDrg^E~n zijB7P8tQV*xl`ACx| zA4!(YOH-Qe%SYBgZ^>D$^T2y<^XIA!QsKMl2@bJ3KP&{@;UxKN^{mdtY^+W+TpMFT zs8FXiYGo|9I;2jwqM>_%TrR~_y6%c$XY)EcB<^EF1fGXruf=Q ze60Sns*h0j`|c!er7>XtVc;8M97S12uFv#fWzw;Sz?iv-NoX(vwf7d(@o{CM))OCT zDOHpFmwVrCJO)$FZbh;YX1xD4&R!zPtFvFEDU;p%E?xDEz9818yr>g5iA#909hYL5 zZ6TPfvh`PBLWv!8?nh1KASpe}pUgmd7)h>=QtRkLP`?o(hj$9RY>7LkvkxJr2EzuS z33~ChMMM*&7mkhS!mieIWM{BF1eVOt~3J8N*e`PrC zpqwZnP0Gq^V={VS;wz%-`{=qYEV7D^@&@{oml(i4pq;8QFGDhu+k_c4;#&%$u~%9X zTPC`=jUW{!;2MmTQS(*_%LHe&24KNie_?Fl9ly4ZHcC0o#@hhJX{wk%&oe^4IBo|f zyS0)%2RNLx=YXw;|9sow2KJeGye9~H;{Q_4mjSfd5yN7hf!U~H{+Kqgsi=oEd)dE# zC*~;$#D4s>I{aC&Y~9?B0O9Ha0&zTIOz0_CDPtb!%X-z#N=l8rOy62WO)#m-PDOOj z>;%?w{Qz*VpS*{huAIl3Vgbolq`yW%o)_}Ryiqa1&;|VrKn9J?NQ-cOc>=u;8x|(Q ziE2Jz9J&pWoY3YFCv~^2OqmD31l5Y!P{uqAv7yK=DcJ`^)r+VyVH=(uQ{w9`sX}Ca z5*0zJYm3lPX{uIzj4EtIB1WUFINpC&KK{d?Eg?2;F zQ0x!tn7bi8po@DM+{=jL<9n1&M|LMylCLXsGex&`)D5KY1$7Lzk}zFd1N5N4zKd}y z5Q6T3 zEkx2F*B7wK(C4p;^*;8ICQt75Ce=}Yw;05|z8UBRc#NGZigq)xima~C+>MU6l5s6X z7h}TLLT=x3kK>WswY#81zY$9GdDPQlHC|JdWSJZXV}ecK*pd3OM?g3-3PSKF0)XoP zn!5MTV7)fk8u`Fh*wGX!lDE)68rmp5h~2e&gYcW&Kyz-*ZvTqD4D#K?&fkCjB=EPPZLhb}|$b5A6FL6;}N!UODJf+2H0%l#0JOfzb zC>`$r>kEZEjJKSvpE@EYgB|16p|{zA+?!)al*uuNojhXG0*2ZF6F`cruq=zpqL@d! z8yKVo(uBaWRH?4+VfW%%=zJQLPmiFos|a-MEx8hCJ7V2KtPzNhry+o$dzf3Sh*cP5 zL}-+&Cxl#{;7X>PD(A(DVQ?`~Rc9{-M7R#{C!2sjijBG@sY+i2h2dTEboP-nQ+Pr} zyRZh1m@w+lkx-zcUuDYE$z%sgb@pi(0iFb`C@R5LATqZ6ia!KfO~n1yAMhhMs!0Y^ zU4g4VIC)quvj6yQ6Qh@8F3r( zzo|_DDPFQnlurVyU&Hf4T5Zx}v^|v|cKhwAtT}1(`dU}#oEVq+s|q= zCVVf(*%gOz#?v_TBY5TN4q{FG356rdl0isQBvJ1!UP4X!lG5b(ei3wt62Idvv^(w~ z$4~Q?c{}JE3-bhk8h1nxTM`Ji)i^@oKIjG^n+g6PD38L`cShE+CDqVLDMmTjn0%|M z?M@ZTs~P>B;WZH%rfMcymI_k7|&`h7rNe z3bu2V<(LYs`wPVQG$K7jXi|_&r^SP)JlNWt4`1PRJTXZnlIMr&xFkOB9n+5>bN_LJ z0hEqvx%OfeKo{e>wUEFVJE%IgJXM#csZ_wOyN3j{COZ3JG$qM`0x`~w0OIuF8^T`k z+eri95u{-h1$`{??&OlH(lS%)R7=;>y7&Kusk6gfh#N{PJ7@Za;?JF=VyDp!E7aPPrNp%T7?9+N8xs`VVw&@9m?jI1hk4eg(vlEG zju2ncoPw2!6wwiZRSLo)LCHFM`?~ybC4Ir1;raw(ruoH5VvII4Mg>w1#28p;*Gp)w z?is24dOngACV0aoaUIXiUwMp**_P?-hiDq0s6V!iT*tT-reHgJ&vwVp+C{8vHv|jT zTE>LCXzQv66p2^fdqG|6{3X!~RYIJi2G=oBo+r^742Q`pX1LBYN|3s4{$kzC@-ALC zsr7bK*JE!Ff_1hw>F=D;gH$^f%r{qbpIL>L3V;|cR;h;|y>gJ@QpGZpZ@S9@+>9H1 zT~7lAsN6wN4Ju|=3A5oSR_Uo8xj}G9sz8d%(AnprNw{v~;}$wEc_>^y8zJY}&iWdW zZ!#98mJk7&gPro*6JO6ccN@)dgxZA9S;ocT-kzh2+e0D;Utp?ayX6~gOlS*RL_Q~& z{6*p8VTvtU4&>>~{U z;jBrr;QWS@J_>h6;gA<9L40}#Bp_U8$}=Y4t!lKDR0)^I;`?K-o`ZHV_?nO&gKh~= zk-F~G#a#r#65K!z2qagotnumHq>4 zBJf84CEH!0tPUWLG(r%8_g7vvGkEx<)^V)&iL61qz--?cqI}FE1Evaa;w24W9wuT; z7)o=ZvuX^M&^rMh>3S522GlS-UEDI%yG8*42-1tt3(@%Jet&?@LMt^k0~2g%E2V$( zO_XwzZXDCWg1yHh#bededN!79)1!Q>_0xM#2GN9S8=;;jRGy)j+A%#!X(MjNE6s6( zQ;Klyz4AGH_S!K!OsT51zl|6f9mkJwUBw;a^R7Sx`xoLSNEs*aft%7>pWZu|h9|Td z5nAhH$q8v!;*SuSq$%E!3*JA49^ceM6zsO?9%qHyQN_ZtwF=eJzk0N;hU zQ|kj1nu1Gk( zS{Fyh!xTF*TFi@g00b71Tr>C!aIe$D>;*A3BkYjo**rj1Ph3LG9f7}INLyidlcdnL^}A3hQyC$3n?nl{GFZvxCPHX){gG>*ny)1=asc5bn8C|bL0%Fo^fqA-e+}T{@(bBj zr3Ktx^r0{=AD^OjHD?K<@k0yp=eXlb@*gu{23rq1BnbPNg6#N}5o%f6hUrXG6 zYg2+me+z(p20EhjC6-3%3p_nBjLzPlwHoED%Al)Sh&C7ija*M_`ig9jzp}Bf zO6*iCls_g6vb%DjR~ClmP;)v+3++->>*diel4F+MRRcOxJ5NVDS%)RZFsPPvS7|m? zlsgY6>Tx2(F_4?IMUx8ebCl6ya*BY2i%b!WUS*qf5i(qhu@BQN zPIKjOVKEAepw210MBxq;f-cIS2qrn=cFM-bJ%?gr0w39O)~-7hE`kvlY+Z#PcDVqg z`6d{@54n37B@m;41&UuvQP*w)s!$9NER6xciyEi^5eT!<7UF`)HNdf5T~7AIzSLyMO3 za~{F^Wd#5@>jr)(2LQ*!v93@<*0EkdNChcF83?vL(10N8mHJp#BQ_^VqY1PS7h7B5 zl&*C!q=lR>(l|IAhs`fOn4>1Jh<758$qQy>=cQ6$5tCjU1mo(!>spcB9EB~IbfmQnfqA*r%m8_9(-5|7d6T%>eA1MvZ;6X|_N zlH$Ht2fCIKPm$uv_C?U&lb)kI04)fXdoVAzum`-{<7m&8{vL2P(Hh+WpPB(F9Obnd z{K1Zzc7dCamfxA^Y)qgW2Ev%FR>%}5Vkl!G!kB%()1Er0=;3bwAxaD(icqd=WG~#1 zVhb;)*%n%m1qZ7XDt9)yrxQnBFY5)KI?h8N^G3UBq*>qLI$&)}Ag0DVUgmkY(~3x- zL-8m%aKg3rM2eO)RcJb<2$6&0Acm}E%S;4Wr41$|XyYE`F&;(D$%3fR4uoQmlA@}v zhg8JWF`(PvD}kICgDEP8A&R=rfbBFtF5wOVcGix52Xy84b=-7CH^sUE%4)l(z4B@p z2#IxkXPSlTAy7)Tu08DyVC@LQxE#qbmk0@Fr}4$c5-5NMVPwODupjG3<+(~C z5enD0iSx+3)5AFRflc>t^+8WH{pmsYh3$=)NidXe++pxMC)=%kHBnUg5~AW~V1bMa z1%hy92uQS1nDL1{0Sw&U1>2_;?YM`I#2OkHa$iXXnPb?{E=P_Cns5~_i{MtV2BpeZ zXc2iDPHMJt{CQRa*0?I(q=BjX)(h zZokfc4-{es65P{(;w=(8almf2-ZLvDLp26j-~v_Qz$d}?j`4bJdS4NnX-e)VwT<8> zsBo4hMp9LSA2G+lq^Q0LOLM7`st)odSF02S7R1_;S~rk^zbn|8m&3gbI(vJroDD5P z5HU@jyAu%wO{+eGWvNzizfNq>7&}(Xfk^^P$cj%6OFL#X5*0Y5EPg4zzSr2UwOWy6vL62ui4|U2XRZ+Of_m-$1WaS6R@>10j*C(n?4YLj=JDwO;2o>O9l| z`lz(Fa2?!XFHG@rLSJ?KcBpnWVm!6@TgiWxIh*xvbJUZEu>?DkCd`4*P&pb)#?yAA zaRzN%*U_PTyh8p4JbpF4JVd*eIH;m-S?*-Lrj&HUkkBgYdhivVg0hNlq35W4nfk!` z%b`Ai6o_B=fy5sAPpx2;H;x|2dZbyKA*5iuah_Se!u-H-g|JgGj|l_5xH~$KCM##Q ziGS42kjx_Lj4RwN(b>A)yBZ`SUc*M3yZ#$@J?tpgLl{6ecZ2t}2E(FMJ4y|;YMp(I zTSXD-6!G0wbZ?q_jYta)^J&3Iv=7RRF9@mG!FZIMoWg zUV`cHuH$Xx5tSh)3%Km5ap290$+I09$(`XGi&-&Ehk&F5%8^}X4`w(6!^k?*qL6-i zVVl7HVNacj-VO!nl%)t^XkJ$#3s@1=Q>3L3%c+qit6V*?0#QA{gCKoDQd`o2QFM4j z4DYq1w3|tDXJ%5RpB%a0kOUwcCZL|6g7x9A)}S$9(cC+-7OqAIK|icJhA%j362kY$Jf4(v3NmS38VsHYM)XAquxCY=ygoxLtM0cFdz!Gu9xt<4pv zF(M4eEBN+~irgXAfdj+vS7b>P2nm?Y4hH468ou;sfn`p4fkZxb)KFJFoaZ z4NK!^a2SK}*GmG-jyI6`kEtv6NXng~K->pT*hQH*`JUu>9!!}m$zVG8_G(^IaHkco zXVZZPc>F`6C|Q!s3}szIP9-0$KzPR)P51u3b%Ce@ms-ZN86E^wIM=Ds;|gUU4g4I$A9HL`!8Y`D?Z` zStc-z=okorxT6x9{6cVow$O7JE*3LAj9paD=%kCS1XnaF)wm1x{D}Ig7(^=C=NgbQ zhVd-n?M0-Wu&fuA<{cU&o_FzGH+LY#;u6XVgg;13Lv^D-!q-ME4kZ6 z5W>`|+qAe0iI-Zb;Glw-BkHaK@+E*ui{W3+lcAS9y*L(sXxznFCv2QuWKJbt#?Js# zj}HqgOxBBDiqX1?0dOZ!8=W+ZWOblV0Q!gqa0I;j>FlqABvhqA#S2oRyT*7DH+UC+ z^y%+FkT0XT^&;%Aj}nz16PAmmsq?Cq18t@)4blotzs2HQfN*L4Eizs=c?XHvmG@t< z+1BT0H;cqX@h(;ewd4s>Jhc6$Jg$~BK%gx5#`|L+v3jtD&Uw=#ZBtjse^wk1k~$mT zqxwmVhj)NtAfD5MlvK6kX_P?jr|Xs9)RLx-h+w>F>xl5jJGtdXB~J5vo znrz@p7|)=N6ef7_lu}*bs4|5r1yd9YTqL#l&Scskw{a>QMUvxBK>v#AOqQ7mWcC4ZN zb`~;(M4BiVJ|!RKgk~7miFg+KK}5(_L{PNwSDtK#JMd0Wxm|ncp;w>ceiXqxBmpIV z*V|xYZ0{|^Zh$BMXdH^2F72yb2drJ7fhBp5H3WO6_#Opz^pt)p07%9=Q?3!93YG$Y zT@4$8>QN-unlI=;0P>y}X(^nwcZ|V2d(%8uyXSc%Ui+R79pD1DdyUWMOH}11^2us) zD?y2kr{tE%>FVNM0(|9PT%?PmLyZv>^y3hTE{cmio|zYR0M$u%EfgFnXYz7x=aoMm9QPf@#Z_&U?^H>9B+G=>deL_X6oGnfvX+{7Z&2WE(W0+i>(Xq-0}^37(M7)J6khO|Fa?<+p~fS2UC z5{&FQY=(O5sp`ph#%$>5s45tNEqJ?3k8_Uwdngd#v$ zH__%VM}s2SOn!YAa*FgM#n$C?i)9gXaEYW>41|?Dv6sM~z=l7H=XxB-Fg-W|Vn3a| zc(_jd=>gu!(b;KJj&_Ovc1WGQ1x*WR1iS1Y=|ZJm8|DGdYdDGDfQ`S4d?X%^V|NCJ zqwaLTRE(#lybc2dm4q;(xb}0eSU>??Eh0Gs^jL4v@kpV%R`OE9eg9jqv(dt}8^CNk z%Un<30q-SIzF7DRILuk$i1#w7YbN-Lh2XH#9Foi8rHf0(N|Iiw!$sJ4(#5TzB69lf zmnpBLGA|13jmRp8>Fj?oB*+hu3!>BHNxHI#Vx=@PZIH;Dns;nAr6K)*++cw8|)ODhR4+^7|IzqQ@C6!e~7!Q!Zw2& z#RRC`LzH*4W@mYo$jr{bXV6A!#bj8>9}nXmgMm4ig&RdGAO0#V3~4}aL(!hZ+(b}@ zE759$54iz8+oXhlDY{$-9->Wqwd4v+56!(jQ-sL)&KJHm(J4H;^YtX5jm;RZ(b&*5snA6N_Z5k>z0?cF&Ct;1eFh zRXr_Ghk`;g&5ssDPgh$45Yj4EdZS0MmZ)CM)p*f|$Kyl`pN9c_?=2a~vGPh?ek z|Dw*H>nTDdCgSO=UMs3h44xT``x0RJwo+5=*@mmd5)pJvhmrHFk-yp^QpHb0A1&0a zgbSSVG1EI&M+t*qhQWgFCKnDNYJ9FvA&6G!efaydfZu4>2Poi7A*Pg^M)ba{jo076qmv<+cu#4E7_~{vjz*dD*get}$pc`ZQL%6QL zn6R|-WQG2*YcMF2;3`BSO85)B!>=9!Dp9U1C6j?8b5ITb>`HLJ0=v#Z$n4K($}xDy zV>-AQK{+)Wfi)TBN^K}kB5C<7?eKtlQf#O434`WuUFqVsv0kLT%p%WTrrD9et{fX1 z7I3&sIy=2~OUmnd3s3>qA6wED3Wy%QP#?g;xynNI0gH(5KhXpEbZORZBJnO*7~SBM z9KkFN>gHWcf0d5R;v@`QkAt5W*|-H-g~wfFplG~US^hYV;>wq3?p@?8kDf$e$8_Rd zA#Lvmd~$m=5zV@h)`9l4XrqJ%q4k1V5ob@9Atf=Mm^jEqVHW&*TXV*r{SiJgg%e}s z{Au|SFe{)i%EYt+WjmewCNQM7n4ihJ76YkXM_aTI?@ih1#WZS!wS*reWba8;?@;z% zRqpEkA4Vxvp5n>q?B{_ARr@o}1O&*GDiaaRkWA3Qk_XLKXaAO43>nXOLWU{dP!3NU zH&Dk0bJJKD;U_g1CACS*22rfAY<812xVo1gpnUo3xh{u#WdXXht54OWIy@9tHw_t5D#mI`}Nixp9;WakA$yumu zW&*V>KdS)8q_fle&@}l{;7!+!Bn;$b(!&qx1HC`3v#%#0PQLfQya~$S7483(?vR(wH38;iGrK9g~1w8I&B) zu;*ATc(@BzK(gKQHEu(lPfRzL9T&p8zhm${Vgi5wW8k|@cO*wYeLu(GJ0+f6?`;w; zK_KgZ{*Lf_0)^O5Sd(q;=dj)>0RiqP?Un;^&}_de9bE{%vI{;SiukjsQwcE{=W;?& zE9?#H3yjQDV7VJys|2}N&%q`ibP^L(lRwtZq)M>#r_s;t?G0rq73E?woQ|YE#1@@t z3V0{aR){xGd>M}kr06CX0`hB9yvr5j`+MdWzli1+a}MA@A*Kmsl}K-6WQ{!5XT501 zQiKCg{q)$Ba<>RlVbX3Htz8Y+O(N4rG=7llbGFR1uHE>fkjgTy*2VP$(yp1PH748? z5;%MSBoG0D&sNG(u>^uWmFNXXTMk1*fcXDt`x5x5isb)ENFZS11OW*G5;Q6(C{dz` z5Sbwf%t$yCQ4|j}inzLnI3pkei8B%2J_h5htFCzC>Uyn82pSRs42K7Y2g*wDczXGoCc&c=)DrtAnyk1KyUKc$H{P6_p5OqHWgYmzHByMAO_4|nJ?&b>y4%63skJ$ctc(=H;U&)<_GkF^~NK7kvS~Jxxtsl zh8yTRLJqHfN$NkF-60Uyp>zZv(%$4Y^Il3p9;_~xN{lXL(k)?rwxT1_}1e{``+HzYqr+k6Jkt`-yM62R3 zE{S0%r8`79AqFT8M~wib?wsbO&tOb=Q8kRC5Fw3^a={pFwL^`WKaElG4RB=QnLY)n zkf`j;m}>K=ACpYUOE5UF1u1=E`8*s$qqjFvYApH1aHhm?&=T0O@umCYQc4eo#~P!M6C=OtT=e>z%gy8TP>um2P9@mA2fT8cL9xl zsm42@Q_&Y!?0l62jXKLp*EuU&oz{Pe^> z4kwhfinD-q6_tNT9?kGODg4yR?XmnTOXb<#pC{gDU2HufaI}rTQy5ud{~hK~cyLCk zyr7{pVdbLIMPLlSa$56u+y-zo5l7923SCE$)`4}iMl9L&p)WX;=V9t6l^vGak1RXP z>igi(mmOxUU5HD>Ie@v`!iH{ksceu6b@|IM96FR-1}7CqI!&nJnPND~$p>hpX;K?& z9<4ePbVOHHSW7vwYiF@XAJ)f%6%kpHXHOOE$K*N=mf;ImI@!VG^5}7Wm?aoza1Jt4 z%$pv^YzV{?;z%%r^P zW1B{55v^a=QgBkd_Niwu5xQw~HRDAPs=p!ML?@yZkSC|UN`70)9n-iS=RTaTjiP%P zkKEb@i%#_dO`8O0l^f61T%J*jYd67}$B0qoZf4ALySAt#7aSwWc}OC}SblaL@MX_I zD6I|gXEiUPsk{|Fwv3@uHbvgx^HA;u%o8A&#b94w#oW`fH<|2Rfs+$+jpyD?V{fO{ zU{cV9)>TwxqR8k^72JeM{o|be?+5@;+p_jxCk<5#^X{xwya;(Vg_Pn9mf|tHK}xc8 zY^lsVhr0AHgmN_wgNQf+!YN&!1DE2{bIY1UO-GeAiJA_}-dfhA8fRUgF4y?sI+1Jk zS~m={W>i^1op5a`>fq}o@?^!+$@@B`pYto0Wuky+Z3Uc&DmbZ>Wh&J9+MI>^8qbc}p2 zQkW8tL{Yh==`SrsiYhVzYi=*SbAs9e%d%5wtdItOB3cuFJKn2Y3g34e{Bg^fA(mLJ z7}iGPscTJ63J>XBEqVO_d^POw7i42b3k00ULj)31N#7rHa5g>TmXm;H`RBDrj`esu zeOlDwgA@c*!W z@vFFiks)UtQLAS$dur|?9jUE^;~ba&fzfvU)BczIe?~Z2QTAF`997ENkB)F~83d=m z8GSSw3?>)EPI2QHP7(%mI1E;z)iIr>nrC;_ID?CTkzL~rH0Itj(OsE`x9ExT-s_$* zZZTBwSPHcoS3?-bjeJ_HB|6LB02bcy^cOs7wb`3$BZ-R>_rL5r!MWt*Nm^HlJ6oLK zYv=qR>E!uIU8TL$RapH^e7{$q$Qc}Gig8&6CaDuuB95zto{R3O!M=QyXWp<-NV<_D zew97_xB`WHLUR)XMxrNlPvRu)s-uw`&_F7jAK;+Wx%mIC1l-c#4!N2l`GkWG#V?sh zVW;r|@`nV_gMfLD$xAclouQ~b)nwl5z%ZFtVluBI?EC+3{#o^o=i?wn*}#8;kCi4L zOTdFT{(b%*^KUE(fN}MWVpGwt%HYOgI0CLd9{qA~w#IiI78@|k2R|Epm+`9)ob{#h z;)3ViIl>My)e~+*sfx6@)gAJ5S3U*z1orIqOJMgF;A{2Cww=6nE_qH&;611C3Wz8D zR}626;L%e9-ir#aJMi8ukIU>7h4hY^pBcyVeb_E>!y7kv!yibZKagUqcojBDhE$#j zNsj(BbAiT$>FuyMmDJ=r&s~|U3aH8lA(Ke(i8jF>z~Nwi8MGH58~VHnol5pvwOwe* z&57t!q{ZMEA3?O%9c+7KU;4z)jmF9mroG@+D43(3p1^F!kb4Fc>uwBV5X}BF$GWE` z3xm@<;Ub62;xIEXLj~FY?^0y9A=x*RY+eDRT#TmKitLz~s|XxT@O7dS*v@hS72hb+ zL15c@1r^x)4@Uw5X;*HH+fNDqxjvihJ4m9aXnxr>OdlR2*LLC@KoY)P45O}4;4 zRQ}?YSUjPUWd(!ib_fB(KmdyOfH-4{lD1awtY@`#23#+dG95y-iLWJ%M#~E~HN_#4J@vpl8aNiXB@`6!sf* zL~-wi#S?YjmGH$GT+b|;xz8A_x(d0IWQXxecNtmyNy->!myuwWF@#X^G5m}5!tgeEVE7*$ev{PC z)x@Qyy%V`b^3dHVd!ghwU*dW8*sCLdWaB^-h-wY5CC%gkq8N*kM6zs z#GPq>N)#Fil7h90f&E{LCxfFE)zzq zP|x&r&)$Tyb7A>=7@s_Upa}-P2WF%Pfoc9r&>DOfxXXU0`4^vqtJ-+y7{dA33U}t0 zK4*3f0OmL!eoSFrqtD~6bR#|5$I};~-Aebs_#9;npO`^)k)Z;}JM`xMCJgLk6wrKz zvJn3FFv%w83S_g~gJlS`=)k8l#ZT1Cq1+HM}g(BuM^_9# z=WO6EB^dlcvolHF|B^Gf6F}#}Dfn(yR7C>fh3>Tf1PpgM!L=9LIWQSk$gXC$@z1%5 z%Em?pD!&T+l?BKmL|@3^p)8AMf@knovD#Vw5XOCS5{R{4ra0&8wVZya@$F=rV&8pB z36i6|CRHq_!(dd$eZCIUnWzgQ192apHU|5rIMX(U@0cJSgZY0(_>IZLFGjFq`rvl} ze(}H5rr@V*J+j79YLMP7e?2JBQ^2530M3g;Ab1sD&1N+R;aP*r= z@MAGR!#H54ISv?oG*XOD7zcFngl1qIaCgG|bRPcS6giu4TSiANXf5A^7M|1) z7=;&d(A-8uF{5QZqht9L^3jy4VjQeCjE>23HLnuSQIl`VZHKvo-ngYpKrq^DWhR=L%DGnvkTW>U;>8Qk`{pim48Viziy*gCsd#6bTo~Q5V#v zt7jcUn{0bJ0_C@~r^D|iBjbnXrXKNpTh(7wXMzmb++_A2qOJtmb9AM6q1da@`i`YH zG#1CwvtCpatI5BS-CCU%!yiSylbEl2oG?<3mV%cs8|ZLDKn&clcG4vEKE_pJO%uP; z8Qc$nD_J>%Z-KzFKa`walxNX|;BeqreZV=$QQ6XmZ~`>+3H_oMU5(2bECpIMZ7Ms( ze-3NQxw(Z;#O2B3L`=a4&xtGdB6((Kp!}4$_zz5fs6dPtXPW&%yz;?+GrOio2Y{?h zY56VlPv{)1DOz|VmI=4=L;&Fp@D0oi>=d7FUu^8w%i2zI{`KmjfLmAO-)qYTvM z{GQo|OgIMKRltKnaoLUg9U9C@CN-1F1&KbsUP@<{W`b61}|G>O;zM*z| zI&yC7_H^)0=C2wC_BY7*b**I)Y6G>odF%YumO-dO2C6SvL=n(4!O1qXQ^BnkHy;O% zub;}ncb`(veG}Q$4|9ph`vPQ2cON}XwNIrhpT^^Ge~Z*dIWQ`>{V)0MaW3S@+iE2H zfL8X0crLd}-+s`z==CE_(Q8B>luYl5#)Y32t}>-S8Cp#OcP`BF=#O)A-R0>ft&TkuaVq#HLfM zy&=v-T)aLpZ#vbO`?z@1sg^gLjnS3wOtb6p72|=n%vaF5zwzbS3VKby)(Uzhj+7R1 zEG?}QzkxnZ*wV|>kWT4k$|%uGXAsL94smcW_VM4!?#W+VsC_4MnK}j7 z4gHXGNcF~gpXKNN4mP7-NIiLeYS-vC+aIwfKcg$n$w+tL7kf4``keCvxT)fT_;IA{ zFK|Pm<+fC3pVL|^X5JxE<-q`vG*Da-|2J+djMqX z9qh;Fc}0c_UdXR?9MUwLl-wG%}EF^7^av{(w|*kdJv z$eF`NkD@k~^5D-*g(De7h+rR)$d_n4%Mbks1_*!cVC*(|Yj+=gSYk<;Qs`8bY%OVMkf5~4SWT7t+&6x$4tx4EnvC@2nTqb3r@j;%E6|e`BD)h9Qc6Ni&FZ<4s zkm4vi#DATIwfoUYm%>)SnY8SK7>GT*$4x)mqo0gfW7vqPnE05HvGV(64Xd)7R(}7_ zhOZ|TJ98V>tX%PW!)kflymIJ^4Tz|?GDTju6l(*sDRW2=JghAB@pvmCW1(LzNmOMvp9k7?Nf`vumn46HF869)UK=b5n$q;xVblo?7vj zoE?P@a0(jnJsB%+TGnuwe61yWUvKzUGTpH9rWYG9YqCz>w#vV8?6gR}=|}^P``Z~u z_3o8`AwX?i9Nh=y`QW6HklWh*{P#0?-ozRrdTpn?Z56By^8BMb3xn}}pTKqrY`Z)+ z$a9os9X<{}?Dk8c{7WiOBdOLCplZ2B0GnfCvjjWzNW%_Eq6Dj+p<)QdEOx&2{m6vv zY~S9%Cj7tI;ptX`D}&C2@hC=PL?cA37#kx_F29ebOkkUc#A2{54q#i%Wm|NyEqeCX zRk6WQzfYtT(0e4Tr5r}Vh_6`r{fiAW;Ojks4Gz!kH7w)bDj7}OvgyU_a7UpfU5S=- zeMWJc#NtkurWAL&JiWNnH5oD5t$bMr){6DOS60QYT|2wg#`LRY{^ukXcSru+k$?AC z{(V9B*WlJS$d~zVZIypt6!mZ9KO&UW-CKKPh-ahW4gAo_8>s6vGGU8FJo!`{>Va$I z8;5u|MtQYdV0$NTtaMc}&g6*+YJc7M^K){t^D?JSyY0`n`EI-Cmb)`2-8n6DM(%|- zTsW{_X2IoGkGW#>aQDcunK#YM9DL){snhOs-8uD^DR-l%Z7~m*$utH=8|hr;boX$E+F{X2#vf2$gz@s@{rFg{Pfn>mm&NPj(>=(Chd*FA zfwM2J#n#R{U)U>4keMtgGzL?1+lrk7w1ZSC zzwc=rRvg{`iZl2fAWP{`dP4avq9XJICnc2Wrr_qK{Ep9CH2OwcxmSNVIJ@#jVGj+}o zqwaWr_HN^DK+rcScA(4Soa&v=qyDPuR((dZ5N8phL(u@GUgaIZGB`icmpEP`E0Cun z`nWmIgY$yYQQ=&qGoCvOWO0Csd6nx}TZRl~uf-HYZ+xc8T$e&>eR%|S=}cfK$H^j5 z6Sw--6RWtJ08TK$XA9U_&aK*$Dn??ra;3})hSKy*YvjV&u;uJ&jAte?xEuinp|lQb z(;Or9;TUD5Z2~5;{G>6>v0T`XO$3N2(7PJf&QUuyL37A}ioAnp>VSji@_4YWttOYi9B1%qwM^tUs0aY}(`RAF< zV8Ky@ZnCAtN5{FZM@7(HAqsBjIdX<2Bax1?{5H&#gGvO+9|U#fj2DES%N%*UeyROa z`72-V1`&f6sxDT=jrDyyQ2)vU$OiZ%zRxKjp8F}7euU_!?;MYwJYUj+1F9bAu*1dz zGdVBABKj{tw*~z7Q(Fso+4abr8yiqkWGqs-EAtgA?;|z?Ok%7wLckV=SOZz%hVf;8 zu~s0!qb2YCdpCzO$jPb*H?t|Z8h1kiXit$xQIzot@wMbIFhzuy6ZvBNgL$NvRq022 zqVz{u`ZD~Zl+lUOF@Nw1SY!2XQ2V8aDWsfz@{>OVR7Y0-*l3m;Zy(K&338kBH^rg+ zFYCKuPUmx2%v4;y#4|VaA;!#Ga3iKZM1P%z$9XZe9>l_zo~#F1!nD$K60GeDr3_I%xGO>MDY(iDcfJOmjDV$Mzqr@qgp4 zl*LvwK-PH%vZ-E(e^i~jUuQL>_%lkR-^jpJdR*fYd+n|)LsB$^AwC1O^-kc)RjIO;A^8T5p5P3gg*Kq= z3w-}a;BcBV$hrlNc2v_F#kyXBcW~A>%B{CA(zY|KsR;?Zftfu0nFksa;;N)T6c5GP zI_wT}GF~Qc%{{mnt7{}TpOLyf>iqafX%GKp+wiCtG zRTC^qU!dwUgn(<4fum_?z^G=i{-Pr5M_;}hCk!GiD2K;gq%fZJ91QJvNyM+l(ZB8$ z(=-riu_GrFd(HGVu*dBYD@;_%R!s`0z11C5kjHUU3;`89I^tB&V2wBRM_4f8ketDG z0JBm!y%riTm30=?MtI1fr=%(HYpSPqN3u8JP~d1==e+q$73%WK1sxrplGJxS3G14^ zckAv9ImgtiyV0rStbYS5;pm^7MSEzv(x2YTz8hvbT#Gt4?R(Rst%1|T;4>YCs8son z*{K?%o4xv7DbW>PeP&8D?A9;KB%L=9H!u_X-iua5F2@Vb+Y)Nhs!lK8c?pKyg|Ho)%6(JHGunU&~sOo~lctE{%cOk4ab z`BGde#yhXAJ_%`!Lx_ggR%F*StZ2v9yJ^M=%6T&Neu>K8$^1o2{tkfBlIM^=PVCtb zH(uuawOV9j3>NmuGPNDg7{H8pA&&3y!l)>Ng5a|3O(3S4j*Kw{q#zRIY`LQhha6$q zvL2_UUIj2?8k$8VD7%RX$j-(^U|I8NTG+|272Q{Lv-Ij+o9-RsC3wlSH8LOWt_&;u zvxqNzjNvb7jvqfiV8yeG?ZmcF*v`Goh*dWDz$&|Wp9pz}ilV}BZlt=|n~d2o%8W~& zbEon}c>*8%Y&K94k*DMfkrEx%F@o%_WH^g+{&@VmI7zMcO9Ryau&l?dN zRy(>{{EKBZ9a%{lt5;;)8Y6K~^b+DffV4s=V<;4{1xRB>QN##P(M(H$zBti8YjHva z;ubNfol(^RAhy|JSR9$l_U3)!YhRj&)>DR0?n;*`&cot3Zyd*$Emw;9rr!y=E>?)W zh$u}nR*$z7q5&a6IN0)?y@{)w^~MK{BDUvvzLs1@P$9z0-W07j+no}owj%neTh6;j z%|ALBB{0rCj+BwAga=T9((jh{C$)U9Qhr^IhRh-l=Co0xlGykYis+kwrnujuUt;v~ z9tLw}WmGALHs=Z?GOj@)Zr!M2zXKyUguo&N9E112f-OeQ8FWbMt7v<9Q}-z>E)z(q zcZ`*1-oIcT(S}F|w_MyEdI>vzV6AiRo8QfWwlV)cWJGy=*cpX#=!0ONH6$P~$l<%# zUD;nr;oUCa(anHYzlVQBGqA7utZ}6Dr7SkEW~Tr`56gaGHtxXhu=&&55HGp&xg8ys zmULd^N!ZY|JzgG&6Ka6tz6IP~P6aX+zLJQbP#immgU>mh2=)B@OSoYAAR~Bf2Zx?k zJrC5copA~w4-=B}1|X3OP&G4Ot^Z#EiEgWU2Kj+edpl#*0!_wYTuzpEvnA81e9U4|}-CgIbf~%}9k$*v^u?K|Q+g=n-0Sjm8Nq`FxZ^4&IC5n#I9h7;FHs zmx;I=h}iu!#(1Dt2S-)4qUZ+6aJO;O1#KJ=E=q`<=iMP4+@+Tw-e@hjrY;bJl4b*2 zHbTS%U@RVs_OdH-FVa>R(c#c3Gtl7>g{I$)7-CqzL=2k)vpk3}pDaVOS!0aRs4>nl z&{ofxoV`owH#Bby9EBqCf+;z&8DyL}8kx$#&UXpkWrT));Ik0|c9!1*ZdEZF0~~&^ zlMLs$jr~E~F;JNIoB!`|`dBG<^M=wU1Fb3u7F2(Le=JS<_Ht4@$VeWBoWrO%oPF*F ztdJ|SZa@jbli)b18CnhxcBB3yHz?w%D6opF=>WA8Iu06#J2CR308CK#r;bH-7}wR{ z1_yMnvMmjlm_-Hy3_r~qXi9WfUWzQ7^C*l$ZPoy_b*;Ok<9Fvgs3rQ%SswKz0bhi^ z9UxcH$NoYZ@lZv~y(bBMb8x3Y6_;*7->m>~+3*@gA7i_*+XjdF!a1P*-oz|IX)d5i zGp~Lh0A-7pTttuzxbO#dwLPjy>r~qI`F| zDCH(fSu0RC+y52P)^E?m*`ocRd6;w@WYnwg@Jx|#ArdZkINCUxHhA)za3qxT0R*yO zRCIGz=28-;VqN!pUN&y+$f`1ckqfLmF+hc!p9l7{iFSo^gEA1dhP@@bo5rTgRTNCyjVMTs%hHL}KlIgM}#jElj_n7%6w zsmBM^zN)Chkp6ARgVMjYBV%IKl*v?K&8#t)2Qz%9uxX<3YK)4jZc&K_B9U?NdEE6R zGeDuV(@2V&q}cY@cnTh9*u3+RQpXLY@XWWNsK|}@rvgMk=hA^r-Am!GvB!P5DaLZsJh&@=66U0JWto2_ z-jk!yJQ`Nv_DEbD{BvauV9s)y9ThM&TRkN?%df|i+G^8gaS{~A*IqvvJ8fVn;m-I{ zol8=&_?+4mhHq#*>?<6OvBuw_3}`Xpp}YzR8q=~=)+%f`Q)P}WNGA^9#V0!ft~YW8jD0ep zocsn<1t7ly-3SowpAgVA1%m&Y6E;D2D$t;6Y6O!_QGm07^T?T91$4Utb>-(?PKEYW zdw6A$Y%l@yZuJu)VZJNRjBa=1a>vBfGmXoJ0Gr!&#B=9|6wK3w@@Mw#>M$P7XBG1M zpM~f7c#gwqK7U`1x!FV5he=_S;HVuTHPD#EW7|Xd3t^gzwNE|HQENPTYdNDli-`93 zX|2AGX!iZUp0pO}C#dgj+_IHWm2y=S<8&0kl2j?Y+!dwZVoOr-aYM^o^40fbcNIJb zlz^q~{GG66&2wp|uu|NWGyp2EwXLw^G?qXkma zqnEKzT@Gwi!M*J&^x4(0+U1|pP*>`o*-)3@Ea%{&p)S!ssG$zV@~?agr>OY%hB`cK z5eOX09e60+0UTxCp~zAI_FO^#aen`KY?l6|?2ptOJGM)i@yo{TXY-?P2a5G+I4=_T zPugq!cNz(-~U^D0q8-FwJOA8Y}zcz5<=(t+2o5 zCLlSWZftcwa0o@Rk?+A03N;O$3m%L?o48tlqqll;#+D}hHrPAFrvNow9qmPWaJMkC z2&EmMxqTeZ)gR#>)d9acoVly5Gr!>ba){Vrl-bDmd&-bp734hN!SN*=4t$v4qk%E6Z?3vP`u|@~m9{W#5(zTOQo!JLA1 zL424ChVi$njo`0Wnu01S{^?IF0_~)-e3KvJy5SRPB0KUFD*tH{CfWO4C0SraLLk6_ zU4r%qlTE18Elh1YL@i~1m(Fu51rb-ehq-IW-klb}r}Slv9w0E(c=7D1d2GTWsm z)c-cn0|x^8y@j57V}QI}i+XkP5^tY333v(c@~zqywQn3t4fcMB+Y}v<4i@Kc2LQ{x<~-Ic z2#xbt(Xhx*See~`ZBCmua?_|U!+323>(=E@B!PZLB8G{WM*`@xif#@Kp@;0LO?ysp zG_muqdJ)BNDn>)Wk;hIqXMO;9idrAae;kR&8iPr9jc+`pQw9K~;~P4OiK@gLxsCLBgk zzUP|1F7tQ1`8(14ooxP2HGgNQ-+86{#h)iUuR=XJ!tle7V${qyrFCitqYb`38+F4Ybsi=U@?7I>)bX7EXv_3{^D)n&=7RjO1Xhrf1Mog%B zT2-YAnOqlHm1*j;@pQV-`*}#{^@XDk+3g5^S{V|d5u^o?ss-iOMI0ag$Q8p4q&yCaqRN*NLQ;reeqnHrj zck{jQG4mbsXxLzPk*EsR^QBC8gB`Cx2>fp(Z#$!4AR$oF2qM3WYW&;*5%t$exrIK zay8D*&r>2eKiSf>IslXqp16e4MGEQAn)Np^`Vtj=O@9G>ub>DtQqmX2yG`Gu8k4>* zioT!mu@!yYj!hr^WvJN0Nfv$7IYr;W{NvIG|FOJD8nth5ap;VnmeVJ|p?i-OkwMQ^ zGSfH)$+su@4Sw!KjOT?%I6uc-`43h8Ni3f#UVXP+{&bWN$63yCXkMP*Dlbcw_x7>M z>tmL;ha5CrRCi^qD({6hR(U?VymoQrnfv2SHK7k9^9X?lMB!gb{9B11BjzpO zN2b8N;Q6nMSOu>Z%%aTPfnb(+3d_JJjEB$YhjkurIG82%1SrDs5jw99Mg``)qA$BEzm!jDl?j%lV>RdriZCQ%MoKcaSEu~dF31k; z{=|>WcJIgqkoRI_+?7*R zB{w@zN!G7=CjPNReBs4p+8%}SHc>=PW?3jk7a&Amr9Y*mz4HJTpcYv5F)7!QUjR75 z*bV6i+?7$4+fB?(+G{Mga2~mKOnZj@^lD@Tqv1P^D2--0h8eFlSbYTFm>%oAXn%1& z1KZzfj27YY>^mU#dUrV_{kWU<&>5t+1Dp62V6=(O;6JDip)*D;GtJT;E@_ru0s&17 z_pM!J*HaoFZB-%85~g`7o5A1{|4(X2nB>*I#r|I8XWDu(WuGv=7HvlO!>?HW+lUB0 zV=<7H(z`-ShbTF#bwmiwzoZGDzlJLSEsf1!d1AY&9)PyfkaF3+%s4M{Eo-( zMEp*~?_~U9q+2ufxIKUsgRj4=qxOF*7Uz4eY$Vx09AS$;Gw7M%# zQI+la2P!L#C|23~FBH@CJkaC)BQ%^&djc|SuxIKD6u(A4eu34_4GQ7SYr*Ej^b?Kj@+dj}tU-aaM?q}nx@g>12bBwK~jF-Fc zk5S{0hCr{sV|8ahn6;k3F{7VDR`gXP@#fKbj$#%te03GoOv!S`3Z8FE^<)!plLCZE zA@1u@Z%a{+tH~pPZd9OG0OFBR1YNH{j{x+8nauVf*KBuNYK(QCPo)T^a+Mm_$=nt)6M`eoZJilqGkw! z4v|LWz9#xObC1cNvNz_Tj;Ov2^JaBRX)#{=Lg@z-L-->)gmEZ_msk6oZ^W2 z+f*RqLdh^JsF6e6TYg6;umFolm|r8+`4xD^7|M?y{uu^bQGoAK;3*b(Bf;V1E6sP| zr<4%y|651*k?8ftr&s~?gk~U+_&cF?o3Y@+wy{tz#`j+VZLgou%~5qOipJp@2V}&I z)R?u(f1n9d{CbLU<}_&p#+!$cA41Aj89wHWaNLqF7*zb_UF!Sw0~{v|gMz@JWM8Mip&NbY+KR;xRBZoCzHKhp#7<2jU$r*E0Qty% zTTgbY@BSZUjY6uiJX!epBpAnjWR>qE)m~qDO8m_7VWRiDu~Oy(#H029V-9uDh%VBT zzm&%>pmE*xiHW9WXJp@b1Uij6yDM2-jAP9L4ua7;lT(Z zw!^I@Jp;M&yWsQiU*O+nAxA!s3 zPH$?&qmtfPe!pv_6a48v;J{}>&jNNjppCr~3pIUoI|9IQKkrGv!-kFY5E?l1Iw z@by*sT5migUw!nh&XkdCy-}?|pBY8}YKzLq_Mo%7vwYt&BjF^*Ch_Rm8W?A((S?OX&hdhbcL^85heV4Zj(4T@i47XKNV1i?J%2H-JV^9Nfh zB{0Mp%u(R>TpkCwHv~%TQwhd<$Gz%zEf_K(ayr&d(7$@L=`+O8*z-Y4N|8>1Xm_+F zG+VKEefW%cd+gEY5kEHnqR%6~{oXR(cL6?P!1XM)VZj!24>Oi8Ipb20gP^s*B7Vjz z7@A{@0SL3CGaxM*(^k-Ksz9x@e`degl0T;pY{j1e0Ab|GLdc@~j=>`O1#v8LIgBG0kUuvv zO(^a2eHMSvvP}N$#3CFjz1HH-1cmwMyWq7WR;oYh5M#S?cZhxMvGr={3HV?#Q&baoATSVc$!*g;5ReV}vu+?DebA1-4O;a4ol ztw<7GFZtUWv-%QG_#eX?LcAB7#b20h+4lcizGv5zH_SMBtfvH<@U|IK#={Wi)lI;R z6jqezuY*I8*Sk3yTxtLnya6|CkdM7l=2g&rLDr9B2=fn1ukq zCSN;D$&C75%CC9{_2ydImfdN%>pZ26!(R8r`06+1Ou{dYc0!!ktQ4$-b=lkA5mq6J zgm4OQ8bIYWGq-v2Zcq2c);Hk0G#EdBhjOg&GU!Sy9zjpO#*gW2+yB<`FKzbjzN$$3 z%zb5%wwi|m$(5-*?9=w?DWpN`=)tytlXfklXkbq z7+F1EypQ!(UadPkECab z4eRj@3kbXEb3(O0mFXQK8?(Me^{fgT&wj@@zn+#KrKh6Sxq#``(h^dUp}r{Kr%Zxtr{ zFpGrXQM8E8Kf-ss7~Yz@@_s2QZ7_jE%5{ z@MAAWAu?B&5G&*^tsl7bv+--au#F?5>yf#rS9_z+HZfaw;NVEi?cS2z5Iwy@FI|K( z%4_DfZ%E#87e*w0oM2sV{PC@zUd_XS^w}wep(zQ*QW^;{i2k+VB2lhrBH9m^MV{@~ z!C}k*VH9g0Tdwf4^y|_s7fev44B^jo6Tmw^n zrPsZbrcaT~TjoIWWp{$)q!uJwlnJ}e14e|`x?(&79>v#ZT&x8dMm-4!196WBBhyph z^Js`g00jLd?7whPcnBBgYS00fakl|8a|@oUYw?dc|Jz$Bytp{@BI5ZoeM}{*VDdv+ zu_eA6Aik}>E91oXN7H7k{ud&u0u4(0u{hMP9Aj}uv^_e4q~g4&udfisL)?Ex|DmU5 zK<_~BcHRU=97E6B-vmVeS0?dloy+!z?ETDg#wS#MjYkI=@bS{&My7IIF1Q#aVuyPw zraZX*W|4DT3w_1l9&UL-7!Ui+jA#e;o1piI?*`JFNqQN+rRbI8 zOnA`nHzW01&`x$3kKeGj2?s}{`auo02>`?{C*7z998Kk2)+M*N*;XcNU4vhmd6vp= zm(x~^OOPG}rABfsOK-2WU>z|3kvr&eaZ5rdC$JT|V4bgykiZnw(E*lZ7~T5FV)S+B zxUNS6S&W85-1F<_Rqvpk#oi&mN;0DQ^ERh z4IS%>D^VWw>%pI)Uv4~Cufjh{zpm#@yE0me?hBKR={@(<45a_8BB`bx8c;NFaG1%hyR$q zc>AzN*@rxm_#@VA;z?{~AG!h~@&cv_#6IAbs#tsdzuSjPmHZ+K z2`$T)2~JdU0TG;1NqB!TdBA>W#>)ruHJN4}rk|L9HIoLRk}>`aBPbi7miq7dZ}tC| z$<%+Y$sJe!|7CHhmHykDj`6QW|M(x%cMSdalEfePH7Bu|{+|Vm$O~v8qW`XV{{Gkc z-{yPh|0C4@s+j(t@;~XnOUd)N`d@Y{sC`M)*9CJ;`!Vuq5=a;W5{{?;&k(^Wm29d18S(Og z{%5q%|J#@}2$hWK|CIz~14RDxY0aNuia66g^da^?_Z){mRbN}RKA!()@n?h0$(Vk} z%5TA+y1nuIdHEKQFaRVRk3T^o?1oae7_Y%T^l8DLJ}vlj8I#^DNiF@kgrJT9wX_eO z|JFYIcrzN`t-G5yzPSEntnsHUHa}bRj}%1rgeNE^xYFL&*uI!*zw={&lGvg ze;#yYqNA1n9Km`<>%Li?zm|XKCU7fBnvbPlKNIv0w1DkzKzxR7va$b{(hv zUHql3FaL{u8uOKf8PlIw`7PSta7BXIKj)Byw=vszy!O|b2zR1Jt=r##c>RF92E@w? z#`?P(k@QFCTg*OvN)XqV$e;Aq{CRU%JbxAuyAy~zru{zU3#-=un|&H!bFvwK%<^0C z=Nv_X$)BDip#lp>$K%iM6M-;VD%sM0r?=owdNcm$2#c%bw*J}(&g0pcQTAPv6S03E zY|7r~sk)(HX4+3VkACGTS?kFL)*4LBc@BOLJZ#`h!k{&2sHg90PpI=fczoQGy$0*( z?RfZU-Ue(q$y?E_21iL@q*jOh_13%^=4oYr#k55dcyc1n=;(4y8HO@&Xj1BoLD=Yw z`1b`GAZQrh!Hrz3e7MW-WBd}9870|91+?pc=3kD{&$W0kmNRV_8~fC1YV;-859EsS z!pXw{>d^Jna^S{S4 z3aiHt|BUn3a2_o=Y`&{palRoc&`wpL2A|BUc+?2oxCB|Dm=1dKco2e-CPso7*2K@h z==o(VDAe;^56XTPdv_6~`7)jzz8=s=5OOuY<50gqUAi%nMBs=HId{>c5*{iDkhBydL}(y?9B^^qzr9Kkm%pB$$NWtF=#St|TYi1;!ML3{Q0c@f#A%+QnX@A^ zM(u4H8S0mWv!=ayI5%wjNbSt&ouX%vUTM_bUR^6oK31waz%z zB(P%~fvO!Hk3Q}X&e_q})MPH)959bVE^FOoKeN6-Vqid~GkDlWE9Qcs`Q3OCNs75r zNb7MIx~BY1IR2H_GH?O!YpjyOv?2a>*)s>^pwUOX=t4r{n&`Tm!o#Z?k#C$iH2K3U zGe>F$k7;K%p)Q9va*5H*?a#<9T8kD@98%jR5EBBN_kmN)Yv6Ecn?%$Wql3yYhOlhR zPvewrd??mxB3FP3;^7waj&z)0hQzlZu_WS=W=%#1B#Qiq+9^DQTm@f)^tpX1cFkcjSq5}VppKyRL z3VgEybG0iR;EMuJR^T}T=8FQ~p}<1~%ohcos=#D&IKUSLCXZ10TD*k=d{N*T3VgqS z`J%x05$qox4)B40XcH5vPR9!@$3veXAR>1M8~Cyse5>lM;4=X?G6@d{2{xq zC>Gvj#B2On@CfH$^ik+9@CL-;^(Ed0g-1C5B3II_)tB{&!%HCEVueSz;B{4anQ?eu zI^jl@e)c!UdH zcZEkWS$xSO-u9n_FN6!;zi6EFWi$*HUPt0pDm=pZ7kO6U?ZLB!7r~{eMuoy7oPUw) z6`p}-3$K=VlNBD}{EPHbc-!%8;XOq>m%<~Qf06BQLqOjaJX?5o5idjG5zfEJ^9pYR zo-I5t@%H>E^(CBtk((6W8a!Kgy@|I*;StWi$mzhd)>~Wlzb)T+(z|i6aIYLMk8@E9 z^-Qc^8@D_xo9%CeN?$57$NA5}O)ySPlV18#J$c~W(o4HwbY}BQA->=c7Z|KMoFxqt ze{P|63z~)ma@2`&8b`c-z>BwM>Yi2jY2nq-N?82-bBUI$3i_^U8_WZU$itnl%RP8D z29bGcdEzy-ucq7MLMzPwHYDGTe%V+pyQX~|ab`Z!V87HuI4=Ko`B0)`*u~Yy zwu|$QZ5KVqwu|irJjPVh1~G-OFY7?cG3=r);PEy#O(C$01I3x#=UR6kh^Dk1Q3}Bx)ye&A4-k7WK2p7Dz3XcZSD)epQU8V2{7d*9JrJ13e zPrUOKUWSD?zqO&9NW69mFWtiPwlFYPflau~&#ivVcWD_v-bg`v?2h1$B>!@X*E_HZX`bO*k3y8CV{)aJ|A zLGufNgckPcEBTLrS{*ZcUXyE+9_CH)2>byqnt7;!D*4{0Jfawxn ziuIf$yDt*J%}`UJh1@`KyS3<><|HJimgaYbX`k zoaGzE>{-;AuBI8t7A|nHAPBS6q&^&A#n8Z-oaMWdX-Zmnqu~O0wMlP1|o z7f4c%`K2LHjHd+iKtd!PVP4~C+wIf??9_uLb&J77xL}}}dT}hZVW%Ewr~VS3 zTlKBsf?PB8+p*Mp?9{ntYQHbm?S=~mn@K8TNgC}WgUuvpdwAj>Tq5(yIuB8=tO2}g z1roszduIjA==g7%_sy~$$sEU+cpC8rD7;*=yvWU}I~{;`E593wm!j|p=U*gI;q{5b z%Ol?QucchV1@9Tv{bk1CbtGP;!XsSpI9q}4B_j?mQVYBag-5vHZBX4+dK_LY@g^%g z!UgY73NIxN?xjdq`rjnFEU8s z?ZLB!*PD226dvLHi)@ilvtpw z-x!z6Nd8YSPqLX^pJBKdcEic3)$05Ry_Cx9UXFeif%%V9r!jf-XHUr*Z)o7chPH{m znPx}oET<_X)Ei3uG%UR!jwoG0;WowMBfqYGI@w}vZQ8Tt7E>Cm63!H*y| z@ImXuYiv&-vI_}`%Sv0Gh}-~!R3CoIWL0vWbSP&=H3Z!2%S4B_WT8k&$p@#I2pTYv z@tO$FRuqrSPTvjm!0_ZUef<}bo`QAj!u#gw*G1@wtMs8B3(divzf)|WC-?u#I*Gnq z$jf8)nEb=^bp^RB5L;NIfcpfqM7p=y+W&XFr;ZT)h9(Iu0<`6EDkCCG&liy!K za<4Wx%WZvFiVv8tC^`TRYWPbD=+u^jmbzRKrN$W8T6=tX-4!pdz0OhV)zBetGf=%yC(lHo&hdF_ptmy&zDyv8!0!#L+r z8X)8@@{-|7^L+M2&M@T_i~ngf1|VccjZAzqRA2Csw6RA-W*dAZ=n0^_I(vd!ZCl#` zO^r}bD0O{IrT_h&z&UD_CSDWzfxp2HAZo&jKgT-DG3|bFC`)%YBxNP~(G>cvFV_F; z(u7D)xX49~bTT>DbThqaw@aD+ER|lQDXfAt>8%lbQM(z&Vx^)GQ2`yh6mO(8`KsS6KEJb<3!(4obGq>SV%hrb6I3In~ zDmTveBAc{Yv|#R&R_CN(|Dt)m81-R8ZDX%mqesFDw%-+=k`><2;2;e@{D4QZ$R)c4 zuR?jCAPA~f#+1{NsLQ0M^ceP*ll&;(8|r)jUAade>T(9}0t`KvGblTB^oN;D`t`rD zT3RP`>F=>ZW|wYJt@_Ik57Yq5(u>6(Kro{}WqkA|wq!&b$euea|T>l8=4?_}kzEi%7VIlayPyfX3iYwlU!OXW;h&xP>3b`2Fu2gLoZ)J$M>%R;t0q%fIs{$e(U*8RYy<1#yRY5a&_9Yp_y_6Qq)-U|P-R=ky3-*8{&zFw`o zV3I_uHK*Cu1hzZ-u8HfEF4trrZj;1|%UY9kT!P~4`N<-E*z@Ah!1ZYIBlRgRmATin zV!kY1UE0g5i|;7D&UVO*TaxskPA$OkH8|3(hiK*!1_SMZHYB?`85mYoT7@2MFh1!sE7ybWJ$itRGR$>&R6hi4ct7A%ecJS$7=I9diBP*{fyRlQxsRm zo4P4^-;_Azy4RGX_LZ}Igvhe9UfvYGKh~GSAW24RF5w6*mAcO$Bkai@6g{fHS0nSA+tRC z!!`IKUC`@%K*vL^JVAd{ClzjtN#o3?RL_o!Y3`?FybV2A&gdW0PdSFZeHNJ&(*ym( z{Vco6)T1qLA^luQ|IcQ6Bv?QMaeE@XSkm-ULiwNMA%La)M~^leQ~cv7Buk+@c(Lfj z9UsWr3naH{xRC^WwdHsG`He7Oxa_spGDx5iP&%f@X z*!;s)&>_na8i8kwJMzy&md)lLcou_snyAtFjOI)Hb;kYE%y@5HDi9ZMhVue9LG5t% z*#xZ8_TRXE0lk^u8^4eM1Qm49d#=13By9C3@gPJ5&>gx4 z-+SP@-t(_r5f7*5?*K%OVEYT+jo$b~ROB8j-!$yzEsLB*JiJX>8FZuMNlFqUvL_qL zX@0QYR;<0Tr3Td~)Ltfp#>kxLiuHSfP<3G&YLl8s(qD&g&#!|qLNHlMv??yX)_qmg z6~HvZ&M|O7eXj-jSQVdX;J|^D<(HvE<0PgxTmR1htj5I8R_8+6N%u!%@Nf23+yfq+ zs_c=rB2bgU?Zj=yr5EcL^VET9j7}>)ZEsUTU145y&e@^6yDYtlREE0j{5w>sqyZP4 z6^3r_Z0uMeMXB>aFrDhe1;a716$vJvs-eLcbG2XfyQtsPg;w;{mk}$MmWAQgiTHQ=(g=RG!+}yh! zv#bZd3hYR1Ke&QMNy$e^XVNEftV#!~1l&7u_w?TouRow32d*7ILY7!sbFqS?jDP9!57|VW^5U$6J#KZfTY=Mz? z1-AzH0_yv$seDs&1>gtHM^o=NqLJ`@)_X_fJ9q!c_rD&HcenXI=+tBs>kMX_@9R_2 z-?6^0A$Od?=dJHERDB*Y-_Pl#=r1$hx6Wj@i29rFvp$vb<%*fe^#De= z0i@Nwd<%fPTRhrV+CCg|7+LiE0jyua9KLv7nq~3P9AC;>%-LmF`b>rj4;I5y9J(XR zV~qNlohr-$4TXzWXXbkF0q1du@pvX{3_2kwg3_Ism54pbIT!Z9cg9ER2o@EBf>UW! zfH6*_I)Fa5p)hN3VlfED85^EzM>NhD3}<=*+uC^gZsYMP&IctT3!E8`Ll5E>lCWP)JcU=tcS^KkEKUI$e}a7`GZ>Yx z0Slqh3yBNvo}x)s6OJ$VJ+g0_aFn6Y zc&Mf|W7)R=-HkI{(i46Cy*M;5(~aJUK`QpBn1Cd_0|3GE!I(M&XWHsXS;%(bgD1d) zFS#NsDQ|;w!9Z-r>bt?67sfC(jFJZ=Y{>sM8IphSe0(Xy(JceKAz$Y{9$X0FE!kGo z_aJzJ-9*O1ZV2*+x+TbNlR|BeyA4WpBa0;Wpd{1~#)^ldIT!MdNVk4RRtBao7oLL` zFFMz@a5p@m;;dp(PHaX1sktQ8dl1o62;nc(ILCtQ23u{$i$iHrsu)SbmXg^QbFc3u zF&`rlETO0AT$qj5BD8>%BK_K|&ci|jPbh+KkWvKqt9$_(pc}RV9o1aSmtsFd`P#X0 z_a~1;b45MD*=iWHCL{H!15FJpaZet%yA^7`;lL+3JuUFl@7hk|&6x>~z#oZP-JH&$ zq9)Ii?$Qs1n0#k&Lwn%o{pRb>%uU<<(XdYnw-EUqw$;<>MM{N~s?=)RoR^>fryCnv+^ozSbFB1SP?DuU5}e zp|c`U|K}sM!-XJwAlgMS&KxY?)(#~NLPerF;e4bfWrZ{N2{0g;!FgM>70%(CakwR_Rz#I`evpV0 zy4~|tqj3h$A}gIA3{40eP9(G)vkJB|p}=iJXo^60fGFa&2^>x$w7o#XCNwE84SXxTpaC<^e6zFp%w0+=k z2SS|!oohln1P-4-Xu3deFrg;|4yO{@QJ_OiXlmea8lfi%^dLCK($WHlorHEGwEQa* zdLluc0ji|obZc8fBbwZOH}~D>4&A*+`>OWWq`>L~H`-?HcS(UmC*E`Z$WYS7yiUR! z`fxDY=zh2J&ZKlKvQKi(P2xqx>3Msn?JP`KQrX}V7QTOKYQ5MPncqRt~2tH9kgNsYhsEN31qPQlWGcti0nP?PIym6z5 zii$7+To8gY19^5Fh=QoAyQ}NPuE)9_7*H|c3ZNq50ir^@pdSJzph6HNzxTVk=LoQ$ z&*%H+kC$e;y8G#_uCA`GuCDHO`ophDPkuP4N6nEJYorNr&;4D651gW+?dGx zvCAP6KJv%r8iCO0FIxw(ko}Pr&PO`r(RpPnt-&ix)=?@Mad1>SuuR*$K2Ogb zNv%B@5`obJQe~6}5+mCeYRoM=FwQ|A=DAjT%Fut9Brznh-LzmJn*Mr@2#t$f=;2w{ zO46!>lG2$Z)~l+6lQNhjZ$TfDl*uIVjW{GJi%GI)a7a=YCVe7f{NTE}GHKyqld_rg zx5FlNV^Zj_N!`m-7aSVh6Vaz2I<$mBV_^5PwQ-u_@?8-~ znGnrk5zR8_19Au8Eq7{FMclSMWj|0+$g{$y;^1&X`*427japXtt=%0stq-lR<@;Fq zf!Hvpd7+l{q^4KC(dmUOaZ!*|P%`m3<{K<6Fn`4LS0I@bV?ONi_{vsRZ*vAfeu$nt zokc-jT2fqS1ie zk_wx%4$+H_U{&A1Q5CK{2yI}9nvb)FAuJlwoMj9_uTOIpF$9GHSIsbl2|CSrjv-9H zY0eW2VMa`I9%2Z>G|j1H2uP$kQyIdz#M6=tap~gR&JdAuMj}Lk>s$<^60JQSK)qmC zf{ub~338sokd$~lLsH_=3`vQ6J3!WGPRAaEq$NKyBrR!SNLunWL(-D<3`t8qU`SfB zlp$%!LWZOz|3+w$4GgeKT=*DPiLvt^{R*3gcfxJnSP}56b?e z$Np5i#LB{Or8@cnIX8`y+N%ApvaH3j)Czxxl3)zB!e1aD%Rk;AF$$SIxM{}~#Dh@N z@;yyM#JSm{UBdv9An4j5YzWTljON1cs?6!Xm{lE;J<)#C_iaK`tl4(}gkmx~1HV*R zr=9IY@R`_?$~IWDaqde#cP;VQEJT0x9b?Zu)|&kS0!2$BUrfaF#8UCtLM#q% zs^c^|?Hw%NutM0X9{iguJLIB)(v;PP)T1qDsnJ@-#@m7|Nz=OEC*_eHQ$GY#$ms`v zYzVBrqEOGIC=J**b9v3>GnW>g>A#Zc-{POe7zEsj{Yw2IYF2eGl1zBglcVina9*fA z!{!@XJ>3v2X0I=aZ;ByIyF`#>N3CJ0#P3;3U$J@+!br8Z)h92 zcb4wwKopdZclI+lRgc#6#frQUzu8uKBiE9t9W4DGXW62!;)tPlt=VoYpZK}61!nco zzI1EWr|6IRD~Assj+jj_I$gV!RrCaGx6-o;)O0_FkbMBA4+9Vm7Y z520YtX3mpA`|Ugo&SP%GpuJ7UZ+}?gf5DGBa0BA+(D9$>_&JXt{}#r-uH)a<@vE7C z4dW?qQ2sMIKE(1DF#b&)|A3Ak%5wgOc)YT`*&mxNoYX7HNdu25Yj@WUBq!O^vh8*l zR{DxK*5d*SMc;bzGgQLzM(15h&L?yQ19Szivf}eu@nju;w2tr2icexZ4A4Y$-&|?% z#)lE#lkqp{_-}Rm62||0J>qZF@$c#Q<5>PzjF0O0*L3_t%)gxRf7bDj>-ZCx|0Twc z)bSx5-<|OfGyXXpe}|60nC0BZ_-A$eFdZ*=-hz0|KYUL^`+LY^0iPsndrCFTpdk%5 zwI=oKqe+qa6u3h~>Z4?n(19L!QU*0l4Itdp3jYPM)&oE3v|FmLNZ8zVqBz_j0b|GF zTaZfDpM{kI_SieuZD)Y-{M$;JI30}Pg&A6x!v@QGdu zOV`wVlLV2F=1c?oP@t&w=y8})S7Lq=gk;7{sT%QyLn~qv3q2YIc_F}9gOd7h*^*#C z{mR~Em5UV;BvWl0sbKJ4QvJ1vVUp~Xh&K3~3B0pu=~$19MzrlwuU5&BE?E~B3~@oI z->-=d$)(hL2A@b9j+Qo9VIFH{M8N(f{vjlW>c!GD4$cU)8)=jc>EJgA!itWW zg0OQVq(vO>wNomD)~Itf-?=h$6y@P;z}D;l{yO(FDEn8BYPvgTNsQ_7#iDj}Mbx5i zQ3VFy)CXnoUH=f6z3v(?`$ioFB{nrkfLAb+YSaIf_)3SyAapo7#P8=z z*#E`H8EvmOTL3f`va4zS|4j83G(=SWg7L5Q7xH%yc|=%o76LQEWdIk-pXaZ-DibIb zt);RB%kK)PH7k5oFvD;3xxP}nU9byBF^d;%^4nj!Hh3_ba|#c?fq{?Fk*B_kz;fLV zA2XVP(yVeQ1G_PI_p)ZK25bi8ti?hF7$hrVcNY_>Jb!E^_ptoYOY;dAYA#QXe;imU z#FEAegNTRQ>GBn=)JFQ(SPfPr$Y#x+fxpxDFenq~#c< zflD{hAS~Y7Rqvtykk@Cg_SrcF9@m%3ora+tMYw1a3c~epAFwsE$|$akj`}+h*=VvM zbA;~M+>R?;#Qi_&L?Fiy^vw$V6sjG9BR53`nJ=NcxrP+RDL-olzE8c+0~-~%e2LBR z4hR(VlI#1uW$%^SE4{$dYhAKb?Y-NT7O2X>Hd63DAGVOr^A^45aed-*ed;Ot49kFC z0ee-vTbz?c{JBA(A%#TDDU!YsOm)B5xTb90G-!*NIC-VT@4?-{byMf1jdM2LEzsIz z8JFua94~70+TVNZFX<`2U-G5$z^TYb9!P)arw+WU*c;hX{7K^D)h`!n@zogk7{O$a zsm4v^cdgh#P*-7P1Ib9iIgy9)#u)}{RUaTzd9*sS9Iwk@n+!|(X?ZPo0Dne$ikdvs zx;x74>ddLbE2?&T?O%Y(&{*)SVs!>2Dwa#1VN`Kwt3N`9p<{6|C{%=0-V{F6>!m~E z`2_?-Gu<$;^-?ap=Z}>aa~BWgLKSD)E0T*C+8JxwllM*A8&IaAVofL_S)sns1;Ig?GHsj4-9RFFGDw(WK6vh=i&Q7{g?-y%15tCH%Ipe7nK< z4v`#J!Y$5cfb>jjnn3C~_a^&6^vc@+4_^f2Q7d`+tQ%)S-xKWx$hND7#}oQqr5Ys2 z4U+5p#`$7$dxj`_Q2OlFra>~tntp;NSg8JZZ;JX?4WN_S#mlMc?yW<+s<<+fr_Hp;XrQ8$v2`+Eiao zGNKr^vPNk+-X{Tapn2k4xxZ>T9@AJzp7+}gT)$Bpm2rfsJsqF1gTzQJ-9U66X0Z^B zc<3gYSy0YZANG~DsIM^hVcxrjmKtt*^Lu&GNJ^J-S>8b+8*(C1^11(|RSXw82_+48XeyBb?4@+0gKgn*;FnO>eIDkY|brbP9*fZ}0QfD(f zb?%ZFhQbIXu1!tx$4!XOcGcLQpWy{{dTJkU8r-TbmNH}o(GS5+T$8-VQjDQm7;Eny zrCjnMCfpTjOYKjv0^MzeuLt8}$WC>K_D!7mYlSIaWQ1(vU1Bmo zJCgKrHe-r4dSPfEL^{`-p?$XmFAnW8l@bLF-FxA zU%}H{Z=n?FS+!jksg^<36P@h%BUZ*fqxG`*$xE&y47SRQKOC(YA6Yl`ZtX$tu|E-t zVED1LHkFe^c_+*xK-ptGydszdw5u^lH)H*$vXQ4eygPWNVYbccN`uw!ffW`tEGjq7 z_u8*Cz8;mNqHe4)1n$)WlOb};y3;y}>LW?J9?0wu{^@&`^+N#>X64*tz^UG_i8CtPx9DAcaDjRT(1Nig~^S9cws zmbUO2^gf&%=hbi~Xbfur;oO1?bsLaFX7D!=An)Ied>m!Z1IGS@Y%YR^m|L)$ z!0UCf&>U3CA>^ZjXeC4L3j07y@4D!qd`?2ckx{+~AP^l^99b6}%zK5wi_rmi(=Ma5 zXt}3sJ68MK1699zine2!T;cjvW$kL~2xLsoc8w{(@@sN-;9OjC!P5{dEZjjvqZx~q zK^F#|MNqU+l3J_Loz;wFZ*=lN3|m(Q6e}1h%jHvC?WOPh!8%KgyN85a?u)uXdM~Y( zO==AlH~fye&z0u27L=C;s#aPHhL`ypo3s7h)*^ULGI*{DR>UeZFOBs*GEjDXnst8$ zgaj9I(504eZ?@1Et3HoACiwww0MdiMSWWmX5C@lmM%<|_w8ELvq+o%YZ#K%;SOfF> ze07^-Mu?di8$}TT*a1r6U`4r(m5}@5*pw_(a~-Q$&F}KmWjjGb?gR5XBv_FS$z2Yb zU7v@e{n^wYpwQvr%VG+&0FJvkgG6IQp+JHX5J;*$cpu528=Q)jFS-x2%QkMBl&Wjm z+Q32ZL~97Ttp%kZn=iv!Q0cN3j7^8-tCt=J_DA+EdyT!t= zb>$@(6VDXT6pl;z<1$0;fT=+o+BFPsCqhkxMkp|R)r_5X3b+`ogzIF4o9+ks%=KE% zjD)^Q471fA;B8DzJC%1H0?&|<^2tCa!F(-^@l`1`A1NSD?26xETEX)d*eml47?KT} zckE$Mo2=^GX!PUG?Yji^B--Zz;Pf-|Q|EjqBZ(w90J%d?onFo!=|(qBL15rvt~$ef z*HoS_@O4<%2;&%jQyJKO=*#S<~z*sbk!%8;ADphH%=xH!t9xOQ&8Fyz_ zyU`%L>((@c{e`Ehm*bpekpg3!Uh0ocgJ=LfF}BoMWD>Yc}r1{HEjyn>d@R`riNIle_t zn~0zYNfDQjl+e@a^e*Yj+u>?s&c8Fi~T}<@*mpxb6 zYt7*)&eXtj1J_yWftBCh4>_#5qjG33U>DU&lZ&~k@HONRL+HN{pmvjveC&X~0QN+u z4a6pSe@0io-PLz~2IRFhgLq&z5gw>; z!GCqD+HwcSQv=5n3!nx?HTl9nX>q(B>r0k}w>bBZo%~TCKlVIdta3l3#<^JM<4XQK zPpuoxVK5iLG983?ai62Q;EaS60QTsIuSK;(`_oEQk7SY+xfS#_<87<@2uLM>WdNw3 zX?>_LMX+f3hE4%Nia`pD0*DmKbE;+^2I%08`!v&h(|^g7_J0IU_bgp_@2Q zS5!4h^Fd6N(W2>>E6&uo`yHeL9lb?x%1aV+=3*2^DuZ)ob5)%{_-G(Z(zd{I1he4a zxZFV0q}xgD6>;f>q28oEnWUwcOoO+=+$(~PeW4sCK@?!@a_c+S)c|8yMi<}tw6|F^ zuS2bpnMB11SF4~WaE_wOPxvk3hZjr(cw~F*G&x!`>v_cassaVMSPV!;${6%H?jM`d z1st?Sb=juHMQ#NjQ(1Ls?7A+c!6A4JU}#23!ysz`vcWlF7(Eomr?>Q?UCmx+@ABH8 zmD{U5oMqPQDW-AamLatPkG6V51`BZi82usN$3oQe3f-XQ&-Ni;?a{3d~&u9d;xEG zxA`*7;jMsr{V2vfc`RO5qw)1)<7f&rtRI)D=U`O{?du_0+r=18(~9X+5WW<_sdt9< zWmpl~#dx+LpCYNV4YGzzie;h|z7UzLS@8J>h{fo9i63i4wjw|gdN*oBCq^DY4k;(8 zXv>W1<%ckXy@~vO<2s6sM1OpA!=lD8*u-o>5`v_r@BnHkRRRU^nBsUqgu2v-b!Kv` zIX_@s5Fc+-3JS?_Kd7sZ(lggJVDZFS@R?iVYr%a&*U&zg9jO(FR-d#l%D(3=dsEAU zx?B$wCTOW(T;y#zQ0L)n&0UKSV4Zm}hBhu|mjOjG$&gb|qe7hylx2ym+_H+11^+EH zgRv*DrJigL?_=86(~59^hi5lLG~W)uAI&WA55Ta-Y+=nVLkpZ?x;~l4oKx5)X$gG* z3)L|Y`hJ|Y)v4W(%I>QhMTWuAWNNs4)uKu5!2TP5BQQq#qCI@E@#paf2F5uSqnGWk z9R^|g5uW527vTKK)quxH6#10+{^_wFDk2;I8v|OUAdkHOA_gvJC z>$Im*IDidvph>a2sgOg46qBp|1~kbBbP^|NlN=;mBlCl7FejMBaZnsbRkHtJUn{#g zWqn2>x2whc!faJ6!0{G z3rxy90{0leCh*hwy67nYu$bF24*Ra@H5^9ge~Yl1i>ECRza}MqE#s#kUUfBfT&O>O zJ0(*+GhL-WekLWJVRa!t{&SwLIh|;{V}PF@5;X2l`69$Gdg_vHPl+GP_@Ap$(krl; zl8W{CSbc0tdO??TY04Kv`NdLvfd-wO5`Q7%UtmeknUC+%AD@wu>2zkAp+7z@CBA_1 zck$zU&BrDBzUxaJVoQw-4YAb@SB>y%vtjz3-l-xFx-tAPy!el);) z1XdVeF#t4bIUgWvQ1}6U!JLfAc4&WxRt=G2DnDo zF)^jAAj=x3>$ou`ezF(w*RYP^WxCkoSyG+>atZv#02u^+Yk=K#07?wt06?R9r4*dY z3SGLw{bQ4jWmq}mQQ<(0Qa0*Emekb%e<#r001pxP>O`F_LLlFyOd^nBfI9%7_UBS+ z`3GwWp%%o?N{MG!-J#TH8_-D~eo_Qo27)wQ~g`jq&$7(YnIKbaCgpYa29d~HhnV~jtVIBkM6 z4e9aOEY$oT1FRyD3AY!fyiMR(1N@u7sRsB5fp^R|4-+UhDYXPL0=j_71g@;mz+D9V zCgmmqQw(qgfe#HZ1OVv!%U#K~|BA4>@gCs3(PTP7XKG8y#IQOCneg$3l=#hzKY<^A zVDSAuhU%U)zy<<88sI$wT}(?B6X;`r{}6c5WP64{Ka=tZfitiJM2h{HK*S(yilk&>Slxn5`1sD0_#ope`0=Dkn)11L*SVYbjp_mZZ*J%1a3FL5&}Kf=xlEgC^o=+0>cdOIDx_Dn^^>IGbz&v zJYawz05o95m}Kjl5LOS|B@KHyCH_su2NAC>G{v6HlF|)uDuFBm98X}90dfgEZh#B| ziw&?FuB+h$a2i z01*OD8ekHEZw+t@>ha0L*DYay=mchDqb$gN~ zdl6Q@XYH%Z$2)6L(u)T8j=+ZoSWjS`0ag?E)Bx`gc+>!|06^_8q}1{XYgu`Rw0%xW z{4f+Pj$h z>Tw#l2>{SLi)gsCs{K2nQA9KfutMS&=kbfK#;$a_{vtQ!i*Ed4&+XEnt|{@EjNgoS zb&V-$*G!bula>+``#k{E?cA2Edn>}~C0)`-De<2%{$Z9>cd!0$pmgP zKpz4(8z6_ktp?~o73y{a>>_Zd26Rs~BSv1Sd3OX>ba;s!_R`kTyi4liMOdTbelcAB z;KS;%o7c{_M`zk2WM2`h;AH=DUkt|0=)}zEh3el}^D_UHzUa|D8+Q9)u)|bliw)nd zBn)#^C0+>~mXF_j{9>V7iR%uA72~%UzgWapmg3iqUpIbz`1RozTUC{nc$2JdQ6Ufm zo@tk-vUAr~J@8hy3=Ia9VdL7>v9t4*j z1iKG{JH0ROiw?=_^j>##Nd7@^;X!ceL9qKE*tc|4lK$|Xu)=Smp|U}V-3pNZJYQ&1 zX^)O*>QMbe^vqaDh#;i zN5LFlHP)-Xo0y)~GG|nsq22G}{%DKNWM=rKBjdZQ&G|EOCfmzqDtUj~-n^&`>AchH zGGunrCm^5P=j+#-+R}U>i`W>BLVMU2q1ayqB@)C6e*}KPhM0beHJVmdo@RyXkgnXg zqe!kkv5hewWs6G%pzPw}ywg!%oG44&c2N-^5q{FRsBK+1){N)N^xTQ5%4a#3OIv zWXat78e~?Fv#cilh>=4Rl^M6_(8xKoSk;f0+&xcY(NTmu7d@0kuT6aCsi!OiCcjo8 z`;1Q6RX^r6_eR&>tn+<(Xg*^6(;WJqY*qU&!6*7Is2Y4gf2p67Jb3|k_2Q(4mqW?A z>z#98GfVP293!iH=s{xoXGmd3b244r2H?CA?HZbt?Vffq9^vhPM2+l#9|f2&*dW7gW6B%Ss5>~Bw7b6=E9K6tR(M!_6vwr#`dM$STYd2wM z_pU;o1WC2$r8q|1gZ@FGaErK=w-K;e$NmaFmODO|Ks4sb48o z_MDC?7rlz`;+OG9xBw)53O9G9mRf_fw31aI=;927Ix0EX-ePm;)ead{NN<6R|I+jy zZ|vOkj~C~pwLDoT_g$igfPI_z_6(Ad$0y>g@YxKL*i$J*f=8-L0^)5N{tWel)6?J` z<15Rs!k0+K&FTg;k@0b%>a&4PIR+M^F9delYP+)Eyeqac%lpl*j2DqZ}mm1^RShus@HNu=006o1l=;IFnE;uJGMEc z4mO78%uo=l&BY|#C2TS<+KfXyKcN3RnuXsy^_!S4)^o>5^vTHxFTM+ZXn@vxuRR`= z4K4AF5}zL}AEY$lTZ)jS*uUMN%XyaN+#N4Rm(f(Gdp1|^SCC`Ko%uMw1&@Sh$#L;{ zDiE#8Q)l0ROEdU-6ZcKq7wwgj&l-x7Ro}6qvOs-8L-T??&_a+(-dFb2@6#xpKomsC zuqp00yQslH0M_qPFr>6Pg3a6gHtc~DIun`T?9{L13qo0d4t3W9o!~ET z9Ol+x(4ikcXRNUX#2Daxv1lvt8$pTs~Qznka zm%iv6=B7+K+E=zQ*wsAb>a(R3B(nr2pXQsslpKy+)f;`WItkl#OqRl1o+5u}m%Mp8 zW_GgwOn;awx#8uR5I{;bU&d|fC(~FFM1{Q>qbYcSvJovCEMURE4u@kAc6#tqd4rE$ zxF9R8J#F=Ld_qbc;t^Y?hT>}~1DgZUXNhX{NooWN!S@w7=8#f^dI~PbEej2u)tQIS z6nF%g=BBgqb@Nv+2(IL>aJ{%zMZ3s>59;HVXLUT(Dd zq)og94hGdDce}H&0ZF-~x}oOSz~u;nn{bgQopn!bUR1263Hj>qf<>F%fQmoD+y4@+;~655xg&$pVM#uF;+ zcmA7nV@ih$9n?|`>dwV_-j!nijABihCF?-=>Z4QTB|2{58Ok3(5i4x1Nqiv@qHbaD5*rYV(&ZAHP`y=)rxM{9fY|AHiIy z#PQjnDuIL+M5uEO&5%ZY)lrCo6bazILfq(pjavMqfm z5FniNy7eGV>Rf-K@|B#Kp#KGgP0343DMP#krzIts8mm*u&k;%*Y-Pj8q=7eHWD~8^ zys2oZojB|XoLGX+51jPcIR&Q#J}HuU{y|qMtFuw@;CN;{%T?cBNhxbZ9wv|A zzN=E7OaPp}{behx8GFDl0pM3kKkfi;hA3vXLgVmcEjpML6i_GsAg-9w^`os$YwckN;`{bOZC+0}IrjaCIlhz|z!Ij{SO_C9Tcx zYDxgPKDZ0HmIcn80>{sp6DZP9EShC9=lb439RFFq{vY^?8ga1~Jg2bK#}z(}&FA@C z@HFKgD04fi`>_8<9L$B3B*a2NJdill_Snvf=$q2Mx{FQwmZ@ivg-wg~+Cc=wcbHuq z@Y)3hIEz9h19qD!@QwWo?#_v~?{E05B^0lx=8$@xmwF0yJz%m6bTv}4W+N7jYa#8^ z3V6)kZSJdykC%h_^|!ht^6Swk>L7k?@SFBD$@u=?_|^4xl3ytgNW;VMtLS%!(I-}_ zI(%eMP+`=a)Ger3Tu;(pFGCzoH3ZxM5=;btY>X5PX%42inn5=Z^-uVDgTOM5&i`+C zp)S&v#qO11YU=nB!2h9+EVRAlFBlVv*-W1d_!X~Lt9l9;XF{ms+7ID6OQy zvwK-49#+96Lg-;o6>rQfOAj7ly_u6f%3}wzK&FOtPv|>1?^mHxeGS+ZS!oWmOWNfU z_5LYQZ{%)Mj~p3cRoL^#ihe#S@GNH|Zg3^^ z_DrkI>|Sm^N5q9~oQOCap1^y_^ANKH458fNFhr99J@SNJ=Uc*E^(GnaS zfREyEFAfcKTPq}{XJ)h_H&)qB=i8Hj6~4f`Ybv|8d{BKZzHxpdHQ`*fuqAF}vcgXy z$`f5o{-#y-K^9V-OUobq(fw6_BWvL}3%ji7V+>V)hA^0FYG_09JV}l%rXu8zE+F%$ zcQ(?(onk)$+8i{=Zk;2Ji@;+Zhlkunn}^!UqqB&ITo{=xwI8nd8&JF_DtPgr#;o6? zTu<4T*6fpr0}kF){pc(D%%361aEKkBf@xIv+ZP+x?u$*y?WpMrtLF7!S3(B_y3|0w z3d9@UnYLe`GYzy)AQ}Og_KQHr3KYoQYb_{?UFE7hGQ7@;@KxuU%wm_b7oA#%UMIP9 zug}IJ*Nh)g1DvUdFnXc=cn$J#4ExJOrdVMT#$UCV-!FPj58o3jF?^eE#PGF4GUnNz z7YGrAZqTaZU2@#JSZCA#2azAXs*g){I~xJ&`aIDEEH~M?-l8q)6pRBDID0hu3d8+R zz|IU{u!8A$wPbNyT*xJR_YD}3JiC{JvfF_)Lg`k7>n(&btq2`JIZmznc|5>tZz*XA zZE3d~@stN#{koU6`Ryq^)5iVacP;n1mN;i4lOKc-q6O?1*idH}YS_I56+Df?b}vEs zG{Ws(Vu}y7qx9SGA&dKlog${jLw3a^%4sxYmrn zpukwAa#kb4Q~x~Z>l{E-G`%8rC+@V|jtd1Y$Ms(2`yDcb^(NyXIJT!Fo}#4ufb&}> z;4}|XuxuS(hPxCzwdEboevldCw;bYhco`FG%S-JI;ww#g!Gc37ll9ma>*66dBtAW) zq@Gds#Rtrpj4+xB@(tIw;FatUn_s)aRT7lpG;6qhF}V(8F$tz#{Z|fVQXv{O?ohca z&HaW8IzRSOqHmFwiwZO|eO3Wx8h<^Q2^vK5fS&M6;yf{{<$4hZrS12aQK?E)?Tyw5 zd)muIq+q))En3gn4id$l4TPh$9RCzcxNu0HNKg{^4(F^OsG@wor3MdX;+bD7jE!03 z0WXIU;S25SHvw;mWX%li?C_T%_V*Cv6|pxcPD=1F@#lCI=`_5nbh@tyipU;iDS68v zLT&nR)+fkWE?pmWbMb`36DzC;+yPk6vDSRf2+{}oaeRhYoWQA57ttOm7 z^?mB8;C;5u7h_+)Of+zD2z7L*K&|rLIC1A@jErj|`~arv03=>#k7?i~jee5_VzQG) zKZJFtH2Nk`>3?YS#oP4*4tyz!=Rj%YK`_Ow8JYw3escYxrfh#`8SYqZ$*YLY5R&8E z-amky)Ls%NdC$PPS<9ZuOS8gIS22}pLT7@|U7^UcrO$2AggyrKAiD1&PBBb)X;(VT zH+k};z3`8ou_NcBY=70mocPeqwLBq%U+)utk>`Ltk-MUyYoh) zLMy^EQTieW((pD@LkVL2(OH}hDr{8|(|6k18^wOwp}v`#o@Tny@0w8xIyl4dMFQ{M z{o{4{QtKi~lXb;5X)Kp>%Kh(kEtq^rU3`TCe3fW0G5_~^U0Mf3socoWDYd_;>uaWt zme1W7N+Pmw;Raq{Qa6063-|-j0ddbk&P00>+#nQq2RpJd__3jc;4x-s8z&b z5J&KrybnC-im)HCw62IoI6j>`VEDh)vg%7+i|hYT%MQHua%e5jC+R@@M$%%dcc$a_ zy^K5;a+41LF0Ibz`Rd=u#C)(gi;q`qP(KMGa(G>ZgCJDYBUtmI$FpYc&4bN7l#3Sf zpSJD(3n6Ac6`5lLX~!h7$X0m^X_(8p2S0dR=3+v2C{2jjs`f$a!Dlpbv>|BY+RQne zks6(T7sUp?!D3u1KWfLmOTg8t{#uVR?6IwQ?8YcPI;`w76m%#BHot*4gWEwkmdh+d4o=OfO4fI{1IbG_)LL zXiSCXf~*yx2>ve|cP$D&49Drk#lal62_x(fj^iX-ci4VD{VC~ZoT+J5KjPEQ zP5OGiwB=8CNXtUdp-dm4Wo(PQD&nc1Cu6ebM}y-1^kJud`eMB4r@7>XI&E(eW4^wL zL0ybpX5A|uYwn8bV`$Gi(!5Q^N5JJJV5q2&2k(;nv8>vk^RSAm9?fxIJpssLoHuUC z@WoybWx$4M08{0wA9D1_`Pw}zp_?{^C=vM&cR5&**AVbk&1pcKxmUyk)vPHLUu`xC zZP7Np<~qc_b8xMp*GZ<{+xeqwo!+@t{k~sRip56f4MvG(Hy3vzE@OGJ2?|>N0(?w@4FIqW<_EOkPhOO8?bo{h#SS z4d_syHkFZAWCu-CKTi6WpA#Ysxh+A2DSRR}mX$SWC$G=|=dcrC$3{t=slOC&AE!2+ zvh+~u*Tv}<#NG7Lc_}Td=~RSFE={305fdF~8#4Yg6aDb~Sb&270KTvjhhGQoN%bs^`Rz7Q6}5pEY+0`)w{BqN%>jA39)7 z7#fJaWrPGyUI(vG76g_r8f5`E+ZsUI5lU==cskZ|?#z~k#+w&E_t@!Pl$3W_)#Gxk z2lHK%dIcko>yOx5tRcQZhn3Jb>eC{5C2np5w#HlDNZs$p?w`3zJ$`$Tszs4vFP(5{c5G>a5nzyeNjtDkNE(BY#E-IpF@i)PM+b%fbubgL{AXH+ z8WZa?O*iV5X=sQ)I?so^a3rw8BM}Ic?ZWw3$PYLgFhMGJYCFx#wI#B-6dsFMG>X-7 z8F~{yylm=^EzV;>5Fw}k1%sJMgP9Z0rz4*K4%4DI!p`x?%Kj6h4(*fZ{{5l$9BU>I zFtca6N%g_u91W4}n9a-Wmq`VU>Q{)+{SOPx8UXxcH%68Rnw716U7dRB0J2`x_OSU0 z7=;G^ZBQk){CXw7hAW5HcE2vU(B5ua$v%_8J9Cw?r*`pvTsUkddPtR=jMX+QFi5lmKRX5 zM7un(3cQYSbAhY2vZJLAeAQ{cm;N{6z=IqcRNLtZ`wGO5wy$7>M(a61XkR%6zwpU{ zB*OF>>|4?hUKbQU%0urDh`uKC4%YkUpa^6S#NHxXSm8y0$$b~0Hq2{BMCS+tf&VDW zq9Jku;@$EF3^ERwLvEL+3+Nm)fbxig7$)lM|P{SjN$lc+sV_A_W{MZiL6Lk;;98v)rci&^*Q17N;V!P1Is(6C1yyjK@t zbm9$Q<_N@IBkiyr$c%75WY>0&6`6%Hgjmm_6jfW7AXab)rd49Zw={X3 z1&4j1kJU#Dxe~6oGTX>DO{=;SIWT&Y`nhC1jD1P4AwQ~9 zZNcVYbY1mFoon2qUV2!gQm^Tz`{|;Xw=mnd(oIT8*Q%^svO-RF#3Bn21ZH3hu0LOzrb?V#uO(!{5 zqN+Oe^c2%9=M#bFB;a1ay-vNB$iEj@yWg;Y@qib|WvU({RkN0_Y6sc}w-_}S3wv_c zbto)3=Gf@%SllQ3FU8SMe1E_u?P?}mS0EC&us@ay`=i(|sd~xMI^H$%M<{~tJ9%Us zy=13-SN#dtB$P>6ua{!U6V*~e3z_I^q#2Dtv8*T()pL_T(k2lBC;~$`t}RlI-S3f? zm{E(@G`I-^QamJos9=M)slm^sYT8bPNb?#NrCN};Gdg7p+WtE_fu(I7>e$Zc0Er|< zR^(2U?rbys(b+meY5nOiHRRNT=y&k)$BogtBX~8LZs?)-J^nwC>+S17u8BBOKrc9U zKo2hGY$06|Ns=vk2-)f&Ksu4ldN!48GC!wiZ$dxRunO9L%M)gtaJ@m(f8yFbbxo11 zH*iVd|GM5Ie{hF?Yat~WLcx)0D3CJ!gPx>Jf9&-(t}UvA%z7G1$1fZt)}5xY=iBUC z)D_QgHHiD}5$m_*f}q3VuUe3ybNPO3fVKS1vtXdSxhW%#u(yqZ{L}<#u ziqjmjuFjZqTh)me+8n?i<0CK&%CW-7qEr+Ryj(qtBK_L!1p<3qAlCC^m|pz$27O;7 zh1|Hl8C33qj~rZw=sDb0ux4T{-{J62of?)}Vi0dH_w;bDG_}OsJ{f5(FKRj=z5l`K z&Br1Afke9JV2s>IH@*UR=itB*AW^L6ZD+#H@DDU{F%5p&tzaUQb-_BhnuyN>heqrA z)SQ!{)h~$+YNw|BEJh~@g}sfXU45Z%+hc>WojS@@y#=@#1z%`C0QLTpZRQSC zN<^H8Lctx*CWbYik^c+$W$>@~1X%N9w&J10m#-i?bU8xg+^^1fzBA zLo(5W_?7D^Yk`i8YTB!?@yR!wUF(0ZQO?P&I#tOcQ6kq7Qto_oT|X(0)m+*KyGWjw;0# zv&~Wxmi6K)54{@Ysvmpkci_JOU@rT|=3XxDyUAs}vPsfXR0lN4S3rL)et?}I4-{u# z585*~GK-hA;|YCj1S!J)ql{~16-PTDr7rs&B@hOQ|475`06_Wcf`X=tr2Ii0_ zeNKz6Xy%r%XuJui$IO3J+qS1pc8s{A`uGQ~a z;d3o@no+zS_joG0Y92WaclDl(Q7_!4xmVR@Xk?0sOw)|GoMU4?z?zG_z5|Uz0Tcw> zAMS#jMs%2_siirZKU$zoqma0?HH6kj0#oc{6|v_ya{M-C(oG;bR4>EL+f+M5rQuSe zqR&I2W?pH@)b*?Y3Xnw3WF+BNhMpDk~IjnpG7d5*6A(Hv1lSpgjTpOdfrJ#q0x+r*o4f`4)~y43m=rh`yIZeWWCAg z^w18tpj=BAl)(oaJ^*JeV7x1|15PN{;wrkqxXx3z;!ydBlO?IfhISR|N41V?08#7u zL8TOtTrKBqvg4CdVqT^_AC^1}!L0hPl52v<;~;_>1$mKF!ZDk`+Q4Z`z4R~c6m3=I zsTuIB%P+7%i*$eD4elsq{rnbmLY$S0^?cz?et~B{WG7(9k6h*iPr+nwMRHkvRg_G_ z_D0ujwRY@OE;CT%xb-ctBpghgbOyi`xB9aD!y4`d4a(RMZ}1hFI1%{Akn~ z5OPMMufQKoA#x=CLx>X!LsEOEr9e^+L?svI*WY6wfx1Dm1#0wTRMX?-NiR4Pr6b+( z_QK{%a+x;cTQz7uwg*<#Md$E4PG> zTyKF@{hI_&9Lc7o`mod?N$>A)pqb7d2}#w7)asI1n#O~ZDblyCYFP|a#S-UkD4K;+ zh0w0cxEUdA0X}%GlAp%;;QO7z2Sqhg3am6MBIg+o#|gjNr#WG)Alzv>(BmD|Eu4t; z4o-j9pvz$I5_O;e8b)&^_@Ku9-#?aP;SVV*WQ zOCx77?!9uSd8)uPpws#NSk~vCV+%Rf`;2Rj!A^Zw$egU_5%gK!CAi-J&_bPl)YXaf znFuD+AJgf(u1cieIwCdwUY)+~%0&7QWKDj5wN8I^cq082WKE`*>GX%LNThc~)?|7g zojz_@B7G}@$@IM&qh=`#^braz|BcU_W5 zzxC48^m}#sx{5^l5M)h$f3;43HIPU@1zD5nWjg(#p^5aa$eK*=qtnM-oJik_U^0F0 zdfk41BE1R0Wcuei{S03s{dokF=?iuGQ9}~xGZ9RtKc>@nl_%0~9h{neuTEd*O{5P& z*5vnB>-1L#CDKnp)?|8_PJig4M0!_bO{VwJ>Ek?!^sNXc)AxR++wV@KHzAlz|6He^ zabY6;c?6T`3w8QY7bMbWBA85nOsDTUFOh!h`Kjsm>hyKzCenu>Yx4W6b^5F4B+^eo z)?|7gBw!g7rugD?Y?pP0_m*~sZ#xM7{Or!@{)6DpKh@*^4~hDpM=)9cLY;opS&8(S z2qx1X)9Jg;Or+mBFp*AsOF3?u=8?pUVmadW6IV?>g^Me$T5so`Q4qKP$HE08u{^?4 z!mw&JZt3EMHwo`G&f%J-Slx4qzW(! z*QGxGrf4m|US&+=9`l$cHmgBSQ`F|9P<>AJb^48B%j@fg8ct zq~1Kx6l&-lno^MC^4Z~nLPYzb8bzP&$zoWS;^~=;4;PdopEYB(g$ns(2O7n)sb3cR z@ND`>9^b`DCnvNGCt3HgX*?A6P*xz8xz-oEGM83?q&|n+jDba=FQWt-UGSv6ybT8q z@Og>PE)GCv${5@1v&Uj{=E^oCw&SF&{fz;erhk|6;-0^7}+V z1Ac40xQCdDp93I$ffo*YA-X`KHzFFUsL#gz_+A^26(Gf3(qQIe@3|-&PY&SdRxgk! z7f1Foyml}Hy*VbsZF%<~q0qxaWfm6JN8%BHw=-&hu%B6` z@qq+*o4{KJ+FFr*n8m>aUQEvHe;?2NjZpTuE@>cBFY;qqBR1T<)?h5ocbw^I+|dPF z3;EWJyI@O0mK+}U8`%^tP$)Ma|07roW~xCjv{$&Y89^(IJtmOeTQD}XHywGXis$2h z1V@D1Qo z)CVDCe-gi;y;;a!n9R;aV+}JPdp@FrQ<(J?$=U^3OOsjKQ?eE_>t)Q^AX&R2t1p=~ zA49nY2`tskthkRNT(A}~$TuRH&zF*~64BtWg8XuvlLU+TC=2qu_Rrqvm;x`~2F%g= zqnAgL4^YcmH?|8}h9jI3wMG2{=2AL6hPP0Zu%kj_3P$JqrlV~@p8f)en3NAB;@!tI zpGiY>yeoZK%uGozl5J>aThIau9OOD&XU6LE7junNs%yvM)EBL3iv_hPIiE#OVs5l|EPjO+FUq4D zLZ3%X99nlc-b*4Rg>*s)pTzl(4XtA>sJ)iIsFhrbEb{@@AgIyAJJXrW#6aU7TI8mbfZYnV|IbO-{)27yBSR^P|M z*P={RwtXKuxo zD+NWq2zCe#3VBHI{*d5V*uyW6UGMTVe%k}{Pyrsx+oa}=(Xyksq+ua(`qB3S1V#>R zOKwod^A<2lGZSrj(U1JjUH<`Q4_w_uQ>AZ!7gHNzamG15!QxH;NDLhK-rjQBs5;wo zUOfx(gqA}gS_%zeXq!K@EY}{?&Z){jf@aK^zUopFFSS z{RMiLr)al7V_?Cc*l8DV>v>@aW;-M)6-mF2K$duI48XRfBF#?8aNMoG=cjdwin*?`*x424mkiD^TO#)viaMcKeB-JT5pB|*g=UtkaQ+QV)JhCF}_4EZ%M z<0M1O0{E^CzgBprt_+TQnpPUoLId8cL7xFfYjCsy#|RjzML{NJEMk(FJpl-qW#C~h zV8)8=@rCwKpFM0eX@^u`#;<`HCx|#^3|QeE=xh)v#}wTxl?^)0fZu5_U_hn8F$UZ& zVCaD)W^IT`V%9fHFw3+j=a6QC*=hFBfIVysX@)y zM2ii0vj!^-I9h{a4LC-?P+bzUv4}}x_5>i%EX$spOPZl3dwj7yw9+0nmNY{uFyq(2 zj8hN(liti1%ogG=Q0ZkVYnI9e4K(0)8oa`QN`pZIZWk~#H;GvrVv?Bk?IM_Uu_yN; z%>=W7_RuTrVL{Rid4U9GXfTJ}y$$*fm z$Q*h!i5YaX6wICg1e#^rlk-S3aI`(X)E+v*9yWJp*^7wP?=29N3j zImhcnnlJ?*C!jHWKM%q)VE^j3H^=P-5Qe$lbMXcVaK!87_u(LJb(-bfU~e37ML~i3 z>V9rfmS=mS$8vpDj>CPuLrZ%FTncN;P(v@fa{HdoJkhK2Lt8Agqp}T;MMtl4Gx!q% zBN=G-L?5XE3JmWrkyj{_>(|f{Oh*kackQH(vd_lv#ES53Sw*@wVODT^LMxDrqtKzI zOi%57kQPYhIx^Plh{kP<;uAe@7jO+}4_C1(kMz_I&kU_N1}W+G`o`95p9}LApbT#r zboL2&+Gx2P;YrLR^dKjt)GoN8FjOp;->LC;=cFxu5@>UJ83lm7hfn9<#NDU6&N^{KytfzeR2*0Tn4xtF@sn}GLi^?E^U z17Zzus(wr^8)LzOk?JaxBB&?Ths0-?IZHVua*-*j0-hMBSKEmPeWRl>FS5N|m>6dr z=TmGN#CZ(Nz0y<9e;=mQfOgu>M^-BNcFxJxs)dS?gjK#RTg6ADoiin@ZsUt<_%a(cSrWCh9r zRYC#$1fq}U$j_W!@)PYVKcNEr!14~4A^f~HP=4lk z5ALOq54OwCYd^_P^a=g5Uw%S4l%&dM&&fn!&szA?@O#rR`p7!Gi)aXEtkelI}R6MP3Rr4n*&AAJXIGCjzU~Q%ezcsGhPRgpdB+ZKVYwg zpHxLGhv%2!*(3O38`0~L5@|!j2+8*sHPA7mG*E^^bpc39j7Pqg27}cS^>lx-7y*n| zQL{@cT#W&_*a(^{3brCQ!tvjSa$!b9ad6JzTVuE5LqG1Q2;%_-a2bRMFHOp`!v93> zi(@$u$lnab8TLRCd`mu5cicy98ZD8mGz;Zl5<3q~=uizOqNM1IE6_4H6tRJTuG7%l z8oF6S%QQq*L{2goat1Z@iH4?V=t~WSHAJpM&IdF^<^wcWLqBQg2@UPn&@&n$2O{T- z8X{w&L-O%{J!U7EM;7%$zX?s$b@^QpLZjHA))Ua67%Y3S@f}46d}aG4^rp8Ar0lTm zZfn8rK+!kqjwz%^YoMq_HDqER3zRLyiCi2R(+`OU?43TG94;8W)A%Lb&%OLQ%~w}~ z7jRX|+>`qPB?KNg`FI2xzsc^ldipOePQkN=;xC-z3alA^e2AJb*W{|>;?-KaDGJrKd47<1unfni`cN1q7DAoEOIg) z5QK4X%<&z3=2h9-Y~?N5<}Fd)l5O4AmZ-+|e)f_*>+H|^D{ud8e)}uj?6Sp$5$DE9 zpP0Kh`~_Y|i5!FZa4#QH`{K#{P-=jSE|oo~Hhl7L0iq8m1C!iAQ3&X5c1&~za3-`& zLpd6HUqi$fX`g7QuZF(VP=SWN)6i)e+ODC28v02?=V@rahP)aw+!4@FoI8T0di441 zJu>jtaO@RUlr>jaLzX3m-D$ry!;TBv!iu700Sr33xx)SygU(+BPyTUGATj8yh>L;P zpzV6}oKNRIYv%iigfv(SAP~E*U>XyP{h@E0AqG|=($j?g=g%PM?(z#!l$JI)mZ>-Z z3(M^#NW(~#v|RbMR^!$jBSWn4``9`F6Y%(h3~sxn0`h1Nu0b7xB{{UNOJY>IngjM% zUf8&=^V{!N;I<6BAZRzX9Er8K%OBeA3Y4{2VV=CiL6JUq=^U4D!mQY+N@LSp{zj+N z*MCW%+e+V_wI|gelds#7P>0)7JNFN4SoNX`Ty@qJ@6pN_TZAYXW5xc)y%&l^^Y&jU z-Y=eRGe~}Q^2gK<0~~3C>OIkUuj7-F4qs#Yg(P!np#RGLOS%om(pWAiWjGVzw~>os zXoK?_OgP7LqVQ9<@?3|mTNp~ctQiMz{j2jS*8X*VyQLfo2eeNg8crot+f>u`5k zXzzs+FJ0^g!v0wJ2sXx7v?g>Q-`-_~J_4q@m*iRznpSo%$+jYAO8`Dfc)SELa9bLV zK1$g0CQyRtklhtS7f9xEdmhO^l9cjI<2==SohArw zU6OG|BSD_u^*Jf%?Z3v;<4lizrYAb99vE6{y!}^sdJKg_4*u6s?Sxc5={#CA)EhCAOcWG+)sMD#}Gm>TqoET%NV?+MgD+H~!ks z7ix0ZA9+iD8FU7m@vyppVC}E=d}=LN)qh+6#!$1X+edy^L$@`7vJb15?Ag?Kpr75g zXYGm5VjUlpR=@padC5BGp}79KP?}h;n+VBsz%+3$o(+d)jdrf&2rGtPr>g0rWmTy$ z!Y%O?t+v8PU@YLu2g})qjm*0F;MLz_0WlxU+nc}O=6#qYL%-x(_aA{7$j1Fl6i;?r zXhr_TO(K=j$~IlxCX70%Ctz>%HEx6A z1=$T^uq#0b$Z55F4aXBfifs%k%38`tWa2l+2ROFA&G2N*qe(J!oL(Sb%shQ)_S2Tdu%&i`;_cw+%&0e6Ei<3xxMU5YQ}`Cq1Xh0VS>MJudXD z!S5w{Yu&NbM5OCBRKzlKd`0NV#?aSL!ntm-fN z%6ST%D|)RzR*{Vx*8)YWl48cl9}zwjLXagSQKc5fJ|m2|=UGau^3?1Pv=s6YuRMqr z%4L$V(jUw0ibN>NsVgylv_SxFs592Iz16zKgH% zn{J%?8=d1_pGoPSj9Fx9!_Q^Aq&AN&kwatNFD+9TLd$(+Ef|rQ2e5y-%?Abl!d~bhXfe93JfDq=bTAxSw0|%UIe~f6CE~k= z`!kW910cxE(AEih-myt|G|^a$F@uon%^~N#1~skp#(C#7W+kAo(2Z z7p0Iq3{cZZ%U6;NOPqU95r#Y^sSs%ckziY)CLZq-VJb^K*G3e~TxB2Q7z%mOn$dto zKFn+ecK!n}wOKMoywJ_ScoIhN z1CET6FPhSwvk>7~Av%BBtI%lCExyH)jhjV>-cS<16{0{J0Mzk)paaub2m9D^orahi}Tx|Wd*oJw2kL(#8Y}iCyNKn z%e>d~Wqb}p;1DN}9rGdBGx4tUeRuG{L1v#(eeW8Q9H-3W~ zKJ5tCkLPo_I<*gvan0g=saTSFYH!G~H(>b(S8qHV5#iF$H+?w=B~7)6;dK`XW+Pas zgBU=O5jvQMAibB7As@lfItaT%WULNi@{UZ>L5SY+8f0|iw-&#cp~~yxC6X`>hD;;T0Q4z#~`=khiJ~R3(R&H>*dF>Y6sn zx;v}+f+JWMg7BysWwovxWlfV1;QR!P5a41Bw?Yq;T!5z`toi~GZ}eGWBFAF5mi5Sj z1s>^mY@1`VsM!~4cjG|=OkGK3Mf5lZxv64*}BETKCU zk~6!)wa3mWP>Ywsybmy%QxJVP8;E2?a`4x++Lqt4)waZ1q3@yjL%Qi`XFVVzpJ2zz zmTS;m;7#(NTGx#_j3m{GrR5xd?Mid30*-MX|omqKkp! zG8Y7j2&q_13#o|wMCHOq2tOJakR_8p_W#G+yTC_PoQ?lk5+IT2i3*BJYpC&UQfW&R zTcW7DlE5zAD6N24(b8fmw%)3Vphbypf;sQHKnu27ZL3u){?(Rx!3c;6x8S9UC>Fc{ zR%Mom0WS~%$^ZL2bIx8uu(q|I-N%V0Yf~@V z)Bu}$-KI)x>TR1EWK-|i)DWBc$fkzb)Lxsav?*EIv=_B0UrgoHZw7cpTc}A$n=mf! z3t{5fD7h&lygVb!K@bLMtC`+Mm`pOlj5#bQf&QF^cB-s&H&@}6_|i7a!-gj+Ps9FZ7(MB+Q0vA52sc;>1C4z^fmVDS)gFGM;cGm|gLW0!enJI1INgc4)>K~UYl zhbFwVB~dxFU+4lVx=^QQkkxjCJ*>L7$gUA$uDiFC$`hMPAy;C^1|!{Qyk!ti$%r0c zfcBoTn}X2e43w_B|;aTZPx`X3WMNEdzhV&8?qMh%Bhc?GFvqW_jQiX6*k(Re}?J}(lyk*yCsN!Y2GM$+-X)?V~ zr;)ODfFW6sIg24lImsjFQ6#V}`4B5WKo%M8)?QdQZxcwRjpVfeqk*8dd#@z$t$p>l zursOq1tDI0|&aHA=GhAYy^Np+EYX;WD%^3KAFea?+*ta&w*?2eK;dLqAff-up-UJ+}C(U?~v)+@|wwXBA< zombK<1+cId#rJ%kv9#_B1+hSe-Qj9sEno4h7S;m16mFuhGjj?;TMi3-1ysMS@liS~ z0Em$_yVB;wxP6|H^^^=F>vPy~J$w2u&b~S!)JAl}0w(6wp?JcO6HY8q+em0e-)eVt zRs45C+rWA;1%!B6v#+9XBCkPaS5^F$^|ru73T)>w6#tzNz^eFTo9qjWa26(nnpMT0 z6k;fn=xL3}IwilSV3l#`|C!N5njPl$d8n#5{WxBEDz?6DwI4ar@SX+?sl^&2Et0S*BZFWn<*2 zFjnV-orX>pFz1|$AVc;DiCkcsNkZa5P9Y_MKW>475wr z#dDZkb-a+`#adi_M?JwXPw=ZlPWj>~2)k=A}|-e~Vou zf>b3mO{$VPl5R*-yp@R|Z`Vkvbd{Ri&tla`AwJsVRe5Jtm73yhF;&v{`MfNasyn1K z9pBEchnFUON1iaI9x}R{ifMqfk}QBgi$5KO<`>Cm(0aZ%DhsHXBB^PrDE95O<)svs zi7Ox$%SY+PG?~?yv@q0bVKBdGd+lbbqPMI0(a{g`*6ZbZ$pZ#|83+=lc(2J$Es50V zH}ipj74*OgQ<#F?t&KFWQfU9tpD4LhHD2FZ%jWdxukjj^ULQ18p)Z~8sZ}h6H z^Qzn=m84+T6b(+aqi=YrqkpTErsH$?^+wuXz@EMKoxG{zWd;EH(S86dkg8~6KEKvp zdpn?OW6j zzsjT9CIIsH?NHfz`EH_TuDw&$t|w5DZm_B(u6ExMMe*RM`z$3(RV^t}#$ekC8Ft%Z z3Fq5wuT0x*3#s$$wsDVweFyYH_9=7#wODOmgh@>0RyErGD3V*7QMbu^Z-POP@C;yjSD+P;j0Y;tZ#mfiMI7-*Nh zfXPIDATd&GwhNQJ$WlHPkPu2ERMZVssIuZ3y|6HWK~?yhS$WxrU7Euv!4h2rLPbpU zd??;f$1_ZjOuwpl;u3yB@h4>pxXY^I_tx+bb`8vsOd}Ye>HJ8$D5enVyD$s@BF6db z5S5Hli`XCL#YgXjYblDj<1zVYt8<=NHT=%HN_YHT_o^i!^kY<#5Uf(sdT}(c5{x(|gAH^ViMZGX|i)-sC;2 z0cZw%$bxAq)Bf{G;amgnGrcCNZA2^9pQ|wS9ER2V!Y74&^^HHLmx%S}lft`(+;gq< z=a>>}{yDuQ%l>nENp8i2lD=a9xgu#)`VFQ8wQ`6TM4Au&*V=!M_v}Bbu>Z`_+01=tNf^oH z?(!5XdG*o$$;Cgk2zNdu*$b6~)(2CXc(kOB>diRn=|YhFkM$!lx3F9+iX|*Pkp!Br zbos_+v&w{5>M1Y%sihGLy(T3Vo5}H7^9?{J%JNVH&|)6c0Q6u8sy&}tRw}y>IVh35 zbF;>4%CZ0zsfRHizRL1Vn}OETgmE@9_CYoVh_DkC`h%UQQXO~k%l6&t_TAg|-Fy0Td%gb5y;*+-#Eq2-K$w~6=1osA*_cKcxoj|jeRB4eMIcw!fw1of98q= z2(!^JKhPWYgV-?10ssBacg?Of7hp%4ikxD{%f#R4ItJH_Qae(KP~yk4MV}I#wAK1? z%l+}xINuE1z?ZdFpYnCK$*{{M(>)*9?hwYLZ(5(SaX)L!Yt*eadBprXDs;_TNWEpYjg+lx^Wj$mz6il+4nn#75IgU!U?R`jp41F18JQ z%4LPFN$FE!R-dw522n3UkCiHt+B)fV=&_+T7j;T3XdjDtw5pfkr94{I%W$L| zvGKM5>XevOy$lcXXjL!6*$HD-^)ej2N^F`fJ3bsAUWbTdBEOCNPQmz5bRyr+(zR?f z%T}XnsTwT07L$|!Qo6s1*?3yt($0!vg*Q=ir_(4ml7r76_o($`PFY)OIUG$zn`Y-X zE!C7**__G%5zKW~SGG(9Cye7F|KLtEvOl8su0#htu!}saCYR?dD~crYJh1 z$BRye#g9e@drZhO;6e^JDIc;v124@@6Zq?vyi@mcqwlcr1 z61bHX=)BF?ddWv0BfLBMoy*WaY(xK0C6|X!eZi_820aAi5RH`x4()nQ#O->H=}$bi zm-o<#*JY90VArICQj;o_9~bLPP4%^@k8EmyO$q6xWQk2F1&-VO#I>Y19vfocDFu$l zhS`)7;&`mmrj#CAR|VQrvTV08QW@l&ln`i30O|ugS_?c+FM<9Ty~G~$67PoHv|a*X z>Z|6S6X2y=9`>|2`m(w8;3hZL$p7fe^cOvp<~p%Y zk)Ojh+U#VzD!b}rsI%L7-)~3Owd~&2f%n0T`P0;lc4S<0WBt8$sy~GvF_n z=4I$@1}Wv2VI^|k<_>pRjOga^AxBiKM#$ff%N4_kXwRG|7K0Hsfs{U^)7&UupQYe% zE;^7tW}~l2DVy!hbq>& zIuOpxC7zx|lgU4)^(;@)`f>ZxhrDB16I;HH%CIbEvCS z_QBV&@#e-|ccoJ=_RVnB9B&xP`bS7b5+euu9x#6m-LORCFIX3toe_>=v3F4e^o-2v zk1D87vC|;_i}7&Yt`?faPI?+i%&1FVX0Cd!FPMPUmk6ZXfgLT|5zWPYK=$-gtRWtI zx*QuyGd*82on9_$wp0Vw1@%F7U{$ui%WM%DP+O5!qW&&B%_)2nso3b$pNI2>eAho* zfi{D1IZpla@&RXmTv~>dsqF^a-d3@}su?9={scPKKde+uNhxJ8&D&*eW2Qyu#zk~1 zg5*ZJC+SPPw2*E|*Ldl-z4UZ1E#zC?3q6tVKl0Kydubuz@_wF|79uX`JG``Lf+c;A zmli@U=?A^^05AQhmlk3!@0WOKA?K1_;iZM3OZqu4EyLrH^#5T5J&WUF##C=xv?GM2 ze6dgrjy?E*jt0t+e!=iy?ohGwiFEEZe(PdGmdV92DxpU(@ zR=!S@XxWE}?`*_fCX#qiR||v*C zQ?R7!J9s62XDi+h*9=z-1|yc-ss+i=+&q zoDni7rLYr{eq9Ea_j&S5`fV>==%wHD(tW+OKPd-z>Al|j5-;sf%0XV*pOizqv_C0_ zd1-%AR(ffFQbxVBKPks}X@62qAT6>-{F*G`(3x5Db@mr)P%RE`??)>>VIIC91zFh7 zm=R0l;4O*3-y&r%V4kSnIT#p!oKJl|i9qCsVfy>#NGYBezDWkDIP7`qoK8uhR)UEz zqxlCg8IHZvTn$ANY_wL9AwNRj9MyM({6HV?zvE)1c_lJm^hGcg1Uo=Bj|o+* zc0wYM$b2Tr8$=@4Y%`!5A6J_xxs2UGEWIal{lQ*oO^%;n_QmFHeVIpxC)C@KcUt-rNCd#%gK{)TY4f}aGG%Se4EPS4V zBX;2)Kp2MGJZI*iG_JP0HX|7z?b(GFCo2^);QExyYDEK!quUEIQHupfqdi}*%k_lH z$QH^1Nc(zS$_m2QtLE@FUod~MRf#%K7Z#Ve$l99yGjDB01Fu!Z@6e?cW<`buzE;`i0=T*hI6vR4 zD=OqX8ydKwvQKqhrCZI)TB0ipPp*L*`&^grUdQr!RF{|Y!oWBC)E2t6EU}w)i8;>? z+|Z}G$gNH-GroGY&)B~1Se9D7E;Z+wf$RHJ^>?dSZg=Q%lXw>bLUmrB3kFa>6;cDA zP{w)Iy1#^FX>CX^y^-_#!LIV(R42@t6R#~duf@9lD^qX%V0@*o|pD_ zqdUB`zZ>1-rTyLLK`-s^Mvr=Fe>YmTA}dyJ8E-%^*ey@*S6eG2~_Wu>rD1tCG9MVnys)yE9KGWXfaM5Gvp zG>IH2u4u)0^_I0o1AEljYz59{X{}27$@4$kROP-@))8viV;#_5sVx8C%oA&Ra%fNw zG)Q@9*Gs~0RStZ0;41M#dqup^c8C|+l3g2GJ~>uI;JemU9*06K`I!1x)X_cm;`dYQ zyuW$#QP#PL9_L737O)5`;X$G=d=|Vkw8-~u*bHCIowt^CGr1?gw@paN-Ng^>M%IP+ zpAp0JXVe8HTDB+7;#ReUcQbb3b|R{gx!_uhQfVLFQlQ6?_50g zpEnUHjaOKyc!d>z%P0^(VV}uRM`54GC>Wc;Vib%` zkv^#)gTW{m+ka6I6!=U=LDhiJ&SvK7(O}*>s&xX6byWKYPye!`+VWs>w{jc!M~R=% zm*HT%O;em%7^~+68>5x4kWmXNXJM}Tv233{BjFF7@)up*VC?oNC>t$)Fy2OryN|z- z&SHLKZlu?f?#AIKhb9G`AISj7s#q`ZFzqrtelX18t+@Qya^mx2^PHK_u@n(r`5DP2 z-l?gys{A$KYm+}=&z8PZrQi1qhT(>bY>(~X((iHio$bD#FA4zS!09mzEu<&Q&h7j5 z%tWBJ3ayam+jBWdyRrM;K$l8RZ@%CY{DbiJ>BD$sdHZbV=!wySo)I|dP76GIMsh8A zc={ZYe1laHPSkuUC%IT9TRG>Hzb2yO?Z{CA*NGgZcaIwI@iaR?`P1cV%Xh*`x8{{d zizerx?VVg(mFW5S$zoAkwO+m~0{!PNPuYiN)c4ov|D?VJ4|?@&8Pc`Bq#Rb}bo1xM zV~N-h{kSM0sIm&R4pa9e^J3D(yy}XNrjAg*lRci*TY7&ICzB~sj^8`^wI?u%1r+#) z`9qKh`*>0Y-ielVL@HKY^`i7J^WrzPE1#TkAIoRKvwcY#o^M%r=199n^7$?9+WxU$ zZ2MOnp#3Rc`*-r2-TyQG_5O2_lw6$47`S`PzQs~wt2u(2s~X-0t+fXq-#f<<;~%sT zSO3rq(l(J$tT5kgPH9esH31=isoKE=Q(8Ukkn{Dn7>v5>mTpF1d*KEgpq={PkRMJ|mJH%9w21pr#9gOUsO=z?_lOtPH2M-L+h~Hc4}qd! zyZH!U86e;$`W=6|+~)AE8bdKPgjVtzbEF|9k-!@wdCeC#?m`$v zjuKKMf?m_Ul!;Wa2PSVL62_}y0_)Hw=wGHiMs|Gc(7FG;{*DG5zrT6u{vJhks=tFI zKhf{x(>_;!FFP))zn!vh|L^p7BH;M_?aPGp#aX*k z^*1${37gK$m@l&!84lY#@(|s{otYtK3#*qsp(M)u=VC*Z@JDD_|AI1d#cBGL-GT&{It{(jTQ-z3Nmxa&_bA)Ov>KJpsvO;3Ow3w^!)qYA1(ZIIqzY)PtYmNk3B`8$!RL<`rd+=Wb!%y0^+IdEJ;JR=b(z7-AkDM+hQ`qgD9uA0M8~>FG zZwyJ=Xcn`;d|+p%X~R8_>$p603gbesn5fE!tMPbY`v*55sxOdkHP79Xg4ERMTEzyV z>k>l<);7zx-$}2p{}%oY`1HH9MAsSQZk2fv??UkZYQ;at|IWKpz4GvXkJRI%`HRH= zsTsgJKCmlHi2~d2>j3+i_>ZO`HRAOn6Z!u&{->~}ef;bCb`}5MeN6HH{h|LH|5yL9 zEB;G_PW(6UznDsWU}y8pnvl)+o<{}Peh+>7pWy$wyHb#vI{Ezb~Wy!Ft{j{|05Pv^)>Tj1KY?kdTTKYoCc60Y5nkO4-ldNU(izWYA@|Wfm>r2V( zZ?2&QVOzb!B=>WDD@BY;VPjvC-L{xrS5A2S*|<}?E(&tlW~bR*NSmEbTj?#xiA{hW zNteQ1X@bYMWbC(JJU%wEh`W`Lecrd@LqE8y^=#+q3X7|KxuSA5-iurTDmn zw*JrH;{{frkB``2Q~0=57N(Dn2guLH$9Zf$S@^gWrJTo%eXjX2exR-q#m5BN`Zw|M zh4Y`ytZ}-n{AbOA6gpg4`s6GBd57dD`rUg{s>^KJ2joA0pUt0KPEF~~{y*nG*Rb^c z{?`8`)!*BcQh5D+Q1TP~9y{@K_4m(qWPN^n1~vU3>hC6&w%^}*e@^xHex(Fnf0syp zqTkB$&(&XvF`99{m`zRpa({*E;qoFecKwKh;W{}O3WZ#623vRs2wPU7@an!MIQ(&oH)7diNYLH`!rV!Yh}cZ&Ak6D)w_^h z0sbk`QOtPi*87t;A~1#%6IseiN33{n)u9xmpllZ=_>*4O~RbwuW!RAsK}X>L?=~s>YoG-XV&W^BJtl_e72jDg^W}zujwC& zFI8j~T4esd31pV8CV1$iy^9XEdH*YUL&yVyP}3n~dfjmvW>PCG>=a5Y3ekApE!=0V{<%1xD`EW4j~Re5jT}a`=QzsQ@FPSHGRbtF4Tyc zGef?lL!5jb`JH#ZNWt?xufgAPZ@Bd2OfS8Nl_dZWCc%l-DhxYY03j3~o8uNK2s>MV zAmlub{Ts%3gmYciBepqEBZjH~)L2-=9n{h<+xT~BT;i8tXZ|LSf`f6i5urX^mB_Bg z<`V{%ug4ZPjxGe9GWEnb&wQPN&cgA1ro9!6-kt*$aLsl&WWHe4JR6CgD!y-hTgG-G}eYxnff^V4${TWZO zY51B4^Of2Fl5^6LNxzqAZ13<6qYQy5&ee%)_LSfQH0js+IC++-LMO01ygO+e1FIh-CK_ETDo=Tw7*YIkQTsJVYeq*~dyNlU@!_`Y>Gf zN+egClLdQu1}t%1@!`ak9pS|EqRzVBf!dMsv`?N+lc!JR=_GmDD^F$ev`3zfm8aeE zgbP8m=o4pQMdI8*0q<_o+L4lnCXQ%BvRallhoeVo4 z!|v^OQm#7wC!Z924Jrd&b?Q&oUM-bs7G29Tv~~8QEd2_!npo~?c^RN@YB|L?vO^!+ zR~@&#Gr3R3R?h+9NyLH7xL=vDTT*d);3~`BH8Y5yL5;Id;4^5&i9qQQ09L;@Cgx}= z-fzWUiZmPxRTL|)%c93t)oI{FCQm2=ZD&H=1TY7^0l#dJKPsz%W!=dmS6Ef z#GQUHrlgU;ItYHUH-$u>IG@i%pZL7|QVo;=e|Bp5DFxgYsANlr`wEp*$16|HsUUJw z-eBxe18b-!If61W2VP@&d)Tsru?%fZsOc9VE%_o)$GP6((mXsjxf3}^2-dNCliw8@ z`MBgmSl;7;(x6<5Ja%958}eeIyg&!>I{93RJhn4=u+UBxFC)awG8^P|A!NAY5g#1E7GUoX#<{r^+8-)CiSHfHdj zFwbn1b;2f@zHeTLMZ?-_ejKlpStv8&CVusf-goukZKpoLgV2J9?v)bU5-kfe>~7HT zCGR`+RU}O?D3{LacOva2ljZ6y--cGY``m+s!E6BCE!j zWsxX$Y4xa`v3GmMRvm6;{6^uMbszcO?cBWPN_h(nLRvEnDkCy0#I+bvbecO(6PRjM zBph3rZ{E9yPh%_c@v7|4p+kCr|2;8SI-Q2qRBQT-&<{pZF_K^N9+QZwyeqal&4lqi z1SIpa=C^wJ@0%fq6yosdt|zGEp&Hj}i)lHyFlUagS8st+z3g>9U(gjny3S0zN|9K< znC-;#Gw83CWEt?HSn@h80R+rKRNFFeGx@0PIiVkZyb$vML{A1q{AE!=4M_FmSLgO1 z7Fz%04|u`7x%6qx-GbiQN@%3+s;^DEL9&yeTRa3Oz2r4&elynADW7KaEm@#2*GWI+ z!v*$3?<;$!_yAhv6RE$5VuX)Mb6Ux#mH1WS-ja$pV`npZCM2V(<}g16N_bJ?fb+;l)~{Im2r6OOpP!r0(+uL7=! zkfy1}6lYbUooJ2u3}mVjZ{5Tf3&ED=Eg)v?m$;9)Ij*jQvh7Y~Ft}wxN~ufFPe><6 z@So1BP}3XIiNwJ-{~6v6ZZT)6{AYQ)o8DC3ZVAID_zqd>A!;S%uRHGY`0E+eZTahp zMP2yoCWqQ8%M575*{nxVoiNb>Pmyv?E zVJ%zc20wDk-3+DzX2N)=}u(6d)n^y+)g_87s50;XRgkmHTJGf(7*r zUGp;j?9jqz%O{gr<00mNTVxA0k#GBB`JefzG?mu;#RHW(mF^6cuknY$=j5tL`C5_rY-AL;7Yg-%kBxaLz7V*cbjgc^(N}H@5wuv^PIcd*1vWwWrU|t34hr;>tf| za}aq$JO-j&8HktLW=aQAd-p{pvU#_yqFv3kJNHE;x^=fbK*O3H2qmgJtJyh)18AG$ z`>(!|I@0e|A}CwOdNc9&EV+1HfBFqI6zA^x>sX=jCYeH-r%(mOaR?g9=kU{{W%fP%J6%SH#OKPq6^c_Njj5{{ zyG9U-paoBuE3-X3iN!1%^6ht#kVPy;&2~?o)~5HZG_0XqtA5XewsDrWLCGkdr&5bV zD-&NSf>qKOR1>Iy$W-5idf=IwY1=`GuxKr?S}*G z0=AeUT8~zI3@)99A=3J!I+>>^xAG$uE1esq9w|5f4qZuoypl=R#@d?!U=*C>IL zrr?gdIr6OYUF8Xj1u0ZiJ*hK%D<=FVCdCCG_-w&>?lM2xYO#Wn1uKfhGKSLF&-`+` z#CS_s7#H-(n}G^O7P3U|=k9VEW>JSC>t1Rx9s9IqK~~L3wh!r4lvz+jSy}e;^K{wQ zoZ!71m8ki;w(x_Vg~AXVuIS44A=2Y~yLlt85LP2&zt*DN@GA<9%t!OvT?)-DKvVl- zc8j~rmpo9KJf}sSt7j%EOY^<^gEXul9D>%jg>ITr8TH*@2b*Sck|SBdljqd0bs9D* zHn!Cq5?2R%;e5yPQUzP;VEb)QPxq3W;rTtifgpH0>nj{*l&W%)eU;1wg$=OiBe)6k zlG$l4&h@C~G^hk4r|%1>`vUtMb6l$YCqNy1%mLyP9*|jPO8thD;YkD@gQ9LVdB)DJ z2~?h5bJFSeUd|oO$8-MI{|(*KPDfV;|HW$+@8RuqMH<40XOGB+KWJU2~ow zZ4ZmcM#drGoJG;zadmpZgf4YEX8U$2EyPww|A;$6-OyPUa>;H9phkf`~mDNN#F=-`oE{^E>|9e;wcJ=Xvn0 zFx%`>(x1%DPG8(5z2R5c z?;~B(Py90beOZ_EZF92U7j#KqGdufza#nWwye{ddU+tF#e?^z{{Ts61AJrx8uFrn| z$=|cn7k5c-cqRLNq)YmVb=mLBx}0LGbB=mI3uT*bXD9_XFTIW=4eo3~(fhAvk8oStTnY+IH zVP|^9VYDSyT7hk1s8uxeKH;%TQ?Eadp%%`OV!h4QS|O0E{iU}GR+=q#!HS*AUdd(F z_pcJ4L`=fOMoZw^Y7P~6-~sltcocK2`M&*ysv!l1X0xr8rFEY+Mf~QskX;@0KOc6c zRejm`kGMNi!b~~&un}Verhh?cT8G5if=X8~5pBEDo@Zc1!ewum(`Zvvw8EL}n4=su z_t%+T3JNM($v+Bc)LIT^MGZgo$N}qu`R6b(|1>up_F*SDkXj;vH%*7o3%M&~DINxYzbH5J7EQhVKbdRF z@%(9S8p3ONrb(G>vuAsgO-#~;b(wBG(%_k^^dbefU7e|OpKCT;kbz|0W zOp1E;>K9u3aB=z1_i1$+tLY~ZC(f7etS#{yJf=*zE8QJfv17e%e$9jtL-w+ca0N`( zRZk1B{grFZ;IM=*Vn4XJ3w_?ug+52Rq@NJ_oIIRWZ~*&!tf z#6%}1QPlk~>r|SqPhFoj%8@(pk5K1t1Y+OgU^|EWt2RnE_xCtRpO4V5c#}zwNiV1H zyWXq;9*bDBQrFs(w)%}M#sTJ6WPuf#+5@5x7RAj6s(#pF-nm8%Kh&7wHVO(9`x#Tn ze95>UhW1m9ua-Tjzd1`G*eK=|!>L6mUwUNB_PD^uIiuC|lr|vexYajHsN#G9Ymm^p z6juULAe$2Kfr{P-!|M=r#V$2~- z{v7;1oSD0r-Qs~Xlql#WQHdovSi?_xW@PmBfa44OgN)GiD18+VsiJ6nz6^xf{=Z)T zSDBs^QJOFF9Gb{k4#~-u6g8}qu$%}Ghm@GzyA=&mo7pGJ-6x3K*?&_BPE&HIQ>$s` zrmN|QI(TQie^R?g2g3vZMj#F1k6<}H%(I*xW{sxRe45?lC>j6pO#q#FB2#(+6jO8^ zv+Dzr^s_qtxc0Be@81e@JVm5yiN4#Y18N0XQ#;>Ew*)`&Pt@F6Cct2GbVmQa%x7&e zznz@@+PP2LneQqdnPf{@cHW$h+G!+JV=<05dfV;)e7^qP)+F(4zuR;4(=Bupl ze>Pul*pr^GTE6@Fs#dYx(8txLC=G(iqwO@U6he7{On^6ZfeEicqFLyV+N=tub*&-H zlf~rU0;GmgWymUpdyr3_l<&KPi?#%}Qs$b>HYR+&HX7)A+iyh`7K(uAQpQilHWp4_5x*N z9X*H%C9u|fi}tu#+f@OpG?ky?<3bmBa%H}{ChM!(zp>?gtN+f~y3{`ia@Gz4$5k#LbsNJt@?S zLcO~d8j)v9h4Z9X0mTlYSfBlh5#U!U3u|o$Q|u6mIr|kW^okWqZHH3qFp3?%U$G*u zSdkR#N3kO)cBEH~caq(gU-}}A_LcNe6gxV*NPoUMCS6RDU!v5Px$q7|6kvyV{Qzg- z)yEcm((-Qqf*o#nfSMIB>9MM~7Q~GLaaZQr;!=b!PAT|AN)}T9q>Tb;SN6^-aBZF~ zQ9=puH41!P*(bY1zAaJ88&Easkd}89o*kqMorT|X3U;)-)xY3HH$12{cm=>%O95*K zVeQ+}=0LIvOf)`YS|~p93e0TIS0CYrdx{O&8CM@ZCwU)_@F|il@%3v;5~I1`euYG8 zuk1~9!MeZ@)q-T1)G(-9e{*ZywU>_~pfL?e4P#6NA2R zL-TS>*UoTe-b1NKVq~%Ee}-#2VTlBVKXIPgv9xUJ1=EdGnYCg*IdNwvQ7@3Ogjz=y z^C{6Ui7`8}Bp^W&sqpG^SvyO~FXDvID}0(hIU`qv5@UKoc-Nq8n)(N+nilZ7Bt!&( zps0NnwG)8O+)4x0fsdkrkE`6vi!o)Yxl5{@dOwGuLiD*B$a+6%L?rQp!Ha^lwR3p@ zdgL_J&}AFq;#&KJfrf-+$qI4dH2e*HJhw1A4RVnN7cdiMnFj#U%CM=bR?KWP0l*3; zs*Au>FkG?0`Sr3eTJ^cj1rt#9$+{NUCk##C!RYP!@*-8>TmIL3&^dA zbsW?c^>Ys*_mo&ipT@BVp}Y2T`;dDorZ$aZ`#AL{`?-bW4vTdh+&H$-sn@v9 zf`^02JuTMZG>*lL{BNj46%U657dpH+y>aXzf@ilSM5Mg-K&Y&_tTmJvy}e~?p2o{q z8)|tgFV=a;)e|F$=?;<5@(Mq6F7F)6#j(g zPM(L|K<3TqPW?!7+TOPDO}xw1oqCCC+xBKe?f&k>-rCdu!b^sO$$+Gkikew9AgQW+{(>LXbrJ9pGUY=MQImu(>iHV<+JXD^T z8ac_{@>D2K62N(BA9?yvo(__yq&yYK(?)s9m#1~|1Uxy(XXUAvJV_XtrED`f$;Ww; zQ*B0n$Hev>KlYqx{3p|#oBp7t2tAvA>EuW#JR&#l2~R3q5Du*F+~i>@aV95hXX+2* zXBRa*UGx3e?tF;=T2JLp?6>rzyjjD|#RC|n=zW!t-kO7*$A<(abMc)ZR71{jOI_c9 zV7N*8DKcm8JRaM9uv7n4;5fg$S#l-7+X{+Eb*ZB4mkLLpsT(9#j=a~GZ42jk@U@8A z=x(5MUx_5{@ZeiOwdKvhovVn47q7~3a}_|+3SqP-&Mt+y3gNqf8XzR6u`pL!X!cvM zw)0>xw!6^Li=mx`)d6Q=6`aV}+?LJxEt`sjIap10PQmJeH6b?Q68Uc$IdCLZa3o`U zXBW)#3zka3=@f)9se&;X+b6qVzF%;V#3-su0VRg9-uQ?SWBmj=8foRqC`!nmB1bY7 z*fbWMTosk^yd>kfIpbL{E7MQDUCpnE2;~{Qi~h+o79skV{Fc}SY5QO0$^7xFd7J?j ztl{MohXN3imf1HPEP@_0wMLB8t6+o?vF>J$hnf!85(i&OiA4|b$Z}WJgqr4ziw0@32~7cASRZK)Z7}EX>#S z0X|2(;$r*qC(m(i6#pf67s1PM7HPqP4;A6TITal^i}Vp^k>v<}lf5VtR14T#KIDnI z#Mq4|D$AG3cH?()1`WD@w^gmus`ARECcICis+C+^pFD;#X4UaBwoNj&i$3LRTz4Ls zaWMAkzr^SQ{|k2o7jH~+8m8*lN(3@2oPJ4(MH~z>$M&HGI<|YDk&qQ)|Gfr;)2pgR(6BD*u)DKbU1N-UhIARTyR7gzBl>06n|W^ zd&J(y%|-lBhVM(N=fc86r4FH8QUhKt5cjvGnt*&R!Lt&PJhy6Z@*i4@71Z)C^Pw@`4hu692_CZ`PZMulMnsM3>LeB`9{-s-Hn?tojJTpEpra zIR1N?h+&uLCyC*R%_~(28m(y2*^YCBVDN@L%@m5bovkB^dEjZCGxHL~?TBKzw*>xv z2hwiK*CtN>>&*_~1pg$11P5;Q8ejUV9DGHUU=9P?5LHnDyV*jS#3ZlaC&%-_*kYcS zGI1x;I#WoAY+Vue_Y3$D8^xqF9UsC0!dFYf=I=0z{zsY+w-0IMX2FT1wuE=#)^PFw zfQr54gaZRg%oXx3Q5D3M1}(NW8g4~)9n^MK;OQl;$|Vh`n8C_ma-{LFdj%rwcgH@GF6#V#~Or?W5#hnPk@PK)y~5@3A0DjwnT7gZdaJ?u0JeXukSh zd#BF4lDEigo<* z&Bwo97xGXU*Fp@wL}1pYIB+@*gkJEz z=X0slpXY)rr#>dDH8HkG$2ELv-;&z#p{Jy!Q2e?gf|6aR*K6ZPkBSI??RG(4Ou8`5`61Y-oe)Q&zyJ=-z`D@Ms9za;B{uWOmRVos zGOEdH_sRFgNr+coW2xGsZgcG)1R1w1s~otyaZJgv@kaz#v}X zOitbO5*+6R+M1y_LMmfnC#%*Gaq~(d@gP^|Q9?Htk@Lg{l~k2?CdCs@^-J+8h?LW? zk~Fs4%~Y$+a=*wcc5yzy8@m|q;b~PRZF(b<{6s6M;~U!_?cT{x%!CS+J!1!|kbdbv zC57fqo@1$OVzG=Y6f2=+mzj6)lus^YxAtg*nw{r(5R}o35O8;^kcW1YZ`wPP7gHVm zvGoaBPYz|aJC6!&yO;4b_sGXl-P>l>d}+72k`mFtVi}A|w zfnlKwNvJ&%5n%0MGQ&IpQRqShZ$W<%$tRS^SdHn)kRG^<#o^SyC7(=+t>7nu?U)zL zQZ}M|sV&w~bp44E9{tR%a0kOn;A`T;OWonq@;^lwXaBjS5 z`(K?OJ2|8_{E%54!YkitXtYmoZIgMD`mekvf^$vz+DPml9cRUd9CkL>=TKRGb;YY! zwpRyUj0V=W-7rUG&cZb!U=1LS<-9U3`@C|994_2k-g8VD!7*iA_A%uwJ*K$B^C-dj zWCZ7vaoOjSv-Eu84(I4}7J}0e$e71DStppY3bm2ph*8f%ygUN&^0>pZOBC4>MU+6Y zJOat`xFc-|IaHn1w_vrLuhzK335ReNLgf)hXS_v(JnooO2~uYvP#*DRa*xe!Wq@sE zfJeQP4>0GDQXj@(A#XLXd*2IGHGbEwQwEKE!l@d#!tdo(x!>KJypdVWJ?ZkI2QOd@ zzt>|jZ}ufGl=+^r$3cHuwm4hgdDQ05&=17+^{PGLoZ!NIWqY1AgOF{OuWe|){$OOD z=B&4ObuMBMbKEuOTY2*$mLXDM5_Y|0TOhqTg*nn%r!$hTq>5)HOGL5lrtaNcx@60}>n%dq9n}h3i2Y3+X2TA$$oPu=X!z?@tsg(P|z_ zHm|XeGXDdRp31K~Q@~2hH_WmbyF}@yb}zl;Q`rvWPZVLP1kMaAIJt;nVDZ!&)%GL( z?sIq{3{FK0MCiTIBz~3#J(LE09N7x`3iC6`1+G#xXHgRtOi~46&n)$z47ksd@1SM- znbL@g)~^2pkH>$_K6Cz0wUer!oX)d1D8HO+2ZgEG-JqDzD>@(<`pL`X{lmkI``pG}8OMz!zk#E5Jf2N-tOmqK^ellOav--)?1Y($W33yIi zIp03>PtB~%&t;#Pv0i(p{DFw6K<94toPpAAH~Cl~Gjz{;2I7?^VKEE(fvniU@^qm* z5x!bpaO6S@vdX#fQFPjB`7vQ&sL ze`k2ddK=Jcb+iH;=;EDH1Hbnua};L`SgDLN>|_`m&645ZHh9#iFmxYB&z2XTeD zTykaoc_YR|&~f5WVc|Pn-~*jQyP{L*-5-_T(fA-4#+v9evruRb(njXj(QA=2A?H0+ zAbLsHK0XH8w$K1h!DwrWJJ)sFq9-qvQyFdvcKnDMThWsCnRrq#%U@9JI|&1(5*E${ z{@ABSE&U{*l>SiZXQ4a~(*@3^M*Lf{efuFjRJCWtz9s%q=HQ`o#eP!^-T!0%38!9; z@dC}PiQddwY3`QQWo?L>Bv*!Qe;B-sYiZ1E< zf1LgPs4i*uqKx;lo@5n8+`U#3&?MuJU_-+ELX%3(K??1yb-IvNAwQ`(RRm2h2@Me+ z6L0(nBa4#pAKLknjQ@U=J~jSw5keVNpl>R{I`xY@|It{3Vkzt{~DJMk{RfS#AjPI!Aa*OU+O;M@lc_1gTa(jzk{I^5F0L35Fxm?duw)Z zbz+uwRd80Fm?>Qq8)HEu03#bRML?MR3pHfKAG7=>2<|XHr_QiT$ck0Ma)LGa6F#&5 z>$2(}sgq>lx_pyw)7o0%x+2r@nxzUUKD7J#4?R%*P5OPh{`r!QAFeb8TTt7pb6{KM ziljRnKZntnD~?e-G9YR!$|K{bp#yj<<+0QjVCu~kUw3kufOCi1#~_bE`^Z)~H*6nA z^Elc*j^}Z_eVoYSMEf{}$0_#l3LdYpkJEUZCXb*Ihh?P1X?l{ezjw8FZ1nbb02ot3 z)6tUg&di6XNBD5e(k~Id-16gq%lgrCGE`voM5Rxc2t}AaL7#`n^BnSZKbOSayioeE z(%kAlwweTwP>LbUA?2m36A6o6R%UhLCK+P8t-;R_Qz1RQMV1HOXomenxiD>ew6vG8 zTXoB|2c4VrYH*hJ_*CJ~<32W8W__6b0ofN|NuOR|VX|Pg@!0vACyVq}vbC$L%tJO; z{44+HKdvypkw>}>y98Q=s*LtJE{m9WS@k7#G!b=07!HFaJ$JX7(Ua4Cy-3<%e5dKG z%n*)2Sd-_nggyH48ROmU`AZxWyz%Dz<&Sr6LXow0*?$AXg<}D=t@_i2x zE6qLrW2?DM9zj1##R}CKe6Rc7kRM>IN3YiYYdaT7JO6B~i=CS$fC@o14i{il{<6mU z<8T?=+4cj+biYdavE_nv2N(0~4epxrQr%nWKdvx~m8&n2& ztC`lC?$^yyJ>%Nl2`>3F9oNcC{@J?^#5043dS>|UGiF8Rwed`(Nmt}WD&C)ZRkV!b z^d-W}eCqF4bZ<397{5a4>Rz6;d#z@N|G2`u%cI9?a62Ds5&g)`C3RpEqbmkY)@*g) zWAlwipp>o&pCA(ePq6-1{XsfY+I5m<(j(8mD1$|7lnrpG=Rh;2Bxt_MuGi4a^-Ler zVot=VdPUI3T14Zrha5R;T+TJ9LTtuM;xc&}t@J4lSMHx5Hg-Kf;H4lZh^*toWv1y| z#X*QO!{6+p6^D(tG*>o0(6r7Lk#+qHkCk{qpcrXZ#~nRZ$P5_ItgaLAWP$5BLy(^z zxnYIiD~e}|*>({_k0+9xAci6^x~SxG4mNV=Xp%2q>ImKNwmgJh+PiB_=qtIQ0$gq& z9950SISs`!x4WYOpO4=A>z{21Bn!O{J2M+~{d1mJCn)5o^ig`Ox_c62G>+5xGf1BA zu_Hk<>Iz zVwN>gPX3V2WSvTUucX1wO%rwP%S7=DXRZAM+~=Stx1n+l_^AN?z*uiGw3=prk*_lA zY_1$DpYb18ny2JZh>bVIGVnoq=}~o^4Cf{Wb!=Qb}IAMiykd8A|~a;xicQ_Rtd0nq$t? ztRrU}e14_7Nem#Y9cSVfMdsUlmCmgbG=~$v$T!E5-}WS2dwM2hxn64YMJD8S^Vk?B zc>K;fT2dCS9d%R9spfjSYN>wGG;j>q^~rt6dWY=dC=dzyvI97l};JQyEJEz0yJ z;xa>I@!{-cW#?Hnn?K(Nzz=5OudDp)NkOG0J{mSsR)uquY=b*ndOHm_YY#rgsg@Ij z`;1&t2Re72WZn73^^i_%F*DDx>8qu*Mt2+|PYv5D6F(!^@kkOBi=tC6GS>>}i1(Xx znM0mB;kjsrb{nixSk1#bq7`}yKuKFCwI{CH9!Z?b{!dY2Q*SX};|@XDKGFTLw#ZTG zE82x&J3ago&vVhoBvFb9+|QGcI(F(3L}|9qmP2nf*!)#r!kwd>Q(b#A zclv42AWa>ntUjTeAhYe}o}c%!%T)W&$$cuSU23SIt7BLTalSVjzBZTLZkWS7i7lvpkNffHsrpcvod>rjL#0uWaq8$Ws9Y$L@j3wMhP2% zUFLT$w1ZT=o11m;rd-SlL1DHqn>Sz43xG%|h(duO?Pz2xzl6Sakp=B;Pii;kK4H;5Lkstta)}H*(ZRgY z7am{?<(Vu+$z!NoD%tkeqYcf{YjVll3m`P z_eZ|}f9W3xJAD6bFzK;j-4yn@}2TPW<(k!J6~*kjEB!sNJNO*`aKV* z73OuxWsB=ZwsRN6Sjcy`!njm?j4b+_c1socj54pXhUG6PRjrmIDP#`TLS!BL$GfNo zGG3{_R{+phesTgkLIH*e74lLh`K)u!8@^$YxcGCj^5b1R-phK@Qd;6&>$Borr1gDl;#0n>omBnFFrIaOw3_c$+kUY=yVairFb8L(GV~|kl#hL0NYq+i zl>TJZ=rn}CfiO=)Ng21ggtX)6DSohgobf&(R&xaiUFh_1%Z1PS6;P28u!ITHpZz2-V5fy z8E69{g1-mhFJ@j(*L;n7%vxIW6raBV)AD)~^EP$V@%WbWwOFgUieL3HM#r94vs7vb zdauT3yvnV)J1hn=?dD9Wlu|#{QZRR0jDx~`>3SNG#P=TUlhfu3{T-7b?lb!zL zd)euWGt&z0@{Ik}-4%9U30Lf{`I6wIgB{b1UxoP=^Hzr_-}cM*9hc6aO=1+{+i4)%WS5n7mck*9I4dz2jN_nms5o)U8m)-pvt8 zl>e-KaR?-XtPd~j9xB+ogg z)$w1=k+F_o@Udw%POPIe_*hQUon(fcN;~bdBt;eU1@BM+EgT3hM zil_2zZL6*RCoPOmjkTvw^W>fE3tjbTVt0@ZL8NjpHk0%$Og{;1jUzqSTFvitu`&fD ze*yVw&J|9C^DL}Y#EV!&x8yHq&fu_?rpLO2uhIxt5_Ra_u7Y`G%oyeaUqx6fB1(;L zb&9mVeMAapJryq4iWTN)fmVpJLIp!!jG9KHTx~Uf{xJYCBf8zf?^ArLE=8;=EfPD- zGqh3}FO>${Stk6#F+3(sC#K~wNH*%#%a_=iGl?t%)x|#K-{1$Xvh!2;Zi#;d1U^5o zqYCs}exR2E=J5kZ0b6(c0E6T+1S5W)ry(pnhG18O-gIFIW_63Fe>wiuX~N|rREL(Wnx_Aua4O8J8U0;)B7DVP4s`6fO62(Fni{T5uQz06<` z4w0|-XAu4){cc1+yqD$cgLsWy$}$&cA&j2)Cy3ap3!r ziGMX5gn0hnKloSTU&(jYzTyoY!->(dn(0>Bz~bbKncf)&7OMr;{wZD{rR2{^EgTcu z*Q4g**uLDFVGTP~Us%&eKSE){x-eHsOZMidTUoJ~MsTdO1+-cz1@<6a`Q^Us`eobvf7nOycQX z+nD(Y@D}_&qdn5sWWq1$%SE)w(8#BYGHMW6jM_WFLDo6GfnZ9 zsVT&Rt%z{!hw5EO?*wXk%VkVhX%b31KMw)Fb9v9ZW{Y>zE*?>J-LU*3&2C>k*_lyT zLMC!iTuLRWPo#@&x*b7==8~Slv&kPX0kq#;6a--5hnv0^&;~}+08>mG@T&S3YyR`O zS~Hbs<>o?ahGs66mds!8NBE%F6W%d}Jxj~D{=jLt6Cnd$OqccnDt@a9Ti(epSZRjx zId0oW#XiM@XF6qK+wkDIw9qvz2JfA!KJYn-#m(SDV)68pPN7JO3En(I_?W(o$BJy3 z)$+s56gIWSriyK9y-k(c)Fzu6Y*WUjhT7D2n+n=ghfRfTDhDWNVYE%<+thfQDk2q+ zO(fyQ`txjte%Bt9gX)%*LX56wZ~SGLzB^8kiHvAhc+xtP%SS4E+hT6TNHY1V3Sq#& zR`EQ2t0NM}y)fbyVpiImkJCK210@Rcq5+e^mJ$OG9?1#1{x|D^HjsK(i`#t&6>LY$Uc1+1zEhu*QjTMdi)WinnSGmm0DS z^Z^y+6S26>&!{pASrV)C`s;;xuHXuWGlNlQ%9~Gj*pxS)?y)IvK0Rnt-h6u0rtExL zLc*I*<}8^S+JWnImJli%wrgv+Og1U=36Ld4E-U;S*bgTf>X-@0^B9CPJE|+TTvZlz zH%ahDZxD`V5GL)(7=-8f+OAt}lCk&~hiBPGAS@A$(;$k}jd=7Km-g&5IaY=n^A-wy zAOZM`qh-4}i!f-X<(LzJ+GF5bF>=U8`@0nTzmE2wSEoAAiw=AzG5utJ*1T)_-YfF( z+ADAkkX0ndGrLOc=ADu;2=@be-lD%CCmPsij;7kS)zQSD(&P_yjmu!A*V8ea<5KJC z8xY58_ub@te3R_>5Z?VV64*`Z*z9C%WWvitAbNq>hWU4LiU4EZGig{08>8+7IS=U2 z>dG}MD5%ZIKv)>pni)|UCr&pyf>CUiI6HB71*@A%(9aI7b~l`r$SX2cKb6mUACJrO z&>~Uy)o{yOy%IxS9F@pBrDDffiD8Gu<1h32>Reps!!29CX~tv`oiV&htWKchhYCEhQ!Ac* zwgWk*2w8pkJZ$-gX4ki*YN6-m!6`j`pJU}uvhn?IoY%ACRVR@CfLfK`hiKJ1ua6^J z55A<$#gfnZW*iS7zyC?1XXbG|EMIpyu76SSs{bAN{d`uufB2oQtDpJPYJPdL?H6>b zTlxLwo3&RN$MehOmYFuxpvAsmfHk!fE0$E%n&D$pm2$)Z-GN0(`Mye$Fg#ucl-!1!k zgF@nWvCKfFNG*Adf^3MoeT$SqEOyVj!w)&jWs$F&jj}Q;_C%bK8zU7P|KvNgVuJMnpIV+x0D3I@YjjtxUgltcJ9e8j#OI%FWwSPsUPg)kw%w^Y5u7%KM0u|n6plGHErh<%a0&%I@j z%;^K(=YHnhI+wM!Bcuu-D(#A??&P^yHkRn8<>V|=mIcG=ab|8{fwC%Dn_-vxkwz(= zxijd+Uimp9fMu{2$}as&&489E_|;0lcs&c1962(DA@r-?4QZy zKA+m-0dZANL50zSh2Vop4EDB~r5I4z`(-E;(0=S+=wi;Y$!j>nXg|h4K~H2ihN7dX0JpOp4) zG(Wf5!fK9?)lYq}KpV|@4n3qFV0Bqr11 zi7(UR-z8&{1jw2}-W+H(_uEHdD1Prht}<8o3wWhzlw6@_m`y6QLespis8@?BHd$x{ zdcbD(;=fpX$?lkqeML$;Rp533@&Svg@Gsv1Y{ zjkvobEn5pivA50`N%o=S!3IcPuh^C|GPCy~QXN(iYMj;?OXecMLe!ia;kV)G8SbiH zIm^qN+d7dOP}H0hM$p*OewcnmtA(+5&*0;|a!8dZRzu1|jaPh14l;vPp;f`o z)7tKnu&F=|#2DPAzn0Hzx{!(#E&;_>_^C8d-nP*0KZ?J8M~rZC&Z#-xLttZ-B5+Mx zU*a3p4ePO~_OOPhuRjF%1B5Ph7WSxbzGh48lU!$(M4t*zB1~)LDV_Dr)6S&oydJUD zhY$Nu;4dYeH-)~Wg~Eh=)Pglw7-o#j&K7(+@1-ywM%*1O$sWdSR~ex3t9@J1 z&Aq|}9pQr2vRqq|2(lyCcgiE8?8v@QV~DE}SC?(CuGmm>GJOj*b<#RD_hi)b2&-^r z;3+?cwuVU#2yomhndw$9u^galKVrJgmOCJc9iL&(vFHYBBbdhelM8d6n#gnVrz4R5 zr|gR~fEMqYc%N*q3?L-T;-tdyUSYR)I6i^}GLqZpN3beJ7V!%y8i^011S}d^%x@{b zrTh-&cQC(0`NgemM3CPgzhQpE{Ep^#G{58dwTwxYe^R`+Xus0%xl@Vcmm&Xc9hnE= z$gv?2TSt!PIj40bUPL)!gA#mq6>b}1+q5DBW(Ld}X6Z9jA%1pV?32;X zYz<^HsdvbIE>yOns$!FK^I*zIpr;ROufdc$RI%E*8JV2L43@fTN7`x*5SjFxSg|Ii_XhFLsL^Uw*}LX%f5e^@PL<3ziN3=RjQ9&QU_=Jx zRmmMOaApU9BvkRdlaTv5?E3TIac;VVEI5eT$(3%cHDaoAf9yf$8K594z}^SG&A*;N zJ(q1gKCqEVYfLFXRt9RlkCmlL*Wmk|;J6o=^a`JuPwr~(Y;zYqpvXA+n0=JEA^pcp9p{r#9cMw$UEL*hsV4noBS*+BuvtILKX=2nIr{^7`^b zpjRGpT2TzJcY2>_&0ct?eT2{{7t17nV&zH6Zs%9TU8^b-sDrQr(Zo;k$ChtXEsBXB zi6+(wPg)kLo1WKs8u7rGH+oUA#1RU4^o_`UYzkk$D=1{HQf8+!tAP3GEG!S!?{pg1 zQ#R-<Vu8UTDNNiroTX<49wmd)+(~jD|`r5}7A4*ZG+#VrUHJ_eIjpw4yNDx0d z_Gxa-dcT=_sMylcU&VHxF{7Ej6Y3OQZx$8wIWgpbLK!YUV; zPHev_IcnxrtQ6U7zBBtHin}c>$zyF;E;*DHamjk1IeaS-X#y?MnTE{!OTl-|&Senz z7QWP}mOP!AJO|WxH=Ww~iL1~oS$|Tt;Ydm>20w&$_5lMzA2u_k3s^ILs36sTzsz9O z6liXEtybJaeo5q@1bV3EmK+MrSoflLOHXxq+gIsedIIoIs_Mt)Ak%ImHbEoQsP z`DQ+R)fM?q97GAs#xDJ4AqS-uAO6Yt&2r~g&1K7-rLSSr_Wv{YCh%1k*Z+3{0m2e* ztf-Az<_f{*lR;gQU>vD}6 z6SjaW;)bGv*5!MR2#P>lAkX`A=6ja})c*ee=kB(Aahe(;94; z#k2~uOxozzV4}p;@zRf|V{zv?&Y_N7^V9-FzJdIu?msEt-F#=^cGPb21rq~YhTkfK zB#TUj(ska~XMyTu8|zxqFc)AkJ_m}ReBMk3i;o zHAOq+DilfH`X*2x0m?Z?zuJA_F-pR1C+FxjrFiG98Bq6bZcQ(ni<6e(c-g+%K6mpl z+W~WUUE2o7Z++*>;pJ`X{dweF64lj(%V#Ag(K*x7{w`Tg0nYu`-N_3qzLT@$UuXKU zv(IF`jO^-f{Gn@ZFPi(5hCTT|m|$h(4Rxb;xB8!^OVXG`-@I`I1F;5w+?rqQp{Y-Y z25qhg+^_5T?0hA9xNTh=Q+YLCi5XhX2&>+T`Ekk+rOj8){#IwxGYt>Sxyfylo= zDv00rKqSOm3{8E;EKqfSqhnk#^L=(O>N;PAXFq&z{9W7^siD>T&kuBZK_F$6jIZ_& zRkZ6lY>L(eu5a#IMnf>cDZA)@#bC(!4l*>Y%s8+pB z@N&0%aw2IMa89~7G<9@;NVooa3ah_O)E0oMGNKJB*+9gug}Et_~5-I&xF2*IPpE*YRo z)|md)T69RV(F#Pgc9`yw7TF@GF6lou_qnlniI4V5_A{EM$EhbY^(CtER^Gg+Blj%V zAir0V0c%PH{OLq+OfnF(tkSh$mktV-2BQbM{*V`B>yN4HLh&nyS51AnDjq%{$2*%k zl5!&G_fM*xyMb?%brjQL=^zu;ZW)NE7WqV?8uh3At)vb-*H*^PDbzqjZlOatFtT|7 z?c0^Q=S2LW!@rC8%K{OJhi(GA$d{V{j|z`nCcu?U0JliC?b(o`8m>gH3kI%VW(4go zgxT_TFcGmv6?`%fx)v2SiMczvo-lD|N857i&kX$wt}Fcm$Bv=xkJB2`^X&5P?=sKo z&tXiBv<9d7(r)I*?~&+J^J9TOKO*nB#xp18fNz=>1J`^-!Z*_6jW_<+^f(ffzJ(tD ztLfJc-K3`9zrjn>&y7e@=3Jta%zV2Cu^SHXBkK?uG*~}79uOYq=G}E_wVVIR%hYG^ zA*1t4Qt(;x!@u8p#|<`1QrWs2q|NAENQO(L;lr5{K8|al@lcofa5|+WkD=;RdH>Fu z2#tr?L})maiEw$_w(R={{th%Y#_XRSp&ivM(%4>!mTSs_v59$gU!io{N=n^Vx#2xy zr}p1A=Azv2kL8;7QDXf~olRF!FCsZRV&u+ML0Cw1iL5_oeGol^8L7kvbIpD<`o^HA z%bvM(aAo|Ij$riZ;Gk6}$1C?8eoDN$PgyAU3l>B1SUgo1VlS2(;!T3Bc(9F67_LHD ziEfCVp#8+-{^W*tLQ}bgE*;!5cxj8cQjGgurLJGxT;z5_;Hf4~|(4-6wxF^8K zxJS~TjdvT^uuB0$=DDJTK0NLtF_T)rk$)Jsto?tQznHv3i@nO&O!y1Z%qqYo0Y$eO zi{YrqCLw1Dte-;ETYs=W7welxM_a>%!MfI7!FYw1+xB2fM|XB&vnGXkh_}1rG`CY? z9q)v&*5-j_)zp<{E+b{7tR}yUEBd2W$=RYH?R*y%Ux~#9^yMw+nP+S#I z73>JdhHU#!Mcy^-m>wqq?Tz7+eTf4KhHn=h!!^l z=6}LYGIm`pF>;Ua5Wm%B8^Z@7GWTQg@c9z=LAIy4OCa(AP{G7DSL4Trq&Qo;M(+%& zOP#Kw9jLCB*>R4?l}AH zfjXpLA71v5FICy-?y(@RPbhbXb9J2j8R)w4!m5{X;L4VJ8z@N`JX{f|e})e^RlPmP zOkIU~wmleKRo9aLlh}YgD$8E{NpwJ;i#LXHpAO|dpPWT$sKNW;j#tP92OU#_Pkz@h z3eLfNaVqDL@#=z{OO7qwriU?l$4a9^?Bx%=i-A?~$kJ)ikv#LXLeF9ZBAYcFD32HP zA7UPZ7lY)j6tx)FuUG096eR`MeVKpp{lVz!(rv-I4einGbt~}u->CgB&If}@} z%|^Jxh8|=rD}ET-aP$w|_C$RxeF%-819@ku1}OFxWF=+ES`L!S~DqTg$mb3Z& zFmU3zA@&$-60YCZ2D@x^;F`lJvveJ5g#(iV_!PdpEE9_2sP>wGpvqnh)W1P7sBy~P znDd|Dpw*^4$|ov>Ic_LEUr<>8hT=DAcNVy=B~KcpcvEaN%$xdCu z!1hvqFX-1Zeqt`85m?AJGbeO&r-W{npp8tIgzlCguG1wU&k{CMa+ic2mhjrH2|X>L zY1f2amLSDNm!k45K||anp*IP$XLgC~qsU)%iR`P$v0WnjDROw1$O1(k61ur=30|OG zp9RZS(`}p!O~pTF#AeZgynQOUCS&t5ITcNNgYHNAYxQ`-sYESDsYzQ)3t0UQV$j*w zelj4n-u{|sTW?X*oKfw+%27uDEDUwSU8vA4eTT$DKtvFD;1dnr!O zMK$)+m!6Ai?4d6`7iITd?765$=AC;ksu8qvlJ_eWvdu~URbMAqn}=QeePiH@_J@HF z-5>^@lj7f}vr91keedU;_;+#y30eF+1^=EF67l=Tw{}YBz04V$aun7+i*jqs43nyL z;#B({Czz>lR(T?ncBfYhpNmcnr&G=0?{)BOVh1Otq9StJ_+IA5?ScInw+Jn3x`IDW z+}-zNiMws9P476@!Oas~eP_5$RR)JGCiGI{;C?Q+y3TN|4z5;kPQNtP9eF*MvZr&G zGreHl7pMp2(}`^Y$IrmrED%{uR$cX&!5&LR)e?@?Sk#e&nKwF1TONp% zK?Bv%%k$al4hcmEld~RUB`keM&7z(h{D$%1QmAg~jNEM%g%#29(*yO#f*=cTd|Z3o zyW7LPrS+ zOqs2t`m5HA*oagTwRaY>cUl=ced=oP>srjO)0&lc%i+Yd{t}2SnD~pTju+ft#DLwy zchlwkaRjhW$OiTv^a5x@Yy<-Ja`|pOUaO3CBk1t^iArA0AM}jty<)$<;pzH#mN78@ zVU1dR@52TLSV8ix3gs^8c(;KrD-J|TKqT3lKgRdud}h6OJd;?Xa)+{6(_ME4>a8|u z;h-a*4C-|lk(zZzbeL(@31if(dXAT?(&@k@vM{=$78-&sRacarT_IYzK8b$X!v zeP`^-9B*wlacxbgZ07Xvr21{M^A_jV3=Sryih;xn%0R#IDk^Haj6ZJ9 z-BGDdaV#2om^nQ?uk+ELL_cHI6#KS~dvb4EUZ_6{$nb^rZ>!j|Tg~APk?5zfnbUQ7 z?7brM1$DctK&pPX59Il#(lt%C7PfGV*ueh6ovV5FV#aME+PWVz)vwbR4u4~_v8n3_ z7kEeS++p)ndM$d?JNN_l#v0%BabhtI3)II+bjL7%a$oG<{?1plrF2b8vist^Eup{F zOj_Kn=7hz$HG?&&>n`U#v3{YcvxbP_-bN|3C$DBqx}i>=#MXA71$q0nJ?qmod*6L{ zzHnb83vGQLZhPCcFSgI(Zqa>hVGrNh_BwhfZUC8Y2q?c}95b`#Zy{f06-+$fhUbra zrD*oAso^nwOvj0xbw==^#yc#_uye@b%|YZ%z3UfwgRFSr)tfZ2OJ;?po;JjLYObsy zP}c0p{zAIc%Th%)9sN1FPTGCl}uXFi6_#XK#B*yZ&Jg1UJ zbYKP$Zru+&(jC1yyVXl_+1)0jGj_`NNB80RsLY;t!p`JR#Lr@iPH&(me4V67$W54B^)9FKndilm* z^Bv+l3np1aExSKmY=EzJga`Yyzq9dFASvbW#J)LRH#&bskKgi1R9X&N(WAFw=p2V% zZTT0E5;lWZY~wZ(z@^8Mbb6M(4wnJ!Mm8=?qc6#wjt3twlXvOiyb~Yh^jK%nt%1m0 zM9lrF1A!u;Kcl(57)=IFU2DoE4%36t*S$Xgk3MfQxNaK8M!b$DAJqHwBYR_A06iZOVxvZ|vzvZOk2j>k!Mhj$nfaDDUd9(Wvb>u76& zZfnc;R6A*6A8X=h&laKv2XSYHpXx#F7vVnJlDXuy_xnai?J~qxgtyA*a;Mn5vqajU z5bl6k5Y4u@UkR>hM$+&cZzfVVZmyVd&~uSDoh}ez2kSa20@q#({YX8=0{kmJQGXSM z>PD8pa^$+kduB0&z{%s(nybGf(rVDL4<#a5fw(OiaFoK zoEog#nH!il5Cos(|D3iXDR`t0GswXV&g44I#q5WbL1o$2@YFP>KQc^fmgq4FO7Gwx zx2b~ibdBiXbNeCP_qysgDaxfH&;8{vnk@|&V*V|*DZG9ZyENcntwfS&BPg|Xqi)GKqii!o7 zb)bB&`y{t!14iWNC0!m3SsmS++m}J*U2>+oETji|bJ$ri?xu93;v!s8%}(J5Z7}yQ zRJ1M>#-1o?2BqlpgI2Kf=-r?lV%ewR!!)1!;b;~^)j7G93&t1%$=sUtp{UD|JeX$7 zkUbTl*65LrX~e6ww6b1G-Q*ekq3rdI6Q~Gz=J)%V4Ds0>$PhJawslw&l8;ErIMYE~ z=pYseVmuJco7kAVPWFAQw+QE2OdbD-jTzE4J-Uj0Sg~FZt`r6K>Xgp@uTz-)Ug6U0 z{akF!luqI3%+BH1m|30D35TLHXTh*)X$1K8>r{T~7-DlMc7k^;J+f_CKJST1&PI=m z*@^$IlI%K6^}N36P>S*H#NVT6h%HTmTpjSlGPD$-@tTe-J73}cp$%2e6 zhg3g<;;Q547e$vq<;+-b)svs%iYie54)tJ8b7b9DXgbis4!q<!J1kd|6F;}2@-wk2%AULYg-=0LqTf~mQ+kwwitt>NNZqphW@^mgp?Xt^=Y z8J1IqYs|c(r9*zYD)%|la--+KX15?m%5<$A=?aN|G+e;L$;bFg_dw*gG_`FtZ|Q-v zubmG>Ml13q=*ReL@+5+8o(axZQIC!DZYwJ4vq@CBmY@}x1gE7Al9G~l9vRIA=rab< zllv_gJup71!%i+5e@?@o?Wdireo{Xu_m&s3$-jRZKS zIdRXznxlh>pIT(WWfIFJt2RB$A17UWTIQq+_oSjvH_k7^K9cO&<^G6Yf9ILY&Xa33 z;UC*2ic1d<&HYlFQCru;3kY>56c%ʜv%8|kl5-A6q`7^%(t!0)dVMxI3Ib30@7 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

FW}ojnYzkJLspN*9il5`Vx?VK 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

P2CsSbNT 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%0Al{U-SV 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�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%0D0x9$hZw~iLmpK<<7db`GaZT7RY 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%0Af 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 ZkGUtlOIp{O-dm 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 literal 0 HcmV?d00001 diff --git a/bundles/n2n_meyerd/.gitignore b/bundles/n2n_meyerd/.gitignore new file mode 100644 index 00000000..53b0be40 --- /dev/null +++ b/bundles/n2n_meyerd/.gitignore @@ -0,0 +1,18 @@ +.svn/ +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +benchmark +benchmark_hashtable +doc/ +edge +gnutls/ +libn2n.a +libscm.a +Makefile +supernode +test +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +~$ diff --git a/bundles/n2n_meyerd/README b/bundles/n2n_meyerd/README new file mode 100644 index 00000000..e618ed38 --- /dev/null +++ b/bundles/n2n_meyerd/README @@ -0,0 +1,13 @@ +This is a development branch of the n2n p2p vpn software. + +https://github.com/ntop/n2n + +It contains some modifications of the v2 version of n2n, which is the latest stable version +and should be used for productive environments. +All the current development happens in this repository in the new_protocol branch, which is +intended to be come version v3 of n2n and then merged back into the original svn repository +on ntop.org. + +Uses sglib http://sglib.sourceforge.net. + +For further information please visit the wiki https://github.com/meyerd/n2n/wiki. diff --git a/bundles/n2n_meyerd/n2n_v1/COPYING b/bundles/n2n_meyerd/n2n_v1/COPYING new file mode 100644 index 00000000..b33b35d0 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + n2n Copyright (C) 2007-08 Luca Deri + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_meyerd/n2n_v1/HACKING b/bundles/n2n_meyerd/n2n_v1/HACKING new file mode 100644 index 00000000..b0b9e675 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/HACKING @@ -0,0 +1,273 @@ +file: HACKING + +Last updated: 2008-04-10 + +-------- +(C) 2008 - Richard Andrews + +This program and document 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 3 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 see see + +-------- + + +This file describes the internals of n2n. Read this before starting to modify +the code. Because coding examples may be present in this document it is licensed +under the GPL rather than FDL. + + +SYMMETRIC NAT +------------- + +Symmetric NAT is a form of firewall NAT in which an UDP packets are only passed +back to an inside host socket when the return packets originate from the outside +socket to which the initiating UDP packets were sent. This means that when an +inside host sends UDP to some outside socket; other hosts cannot piggyback on +this opening in the firewall to send data to the inside host. + +When two inside hosts are both behind symmetric NAT, peer-to-peer packet +exchange is not possible via n2n. These hosts will require the supernode to +relay packets. + + +ARP CACHE +--------- + +n2n makes use of the host operating system's own ARP cache. Each edge node +allocates a random MAC address to itself. This MAC is constant for the life of +the edge process. ARP packets are passed around as broadcast ethernet packets +over n2n and these packets cause the native ARP cache to be updated. + +Edge nodes send gratuitous ARP packets on startup. See GRATUITOUS ARP below. + + +REGISTRATION AND PEER-TO-PEER COMMUNICATION SETUP +------------------------------------------------- + +A and B are edge nodes with public sockets Apub and Bpub; and private network +addresses A and B respectively. S is the supernode. + +A sends {REGISTER,Amac} to S. S registers {Amac->Apub}. +B sends {REGISTER,Bmac} to S. S registers {Bmac->Bpub}. + +Now ping from A to B. + +A sends broadcast "arp who-has B" to S. S relays the packet to all known edge +nodes. B replies "B at Bmac" to supernode which forwards this to A. So now ping +A->B is known to be ping Amac(A)->Bmac(B). Note: gratuitous arp also requires +discussion. + +In response to receiving the arp reply, Apub sends {REGISTER,Amac} to Bpub. If +Bpub receives the request it sends back {REGISTER_ACK,Amac} and also sends its +own {REGISTER,Bmac} request. + +In response to receiving the "arp who-has", Bpub sends {REGISTER,Bmac} to Apub. + +Now the OS has received the arp reply and sends ICMP to Bmac(B) via the tunnel +on A. A looks up Bmac in the peers list and encapsulates the packet to Bpub or +the supernode if the MAC is not found. + +We assume that between two edge nodes, if Bpub receives a packet from Apub then +Apub can receive a packet from Bpub. This is the symmetric NAT case. Note: In +the symmetric NAT case, the public socket for a MAC address will be different +for direct contact when compared to information from the supernode. + +When two edge nodes are both behind symmetric NAT they cannot establish direct +communication. + +If A receives {REGISTER,Bmac} from B, A adds {Bmac->Bpub} to its peers list +knowing that Bmac is now reachable via that public socket. Similarly if B +receives {REGISTER,Amac} from A. + +The supernode never forwards REGISTER messages because the public socket seen by +the supervisor for some edge (eg. A) may be different to the socket seen by +another edge due to the actions of symmetric NAT (alocating a new public socket +for the new outbound UDP "connection"). + + +EDGE REGISTRATION DESIGN AMMENDMENTS (starting from 2008-04-10) +------------------------------------ + + * Send REGISTER on rx of PACKET or REGISTER only when dest_mac == device MAC +(do not send REGISTER on Rx of broadcast packets). + * After sending REGISTER add the new peer to pending_peers list; but + * Don't send REGISTER to a peer in pending_peers list + * Remove old entries from pending_peers at regular intervals + * On rx of REGISTER_ACK, move peer from pending_peers to known_peers for direct +comms and set last_seen=now + * On rx of any packet set last_seen=now in the known_peers entry (if it +exists); but do not add a new entry. + * If the public socket address for a known_peers entry changes, deleted it and +restart registration to the new peer. + * Peer sockets provided by the supernode are ignored unless no other entry +exists. Direct peer-to-peer sockets are always given more priority as the +supernode socket will not be usable for direct contact if the peer is behind +symmetric NAT. + + +The pending_peers list concept is to prevent massive registration traffic when +supernode relay is in force - this would occur if REGISTER was sent for every +incident packet sent via supernode. Periodic REGISTER attempts will still occur; +not for every received packet. In the case where the peer cannot be contacted +(eg. both peers behind symmetric NAT), then there will still be periodic +attempts. Suggest a pending timeout of about 60 sec. + +A peer is only considered operational for peer-to-peer sending when a +REGISTER_ACK is returned. Once operational the peer is kept operational while +any direct packet communications are occurring. REGISTER is not required to +keep the path open through any firewalls; just some activity in one direction. + +After an idle period; the peer should be deleted from the known_peers list. We +should not try to re-register when this time expires. If there is no data to +send then forget the peer. This helps scalability. + +If a peer wants to be remembered it can send gratuitous ARP traffic which will +keep its entry in the known_peers list of any peers which already have the +entry. + + + + +peer = find_by_src_mac( hdr, known_peers ); /* return NULL or entry */ + +if ( peer ) +{ + peer_last_seen = time(NULL); +} +else +{ + if ( ! is_broadcast( hdr ) ) /* ignore broadcasts */ + { + if ( IS_REGISTER_ACK( hdr ) ) + { + /* move from pending to known_peers */ + set_peer_operational( hdr ); + } + else + { + /* add to pending and send REGISTER - ignore if in pending. */ + try_send_register( hdr ) + } + } +} + + +(Notes): + + * In testing it was noted that if a symmetric NAT firewall shuts down the UDP +association but the known_peers registration is still active, then the peer +becomes unreachable until the known_peers registration is deleted. Suggest two +ways to mitigate this problem: + (a) make the known_peers purge timeout a config paramter; + (b) send packets direct and via supernode if the registration is older than + eg. 60 sec. + + +GRATUITOUS ARP +-------------- + +In addition to the ARP who-has mechanism noted above, two edge nodes can become +aware of one another by gratuitous ARP. A gratuitous ARP packet is a broadcast +packet sent by a node for no other purpose than to announce its presence and +identify its MAC and IP address. Gratuitous ARP packets are to keep ARP caches +up to date so contacting the host will be faster after an long idle time. + + +MAN PAGES +--------- + +Look at a non-installed man page like this (linux/UNIX): + +nroff -man edge.8 | less + + +PACKET FORMAT +------------- + +Version 1 + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 0 ! Version=1 ! Message Type ! TTL ! Origin ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ! + 8 ! Community Name ! +12 ! ! +16 ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 : Source MAC Address ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : Destination MAC Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 ! Public Peer ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 : ! Alignment ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Private Peer : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +56 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +64 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + : ! Alignment ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +72 ! Packet Type ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Seq Number ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +80 ! CRC32 ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +Version = 1 +MessageType = 1 +TTL = 1 +Origin = 1 +Community = 16 +src MAC = 6 +dst MAC = 6 +Pub Peer = 19 (20) +Priv Peer = 19 (20) +Pkt Type = 1 (4) +Seq = 4 +CRC = 4 +====================== +Total = 79 (84) + +Sizes in parentheses indicate alignment adjusted sizes on i686. The intel +alignment is also shown in the diagram. Some platforms have different alignment +padding. + +The above packet format describes the header of IP packets carried between edge +nodes. Payload is an encoded ethernet frame appended to the packet header. The +ethernet payload is encrypted and compressed. + +When the payload is created it is first encrypted with twofish, then compressed +using lzo1x_compress. When the payload is decoded it is first decompressed using +lzo1x_decompress_safe then decrypted using twofish. + +------- + +January 2009 - Richard Andrews diff --git a/bundles/n2n_meyerd/n2n_v1/INSTALL b/bundles/n2n_meyerd/n2n_v1/INSTALL new file mode 100644 index 00000000..45221d43 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/INSTALL @@ -0,0 +1,50 @@ +INSTALL + +To build the programs: + +$ make + +To install the programs and man pages: + +$ make install + +or + +$ make PREFIX=/usr/local install + + +RPM Package +----------- + +These steps should work with RPM based Linux distributions since rpmbuild was +split from the rpm utility (c RedHat 9). + + +To build an RPM the easy way follow these steps. + +1. Build SRPM + +$ cd n2n +$ scripts/mk_SRPM.sh + +Look for where the src.rpm file was put ( "Wrote:" ). + +2. Build binary RPM from SRPM + +$ rpm -i path/to/n2n-.src.rpm +$ rpmbuild -bb n2n.spec + + +All this can be done as non-root user if you have a ~/.rpmmacros file with this +line in it: + +%_topdir /home/username/rpmtopdir + + +To build an RPM the hard way follow these steps. + +$ cp -a n2ndir n2n-1.3 +$ tar czf n2n-1.3.tar.gz n2n-1.3 +$ mv n2n-1.3.tar.gz /usr/src/redhat/SOURCES +$ cp n2ndir/n2n.spec /usr/src/redhat/SPECS +$ rpmbuild -bb n2n.spec diff --git a/bundles/n2n_meyerd/n2n_v1/README b/bundles/n2n_meyerd/n2n_v1/README new file mode 100644 index 00000000..e021f412 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/README @@ -0,0 +1,95 @@ + + +Edge node +--------- + +You need to start an egde node on each host you want to connect with the *same* +community. + +0. become root + +1. create tun device +# tunctl -t tun0 + +3. enable the edge process +# ./edge -d n2n0 -c mynetwork -k encryptme -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw + or +# N2N_KEY=encryptme ./edge -d n2n0 -c mynetwork -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw + +Once you have this worked out, you can add the "-f" option to make edge detach +and run as a daemon. + +Note that -u, -g and -f options are not available for Windows. + +Supernode +-------- + +You need to start the supernode once + +1. ./supernode -l 1234 -v + + +Dropping Root Privileges and SUID-Root Executables (UNIX) +-------------------------------------------------- + +The edge node uses superuser privileges to create a TAP network interface +device. Once this is created root privileges are not required and can constitute +a security hazard if there is some way for an attacker to take control of an +edge process while it is running. Edge will drop to a non-privileged user if you +specify the -u and -g options. These are numeric IDs. Consult +/etc/passwd. + +You may choose to install edge SUID-root to do this: + +1. Become root +2. chown root:root edge +3. chmod +s edge +done + +Any user can now run edge. You may not want this, but it may be convenient and +safe if your host has only one login user. + + +Running As a Daemon (UNIX) +------------------- + +When given "-f" as a command line option, edge will call daemon(3) after +successful setup. This causes the process to fork a child which closes stdin, +stdout and stderr then sets itself as process group leader. When this is done, +the edge command returns immediately and you will only see the edge process in +the process listings, eg. from ps or top. + +If the edge command returns 0 then the daemon started successfully. If it +returns non-zero then edge failed to start up for some reason. When edge starts +running as a daemon, all logging goes to syslog daemon.info facility. + + +IPv6 Support (added r3650) +------------ + +n2n supports the carriage of IPv6 packets within the n2n tunnel. N2n does not +yet use IPv6 for transport between edges and supernodes. + +To make IPv6 carriage work you need to manually add IPv6 addresses to the TAP +interfaces at each end. There is currently no way to specify an IPv6 address on +the edge command line. + +eg. under linux: + +on hostA: +[hostA] # /sbin/ip -6 addr add fc00:abcd:1234::7/48 dev n2n0 + +on hostB: +[hostB] # /sbin/ip -6 addr add fc00:abcd:1234::6/48 dev n2n0 + +You may find it useful to make use of tunctl from the uml-utilities +package. Tunctl allow you to bring up a TAP interface and configure addressing +prior to starting edge. It also allows edge to be restarted without the +interface closing (which would normally affect routing tables). + +Once the IPv6 addresses are configured and edge started, IPv6 neighbor discovery +packets flow (get broadcast) and IPv6 entities self arrange. Test your IPv6 +setup with ping6 - the IPv6 ping command. + + +(C) 2007,2008 - Luca Deri , Richard Andrews diff --git a/bundles/n2n_meyerd/n2n_v1/android/tuntap_android.c b/bundles/n2n_meyerd/n2n_v1/android/tuntap_android.c new file mode 100644 index 00000000..08aa0fba --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/android/tuntap_android.c @@ -0,0 +1,108 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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, see +*/ + +#include "../n2n.h" + +#ifdef __ANDROID_NDK__ + +#include +#include +#include + +n2n_edge_status_t* g_status; + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver then uses ifconfig + * to configure address/mask and MTU. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + char *device_ip, + char *device_mask, + const char *device_mac, + int mtu) { + int i, n_matched; + unsigned int mac[6]; + + n_matched = sscanf(device_mac, "%x:%x:%x:%x:%x:%x", mac, mac + 1, mac + 2, mac + 3, mac + 4, + mac + 5); + if (n_matched != 6) { + return -1; + } + memset(device->mac_addr, 0, sizeof(device->mac_addr)); + for (i = 0; i < 6; i++) + device->mac_addr[i] = mac[i]; + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->mtu = mtu; + return device->fd; +} + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + int rlen = read(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + if ((rlen <= 0) || (rlen > 2048 - UIP_LLH_LEN)) { + return rlen; + } + uip_buf = buf; + uip_len = rlen; + uip_arp_out(); + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) { + traceEvent(TRACE_INFO, "ARP request packets are sent instead of packets"); + } + + return uip_len; +} + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + int rlen; + uip_buf = buf; + uip_len = len; + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_IP)) { + rlen = write(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + return rlen <= 0 ? rlen : rlen + UIP_LLH_LEN; + } else if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if (uip_len > 0) { + uip_arp_len = uip_len; + memcpy(uip_arp_buf, uip_buf, uip_arp_len); + traceEvent(TRACE_INFO, "ARP reply packet prepare to send"); + } + return len; + } + + errno = EINVAL; + return -1; +} + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +#endif /* #ifdef __ANDROID_NDK__ */ diff --git a/bundles/n2n_meyerd/n2n_v1/debian/README.Debian b/bundles/n2n_meyerd/n2n_v1/debian/README.Debian new file mode 100644 index 00000000..700c74ec --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/README.Debian @@ -0,0 +1,7 @@ +n2n for Debian +-------------- + +This package depends on the kernel having the TUN/TAP driver configured in using +CONFIG_TUN=yes. + + -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 diff --git a/bundles/n2n_meyerd/n2n_v1/debian/changelog b/bundles/n2n_meyerd/n2n_v1/debian/changelog new file mode 100644 index 00000000..3ce8eb1a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/changelog @@ -0,0 +1,12 @@ +n2n (1.3-1) hardy; urgency=low + + * New upstream release + + -- Richard Andrews Fri, 30 Jan 2009 23:49:56 +1100 + +n2n (1.2-1) unstable; urgency=low + + * Initial release + + -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 + diff --git a/bundles/n2n_meyerd/n2n_v1/debian/compat b/bundles/n2n_meyerd/n2n_v1/debian/compat new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/compat @@ -0,0 +1 @@ +5 diff --git a/bundles/n2n_meyerd/n2n_v1/debian/control b/bundles/n2n_meyerd/n2n_v1/debian/control new file mode 100644 index 00000000..6c06deda --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/control @@ -0,0 +1,22 @@ +Source: n2n +Section: net +Priority: extra +Maintainer: Jean-Baptiste Denis +Build-Depends: cdbs, debhelper (>= 5), libc6-dev (>= 2.0), dpatch, gcc +Standards-Version: 3.7.2 + +Package: n2n +Architecture: any +Suggests: uml-utilities +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: a layer-two peer-to-peer virtual private network (VPN) + n2n is a layer-two peer-to-peer virtual private network (VPN) which allows + users to exploit features typical of P2P applications at network instead of + application level. This means that users can gain native IP visibility (e.g. + two PCs belonging to the same n2n network can ping each other) and be + reachable with the same network IP address regardless of the network where + they currently belong. In a nutshell, as OpenVPN moved SSL from application + (e.g. used to implement the https protocol) to network protocol, n2n moves + P2P from application to network level. + + diff --git a/bundles/n2n_meyerd/n2n_v1/debian/copyright b/bundles/n2n_meyerd/n2n_v1/debian/copyright new file mode 100644 index 00000000..38346ce9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/copyright @@ -0,0 +1,23 @@ +This package was debianized by Jean-Baptiste Denis on +Thu, 20 Nov 2008 23:53:02 +1000. + +It was downloaded from http://www.ntop.org/n2n/ + +Upstream Author(s): + + Luca Deri + Richard Andrews + +Copyright: + + Copyright (C) 2008 Luca Deri + Copyright (C) 2008 Richard Andrews + +License: + + GPLv3 + +The Debian packaging is (C) 2008, Richard Andrews , +Luca Deri and is licensed under the GPLv3, see +`/usr/share/common-licenses/GPL-3'. + diff --git a/bundles/n2n_meyerd/n2n_v1/debian/n2n.dirs b/bundles/n2n_meyerd/n2n_v1/debian/n2n.dirs new file mode 100644 index 00000000..8c74f914 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/n2n.dirs @@ -0,0 +1,4 @@ +usr/bin +usr/sbin +usr/share/doc/n2n +usr/share/man/man1 diff --git a/bundles/n2n_meyerd/n2n_v1/debian/n2n.docs b/bundles/n2n_meyerd/n2n_v1/debian/n2n.docs new file mode 100644 index 00000000..a74d034d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/n2n.docs @@ -0,0 +1,3 @@ +README +supernode.1 +edge.8 diff --git a/bundles/n2n_meyerd/n2n_v1/debian/n2n.install b/bundles/n2n_meyerd/n2n_v1/debian/n2n.install new file mode 100644 index 00000000..7ccf7f46 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/n2n.install @@ -0,0 +1,2 @@ +edge /usr/bin +supernode /usr/sbin diff --git a/bundles/n2n_meyerd/n2n_v1/debian/n2n.manpages b/bundles/n2n_meyerd/n2n_v1/debian/n2n.manpages new file mode 100644 index 00000000..b8b5aeba --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/n2n.manpages @@ -0,0 +1,2 @@ +edge.8 +supernode.1 diff --git a/bundles/n2n_meyerd/n2n_v1/debian/rules b/bundles/n2n_meyerd/n2n_v1/debian/rules new file mode 100644 index 00000000..914e4c9f --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/debian/rules @@ -0,0 +1,9 @@ +#!/usr/bin/make -f + +#DEB_MAKE_INSTALL_TARGET = install prefix=$(CURDIR)/debian/n2n/usr + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/dpatch.mk +include /usr/share/cdbs/1/class/makefile.mk + +# Add here any variable or target overrides you need. diff --git a/bundles/n2n_meyerd/n2n_v1/edge.8 b/bundles/n2n_meyerd/n2n_v1/edge.8 new file mode 100644 index 00000000..37d68616 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/edge.8 @@ -0,0 +1,116 @@ +.TH edge 1 "Jan 3, 2009" "revision 3679" "SUPERUSER COMMANDS" +.SH NAME +edge \- n2n edge node daemon +.SH SYNOPSIS +.B edge +[\-d ] \-a \-c \-k \-l +[\-p ] [\-u ] [\-g ] [-f] [\-m ] [\-t] [\-r] [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Edge is the edge node daemon for n2n which +creates a TAP interface to expose the n2n virtual LAN. On startup n2n creates +the TAP interface and configures it then registers with the supernode so it can +begin to find other nodes in the community. +.PP +.SH OPTIONS +.TP +\-d +sets the TAP device name as seen in ifconfig. +.TP +\-a +sets the n2n virtual LAN IP address being claimed. This is a private IP +address. All IP addresses in an n2n community should belong to the same /24 +network (ie. only the last segment of the IP addresses varies). +.TP +\-b +cause edge to perform hostname resolution for the supernode address each time +the supernode is periodically contacted. +.TP +\-c +sets the n2n community name. All edges within the same community look to be on +the same LAN (layer 2 network segment). All edges communicating must use the +same key and community name. +.TP +\-h +write usage to tty then exit. +.TP +\-k +sets the twofish encryption key from ASCII text (see also N2N_KEY in +ENVIRONMENT). All edges communicating must use the same key and community name. +.TP +\-l : +sets the n2n supernode IP address and port to register to. +.TP +\-p +binds edge to the given UDP port. Useful for keeping the same external socket +across restarts of edge. +.TP +\-u +causes the edge process to drop to the given user ID when privileges are no +longer required. +.TP +\-g +causes the edge process to drop to the given group ID when privileges are no +longer required. +.TP +\-f +causes the edge process to fork and run as a daemon, closing stdin, stdout, +stderr and becoming a process group leader. +.TP +\-m +start the TAP interface with the given MAC address. This is highly recommended +as it means the same address will be used if edge stops and restarts. If this is +not done, the ARP caches of all peers will be wrong and packets will not flow to +this edge until the next ARP refresh. +.TP +\-M +set the MTU of the edge interface in bytes. MTU is the largest packet fragment +size allowed to be moved throught the interface. The default is 1400. +.TP +\-s +set the netmask of edge interface in IPv4 dotted decimal notation. The default +is 255.255.255.0 (ie. /24). +.TP +\-t +use HTTP tunneling instead of the normal UDP mechanism (experimental). +.TP +\-r +enable packet forwarding/routing through the n2n virtual LAN. Without this +option, packets arriving over n2n which are not for the -a IP address are +dropped. +.TP +\-v +use verbose logging. +.SH ENVIRONMENT +.TP +.B N2N_KEY +set the encryption key so it is not visible on the command line +.SH EXAMPLES +.TP +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-p 50001 \-l 123.121.120.119:7654 + +Start edge with TAP device n2n0 on community "mynetwork" with community +supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to +50001. Use "encryptme" as the shared encryption key. Assign MAC address +DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 after +the TAP device is successfull configured. +.PP +Add the -f option to make edge run as a daemon. +.PP +Somewhere else setup another edge with similar parameters, eg. + +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP +Now you can ping from 192.168.254.5 to 192.168.254.7. +.PP +The MAC address (-m ) and virtual IP address (-a ) must be different on all edges in the same community. + +.SH CONFIGURATION +All configuration for edge is from the command line and environment +variables. If you wish to reconfigure edge you should kill the process and +restart with the desired options. +.SH EXIT STATUS +edge is a daemon and any exit is an error. +.SH AUTHOR +Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner +.SH SEE ALSO +ifconfig(8) supernode(1) tunctl(8) diff --git a/bundles/n2n_meyerd/n2n_v1/edge.c b/bundles/n2n_meyerd/n2n_v1/edge.c new file mode 100644 index 00000000..cbac25e5 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/edge.c @@ -0,0 +1,1832 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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 see see + * + * Code contributions courtesy of: + * Don Bindner + * Sylwester Sosnowski + * Wilfried "Wonka" Klaebe + * + */ + +#include "minilzo.h" +#include "n2n.h" +#include +#include + +#ifdef __ANDROID_NDK__ +#include +#include +#endif /* __ANDROID_NDK__ */ + +/** Time between logging system STATUS messages */ +#define STATUS_UPDATE_INTERVAL (30 * 60) /*secs*/ + +#ifdef __ANDROID_NDK__ +#define ARP_PERIOD_INTERVAL (10) /* sec */ +#endif /* __ANDROID_NDK__ */ + +/* maximum length of command line arguments */ +#define MAX_CMDLINE_BUFFER_LENGTH 4096 +/* maximum length of a line in the configuration file */ +#define MAX_CONFFILE_LINE_LENGTH 1024 + +#define N2N_EDGE_SN_HOST_SIZE 48 + +#ifdef __ANDROID_NDK__ +#define N2N_EDGE_MGMT_PORT 5644 +#endif /* __ANDROID_NDK__ */ + +struct n2n_edge +{ + u_char re_resolve_supernode_ip; + struct peer_addr supernode; + char supernode_ip[N2N_EDGE_SN_HOST_SIZE]; + char * community_name /*= NULL*/; + + /* int sock; */ + /* char is_udp_socket /\*= 1*\/; */ + n2n_sock_info_t sinfo; + + u_int pkt_sent /*= 0*/; + tuntap_dev device; + int allow_routing /*= 0*/; + int drop_ipv6_ndp /*= 0*/; + char * encrypt_key /* = NULL*/; + TWOFISH * enc_tf; + TWOFISH * dec_tf; + + struct peer_info * known_peers /* = NULL*/; + struct peer_info * pending_peers /* = NULL*/; + time_t last_register /* = 0*/; +#ifdef __ANDROID_NDK__ + int sn_wait /* = 0*/; +#endif /* #ifdef __ANDROID_NDK__ */ +}; + +static void supernode2addr(n2n_edge_t * eee, char* addr); + +static void send_packet2net(n2n_edge_t * eee, + char *decrypted_msg, size_t len); + + +/* ************************************** */ + +/* parse the configuration file */ +static int readConfFile(const char * filename, char * const linebuffer) { + struct stat stats; + FILE * fd; + char * buffer = NULL; + + buffer = (char *)malloc(MAX_CONFFILE_LINE_LENGTH); + if (!buffer) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return -1; + } + + if (stat(filename, &stats)) { + if (errno == ENOENT) + traceEvent(TRACE_ERROR, "parameter file %s not found/unable to access\n", filename); + else + traceEvent(TRACE_ERROR, "cannot stat file %s, errno=%d\n",filename, errno); + free(buffer); + return -1; + } + + fd = fopen(filename, "rb"); + if (!fd) { + traceEvent(TRACE_ERROR, "Unable to open parameter file '%s' (%d)...\n",filename,errno); + free(buffer); + return -1; + } + while(fgets(buffer, MAX_CONFFILE_LINE_LENGTH,fd)) { + char * p = NULL; + + /* strip out comments */ + p = strchr(buffer, '#'); + if (p) *p ='\0'; + + /* remove \n */ + p = strchr(buffer, '\n'); + if (p) *p ='\0'; + + /* strip out heading spaces */ + p = buffer; + while(*p == ' ' && *p != '\0') ++p; + if (p != buffer) strncpy(buffer,p,strlen(p)+1); + + /* strip out trailing spaces */ + while(strlen(buffer) && buffer[strlen(buffer)-1]==' ') + buffer[strlen(buffer)-1]= '\0'; + + /* check for nested @file option */ + if (strchr(buffer, '@')) { + traceEvent(TRACE_ERROR, "@file in file nesting is not supported\n"); + free(buffer); + return -1; + } + if ((strlen(linebuffer)+strlen(buffer)+2)< MAX_CMDLINE_BUFFER_LENGTH) { + strncat(linebuffer, " ", 1); + strncat(linebuffer, buffer, strlen(buffer)); + } else { + traceEvent(TRACE_ERROR, "too many argument"); + free(buffer); + return -1; + } + } + + free(buffer); + fclose(fd); + + return 0; +} + +/* Create the argv vector */ +static char ** buildargv(char * const linebuffer) { + const int INITIAL_MAXARGC = 16; /* Number of args + NULL in initial argv */ + int maxargc; + int argc=0; + char ** argv; + char * buffer, * buff; + + buffer = (char *)calloc(1, strlen(linebuffer)+2); + if (!buffer) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return NULL; + } + strncpy(buffer, linebuffer,strlen(linebuffer)); + + maxargc = INITIAL_MAXARGC; + argv = (char **)malloc(maxargc * sizeof(char*)); + if (argv == NULL) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return NULL; + } + buff = buffer; + while(buff) { + char * p = strchr(buff,' '); + if (p) { + *p='\0'; + argv[argc++] = strdup(buff); + while(*++p == ' ' && *p != '\0'); + buff=p; + if (argc >= maxargc) { + maxargc *= 2; + argv = (char **)realloc(argv, maxargc * sizeof(char*)); + if (argv == NULL) { + traceEvent(TRACE_ERROR, "Unable to re-allocate memory"); + free(buffer); + return NULL; + } + } + } else { + argv[argc++] = strdup(buff); + break; + } + } + argv[argc] = NULL; + free(buffer); + return argv; +} + + + +/* ************************************** */ + +static int edge_init(n2n_edge_t * eee) { +#ifdef WIN32 + initWin32(); +#endif + memset(eee, 0, sizeof(n2n_edge_t)); + + eee->re_resolve_supernode_ip = 0; + eee->community_name = NULL; + eee->sinfo.sock = -1; + eee->sinfo.is_udp_socket = 1; + eee->pkt_sent = 0; + eee->allow_routing = 0; + eee->drop_ipv6_ndp = 0; + eee->encrypt_key = NULL; + eee->enc_tf = NULL; + eee->dec_tf = NULL; + eee->known_peers = NULL; + eee->pending_peers = NULL; + eee->last_register = 0; +#ifdef __ANDROID_NDK__ + eee->sn_wait = 0; +#endif /* #ifdef __ANDROID_NDK__ */ + + if(lzo_init() != LZO_E_OK) { + traceEvent(TRACE_ERROR, "LZO compression error"); + return(-1); + } + + return(0); +} + +static int edge_init_twofish( n2n_edge_t * eee, u_int8_t *encrypt_pwd, u_int32_t encrypt_pwd_len ) +{ + eee->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + eee->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + + if ( (eee->enc_tf) && (eee->dec_tf) ) + { + return 0; + } + else + { + return 1; + } +} + +/* ************************************** */ + +static void edge_deinit(n2n_edge_t * eee) { + TwoFishDestroy(eee->enc_tf); + TwoFishDestroy(eee->dec_tf); + if ( eee->sinfo.sock >=0 ) + { + close( eee->sinfo.sock ); + } +} + +static void readFromIPSocket( n2n_edge_t * eee ); + +static void help() { + print_n2n_version(); + + printf("edge " +#ifdef __linux__ + "-d " +#endif + "-a " + "-c " + "-k " + "-s " +#ifndef WIN32 + "[-u -g ]" + "[-f]" +#endif + "[-m ]" + "\n" + "-l " + "[-p ] [-M ] " + "[-t] [-r] [-v] [-b] [-h]\n\n"); + +#ifdef __linux__ + printf("-d | tun device name\n"); +#endif + + printf("-a | n2n IP address\n"); + printf("-c | n2n community name\n"); + printf("-k | Encryption key (ASCII) - also N2N_KEY=\n"); + printf("-s | Edge interface netmask in dotted decimal notation (255.255.255.0)\n"); + printf("-l | Supernode IP:port\n"); + printf("-b | Periodically resolve supernode IP\n"); + printf(" | (when supernodes are running on dynamic IPs)\n"); + printf("-p | Local port used for connecting to supernode\n"); +#ifndef WIN32 + printf("-u | User ID (numeric) to use when privileges are dropped\n"); + printf("-g | Group ID (numeric) to use when privileges are dropped\n"); + printf("-f | Fork and run as a daemon. Use syslog.\n"); +#endif + printf("-m | Choose a MAC address for the TAP interface\n" + " | eg. -m 01:02:03:04:05:06\n"); + printf("-M | Specify n2n MTU (default %d)\n", DEFAULT_MTU); + printf("-t | Use http tunneling (experimental)\n"); + printf("-r | Enable packet forwarding through n2n community\n"); + printf("-v | Verbose\n"); + + printf("\nEnvironment variables:\n"); + printf(" N2N_KEY | Encryption key (ASCII)\n" ); + + exit(0); +} + +/* *********************************************** */ + +static void send_register( n2n_edge_t * eee, + const struct peer_addr *remote_peer, + u_char is_ack) { + struct n2n_packet_header hdr; + char pkt[N2N_PKT_HDR_SIZE]; + size_t len = sizeof(hdr); + ipstr_t ip_buf; + + fill_standard_header_fields( &(eee->sinfo), &hdr, (char*)(eee->device.mac_addr)); + hdr.sent_by_supernode = 0; + hdr.msg_type = (is_ack == 0) ? MSG_TYPE_REGISTER : MSG_TYPE_REGISTER_ACK; + memcpy(hdr.community_name, eee->community_name, COMMUNITY_LEN); + + marshall_n2n_packet_header( (u_int8_t *)pkt, &hdr ); + send_packet( &(eee->sinfo), pkt, &len, remote_peer, N2N_COMPRESSION_ENABLED ); + + traceEvent(TRACE_INFO, "Sent %s message to %s:%hu", + ((hdr.msg_type==MSG_TYPE_REGISTER)?"MSG_TYPE_REGISTER":"MSG_TYPE_REGISTER_ACK"), + intoa(ntohl(remote_peer->addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(remote_peer->port)); +} + +/* *********************************************** */ + +static void send_deregister(n2n_edge_t * eee, + struct peer_addr *remote_peer) { + struct n2n_packet_header hdr; + char pkt[N2N_PKT_HDR_SIZE]; + size_t len = sizeof(hdr); + + fill_standard_header_fields( &(eee->sinfo), &hdr, (char*)(eee->device.mac_addr) ); + hdr.sent_by_supernode = 0; + hdr.msg_type = MSG_TYPE_DEREGISTER; + memcpy(hdr.community_name, eee->community_name, COMMUNITY_LEN); + + marshall_n2n_packet_header( (u_int8_t *)pkt, &hdr ); + send_packet( &(eee->sinfo), pkt, &len, remote_peer, N2N_COMPRESSION_ENABLED); +} + +/* *********************************************** */ + +static void update_peer_address(n2n_edge_t * eee, + const struct n2n_packet_header * hdr, + time_t when); +void trace_registrations( struct peer_info * scan ); +int is_ip6_discovery( const void * buf, size_t bufsize ); +void check_peer( n2n_edge_t * eee, + const struct n2n_packet_header * hdr ); +void try_send_register( n2n_edge_t * eee, + const struct n2n_packet_header * hdr ); +void set_peer_operational( n2n_edge_t * eee, const struct n2n_packet_header * hdr ); + + + +/** Start the registration process. + * + * If the peer is already in pending_peers, ignore the request. + * If not in pending_peers, add it and send a REGISTER. + * + * If hdr is for a direct peer-to-peer packet, try to register back to sender + * even if the MAC is in pending_peers. This is because an incident direct + * packet indicates that peer-to-peer exchange should work so more aggressive + * registration can be permitted (once per incoming packet) as this should only + * last for a small number of packets.. + * + * Called from the main loop when Rx a packet for our device mac. + */ +void try_send_register( n2n_edge_t * eee, + const struct n2n_packet_header * hdr ) +{ + ipstr_t ip_buf; + + /* REVISIT: purge of pending_peers not yet done. */ + struct peer_info * scan = find_peer_by_mac( eee->pending_peers, hdr->src_mac ); + + if ( NULL == scan ) + { + scan = calloc( 1, sizeof( struct peer_info ) ); + + memcpy(scan->mac_addr, hdr->src_mac, 6); + scan->public_ip = hdr->public_ip; + scan->last_seen = time(NULL); /* Don't change this it marks the pending peer for removal. */ + + peer_list_add( &(eee->pending_peers), scan ); + + traceEvent( TRACE_NORMAL, "Pending peers list size=%ld", + peer_list_size( eee->pending_peers ) ); + + traceEvent( TRACE_NORMAL, "Sending REGISTER request to %s:%hu", + intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(scan->public_ip.port)); + + send_register(eee, + &(scan->public_ip), + 0 /* is not ACK */ ); + + /* pending_peers now owns scan. */ + } + else + { + /* scan already in pending_peers. */ + + if ( 0 == hdr->sent_by_supernode ) + { + /* over-write supernode-based socket with direct socket. */ + scan->public_ip = hdr->public_ip; + + traceEvent( TRACE_NORMAL, "Sending additional REGISTER request to %s:%hu", + intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(scan->public_ip.port)); + + + send_register(eee, + &(scan->public_ip), + 0 /* is not ACK */ ); + } + } +} + + +/** Update the last_seen time for this peer, or get registered. */ +void check_peer( n2n_edge_t * eee, + const struct n2n_packet_header * hdr ) +{ + struct peer_info * scan = find_peer_by_mac( eee->known_peers, hdr->src_mac ); + + if ( NULL == scan ) + { + /* Not in known_peers - start the REGISTER process. */ + try_send_register( eee, hdr ); + } + else + { + /* Already in known_peers. */ + update_peer_address( eee, hdr, time(NULL) ); + } +} + + +/* Move the peer from the pending_peers list to the known_peers lists. + * + * peer must be a pointer to an element of the pending_peers list. + * + * Called by main loop when Rx a REGISTER_ACK. + */ +void set_peer_operational( n2n_edge_t * eee, const struct n2n_packet_header * hdr ) +{ + struct peer_info * prev = NULL; + struct peer_info * scan; + macstr_t mac_buf; + ipstr_t ip_buf; + + scan=eee->pending_peers; + + while ( NULL != scan ) + { + if ( 0 != memcmp( scan->mac_addr, hdr->dst_mac, 6 ) ) + { + break; /* found. */ + } + + prev = scan; + scan = scan->next; + } + + if ( scan ) + { + + /* Remove scan from pending_peers. */ + if ( prev ) + { + prev->next = scan->next; + } + else + { + eee->pending_peers = scan->next; + } + + /* Add scan to known_peers. */ + scan->next = eee->known_peers; + eee->known_peers = scan; + + scan->public_ip = hdr->public_ip; + + traceEvent(TRACE_INFO, "=== new peer [mac=%s][socket=%s:%hu]", + macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), + intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(scan->public_ip.port)); + + traceEvent( TRACE_NORMAL, "Pending peers list size=%ld", + peer_list_size( eee->pending_peers ) ); + + traceEvent( TRACE_NORMAL, "Operational peers list size=%ld", + peer_list_size( eee->known_peers ) ); + + + scan->last_seen = time(NULL); + } + else + { + traceEvent( TRACE_WARNING, "Failed to find sender in pending_peers." ); + } +} + + +void trace_registrations( struct peer_info * scan ) +{ + macstr_t mac_buf; + ipstr_t ip_buf; + + while ( scan ) + { + traceEvent(TRACE_INFO, "=== peer [mac=%s][socket=%s:%hu]", + macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), + intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(scan->public_ip.port)); + + scan = scan->next; + } + +} + +u_int8_t broadcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + +/** Keep the known_peers list straight. + * + * Ignore broadcast L2 packets, and packets with invalid public_ip. + * If the dst_mac is in known_peers make sure the entry is correct: + * - if the public_ip socket has changed, erase the entry + * - if the same, update its last_seen = when + */ +static void update_peer_address(n2n_edge_t * eee, + const struct n2n_packet_header * hdr, + time_t when) +{ + ipstr_t ip_buf; + struct peer_info *scan = eee->known_peers; + struct peer_info *prev = NULL; /* use to remove bad registrations. */ + + if ( 0 == hdr->public_ip.addr_type.v4_addr ) + { + /* Not to be registered. */ + return; + } + + if ( 0 == memcmp( hdr->dst_mac, broadcast_mac, 6 ) ) + { + /* Not to be registered. */ + return; + } + + + while(scan != NULL) + { + if(memcmp(hdr->dst_mac, scan->mac_addr, 6) == 0) + { + break; + } + + prev = scan; + scan = scan->next; + } + + if ( NULL == scan ) + { + /* Not in known_peers. */ + return; + } + + if ( 0 != memcmp( &(scan->public_ip), &(hdr->public_ip), sizeof(struct peer_addr))) + { + if ( 0 == hdr->sent_by_supernode ) + { + traceEvent( TRACE_NORMAL, "Peer changed public socket, Was %s:%hu", + intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(hdr->public_ip.port)); + + /* The peer has changed public socket. It can no longer be assumed to be reachable. */ + /* Remove the peer. */ + if ( NULL == prev ) + { + /* scan was head of list */ + eee->known_peers = scan->next; + } + else + { + prev->next = scan->next; + } + free(scan); + + try_send_register( eee, hdr ); + } + else + { + /* Don't worry about what the supernode reports, it could be seeing a different socket. */ + } + } + else + { + /* Found and unchanged. */ + scan->last_seen = when; + } +} + + + +#if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */ + +/* *********************************************** */ + +static char gratuitous_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* Ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* Hw Size */ + 0x04, /* Protocol Size */ + 0x00, 0x01, /* ARP Request */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x00, 0x00, 0x00, 0x00, /* Src IP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ + 0x00, 0x00, 0x00, 0x00 /* Target IP */ +}; + +static int build_gratuitous_arp(char *buffer, u_short buffer_len) { + if(buffer_len < sizeof(gratuitous_arp)) return(-1); + + memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); + memcpy(&buffer[6], device.mac_addr, 6); + memcpy(&buffer[22], device.mac_addr, 6); + memcpy(&buffer[28], &device.ip_addr, 4); + + /* REVISIT: BbMaj7 - use a real netmask here. This is valid only by accident + * for /24 IPv4 networks. */ + buffer[31] = 0xFF; /* Use a faked broadcast address */ + memcpy(&buffer[38], &device.ip_addr, 4); + return(sizeof(gratuitous_arp)); +} + +/** Called from update_registrations to periodically send gratuitous ARP + * broadcasts. */ +static void send_grat_arps(n2n_edge_t * eee,) { + char buffer[48]; + size_t len; + + traceEvent(TRACE_NORMAL, "Sending gratuitous ARP..."); + len = build_gratuitous_arp(buffer, sizeof(buffer)); + send_packet2net(eee, buffer, len); + send_packet2net(eee, buffer, len); /* Two is better than one :-) */ +} +#endif /* #if defined(DUMMY_ID_00001) */ + + + +/* *********************************************** */ + +/** @brief Check to see if we should re-register with our peers and the + * supernode. + * + * This is periodically called by the main loop. The list of registrations is + * not modified. Registration packets may be sent. + */ +static void update_registrations( n2n_edge_t * eee ) { + /* REVISIT: BbMaj7: have shorter timeout to REGISTER to supernode if this has + * not yet succeeded. */ + + if(time(NULL) < (eee->last_register+REGISTER_FREQUENCY)) return; /* Too early */ + + traceEvent(TRACE_NORMAL, "Registering with supernode"); + if(eee->re_resolve_supernode_ip) { + supernode2addr(eee, eee->supernode_ip); + } + + send_register(eee, &(eee->supernode), 0); /* Register with supernode */ + + /* REVISIT: turn-on gratuitous ARP with config option. */ + /* send_grat_arps(sock_fd, is_udp_sock); */ + +#ifdef __ANDROID_NDK__ + if (eee->sn_wait) { + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_SUPERNODE_DISCONNECT ? 0 : 1; + g_status->running_status = EDGE_STAT_SUPERNODE_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } + } + eee->sn_wait = 1; +#endif /* #ifdef __ANDROID_NDK__ */ + + eee->last_register = time(NULL); +} + +/* ***************************************************** */ + +static int find_peer_destination(n2n_edge_t * eee, + const u_char *mac_address, + struct peer_addr *destination) { + const struct peer_info *scan = eee->known_peers; + macstr_t mac_buf; + ipstr_t ip_buf; + int retval=0; + + traceEvent(TRACE_INFO, "Searching destination peer for MAC %02X:%02X:%02X:%02X:%02X:%02X", + mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, + mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); + + while(scan != NULL) { + traceEvent(TRACE_INFO, "Evaluating peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X][ip=%s:%hu]", + scan->mac_addr[0] & 0xFF, scan->mac_addr[1] & 0xFF, scan->mac_addr[2] & 0xFF, + scan->mac_addr[3] & 0xFF, scan->mac_addr[4] & 0xFF, scan->mac_addr[5] & 0xFF, + intoa(ntohl(scan->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(scan->public_ip.port)); + + if((scan->last_seen > 0) && + (memcmp(mac_address, scan->mac_addr, 6) == 0)) + { + memcpy(destination, &scan->public_ip, sizeof(struct sockaddr_in)); + retval=1; + break; + } + scan = scan->next; + } + + if ( 0 == retval ) + { + memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); + } + + traceEvent(TRACE_INFO, "find_peer_address(%s) -> [socket=%s:%hu]", + macaddr_str( (char *)mac_address, mac_buf, sizeof(mac_buf)), + intoa(ntohl(destination->addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(destination->port)); + + return retval; +} + +/* *********************************************** */ + +static const struct option long_options[] = { + { "community", required_argument, NULL, 'c' }, + { "supernode-list", required_argument, NULL, 'l' }, + { "tun-device", required_argument, NULL, 'd' }, + { "euid", required_argument, NULL, 'u' }, + { "egid", required_argument, NULL, 'g' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +/* ***************************************************** */ + + +/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ +static void send_packet2net(n2n_edge_t * eee, + char *decrypted_msg, size_t len) { + ipstr_t ip_buf; + char packet[2048]; + int data_sent_len; + struct n2n_packet_header hdr; + struct peer_addr destination; + macstr_t mac_buf; + macstr_t mac2_buf; + struct ether_header *eh = (struct ether_header*)decrypted_msg; + + /* Discard IP packets that are not originated by this hosts */ + if(!(eee->allow_routing)) { + if(ntohs(eh->ether_type) == 0x0800) { + /* This is an IP packet from the local source address - not forwarded. */ +#define ETH_FRAMESIZE 14 +#define IP4_SRCOFFSET 12 + u_int32_t dst; + memcpy( &dst, &decrypted_msg[ETH_FRAMESIZE + IP4_SRCOFFSET], sizeof(dst) ); + + /* The following comparison works because device.ip_addr is stored in network order */ + if( dst != eee->device.ip_addr) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(dst), ip_buf, sizeof(ip_buf))); + return; + } else { + /* This packet is originated by us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + /* Encrypt "decrypted_msg" into the second half of the n2n packet. */ + len = TwoFishEncryptRaw((u_int8_t *)decrypted_msg, + (u_int8_t *)&packet[N2N_PKT_HDR_SIZE], len, eee->enc_tf); + + /* Add the n2n header to the start of the n2n packet. */ + fill_standard_header_fields( &(eee->sinfo), &hdr, (char*)(eee->device.mac_addr) ); + hdr.msg_type = MSG_TYPE_PACKET; + hdr.sent_by_supernode = 0; + memcpy(hdr.community_name, eee->community_name, COMMUNITY_LEN); + memcpy(hdr.dst_mac, decrypted_msg, 6); + + marshall_n2n_packet_header( (u_int8_t *)packet, &hdr ); + + len += N2N_PKT_HDR_SIZE; + + if(find_peer_destination(eee, eh->ether_dhost, &destination)) + traceEvent(TRACE_INFO, "** Going direct [dst_mac=%s][dest=%s:%hu]", + macaddr_str((char*)eh->ether_dhost, mac_buf, sizeof(mac_buf)), + intoa(ntohl(destination.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(destination.port)); + else + traceEvent(TRACE_INFO, " Going via supernode [src_mac=%s][dst_mac=%s]", + macaddr_str((char*)eh->ether_shost, mac_buf, sizeof(mac_buf)), + macaddr_str((char*)eh->ether_dhost, mac2_buf, sizeof(mac2_buf))); + + data_sent_len = reliable_sendto( &(eee->sinfo), packet, &len, &destination, + N2N_COMPRESSION_ENABLED); + + if(data_sent_len != len) + traceEvent(TRACE_WARNING, "sendto() [sent=%d][attempted_to_send=%d] [%s]\n", + data_sent_len, len, strerror(errno)); + else { + ++(eee->pkt_sent); + traceEvent(TRACE_INFO, "Sent %d byte MSG_TYPE_PACKET ok", data_sent_len); + } +} + +/* ***************************************************** */ + +/** Destination MAC 33:33:0:00:00:00 - 33:33:FF:FF:FF:FF is reserved for IPv6 + * neighbour discovery. + */ +int is_ip6_discovery( const void * buf, size_t bufsize ) +{ + int retval = 0; + + if ( bufsize >= sizeof(struct ether_header) ) + { + struct ether_header *eh = (struct ether_header*)buf; + if ( (0x33 == eh->ether_dhost[0]) && + (0x33 == eh->ether_dhost[1]) ) + { + retval = 1; /* This is an IPv6 neighbour discovery packet. */ + } + } + return retval; +} + + +/* ***************************************************** */ + +/* + * Return: 0 = ok, -1 = invalid packet + * + */ +static int check_received_packet(n2n_edge_t * eee, char *pkt, + u_int pkt_len) { + + if(pkt_len == 42) { + /* ARP */ + if((pkt[12] != 0x08) || (pkt[13] != 0x06)) return(0); /* No ARP */ + if((pkt[20] != 0x00) || (pkt[21] != 0x02)) return(0); /* No ARP Reply */ + if(memcmp(&pkt[28], &(eee->device.ip_addr), 4)) return(0); /* This is not me */ + + if(memcmp(eee->device.mac_addr, &pkt[22], 6) == 0) { + traceEvent(TRACE_WARNING, "Bounced packet received: supernode bug?"); + return(0); + } + + traceEvent(TRACE_ERROR, "Duplicate address found. Your IP is used by MAC %02X:%02X:%02X:%02X:%02X:%02X", + pkt[22+0] & 0xFF, pkt[22+1] & 0xFF, pkt[22+2] & 0xFF, + pkt[22+3] & 0xFF, pkt[22+4] & 0xFF, pkt[22+5] & 0xFF); + exit(0); + } else if(pkt_len > 32 /* IP + Ethernet */) { + /* Check if this packet is for us or if it's routed */ + struct ether_header *eh = (struct ether_header*)pkt; + + const struct in_addr bcast = { 0xffffffff }; + + if(ntohs(eh->ether_type) == 0x0800) { + + /* Note: all elements of the_ip are in network order */ + struct ip the_ip; + memcpy( &the_ip, pkt+sizeof(struct ether_header), sizeof(the_ip) ); + + if((the_ip.ip_dst.s_addr != eee->device.ip_addr) + && ((the_ip.ip_dst.s_addr & eee->device.device_mask) != (eee->device.ip_addr & eee->device.device_mask)) /* Not a broadcast */ + && ((the_ip.ip_dst.s_addr & 0xE0000000) != (0xE0000000 /* 224.0.0.0-239.255.255.255 */)) /* Not a multicast */ + && ((the_ip.ip_dst.s_addr) != (bcast.s_addr)) /* always broadcast (RFC919) */ + && (!(eee->allow_routing)) /* routing is enabled so let it in */ + ) + { + /* Dropping the packet */ + + ipstr_t ip_buf; + ipstr_t ip_buf2; + + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [rcvd=%s][expected=%s]", + intoa(ntohl(the_ip.ip_dst.s_addr), ip_buf, sizeof(ip_buf)), + intoa(ntohl(eee->device.ip_addr), ip_buf2, sizeof(ip_buf2))); + } else { + /* This packet is for us */ + + /* traceEvent(TRACE_INFO, "Received non-routed packet"); */ + return(0); + } + } else + return(0); + } else { + traceEvent(TRACE_INFO, "Packet too short (%d bytes): discarded", pkt_len); + } + + return(-1); +} + +/* ***************************************************** */ + +/** Read a single packet from the TAP interface, process it and write out the + * corresponding packet to the cooked socket. + * + * REVISIT: fails if more than one packet is waiting to be read. + */ +static void readFromTAPSocket( n2n_edge_t * eee ) +{ + /* tun -> remote */ + u_char decrypted_msg[2048]; + size_t len; + +#ifdef __ANDROID_NDK__ + if (uip_arp_len != 0) { + len = uip_arp_len; + memcpy(decrypted_msg, uip_arp_buf, MIN(uip_arp_len, sizeof(decrypted_msg))); + traceEvent(TRACE_NORMAL, "ARP reply packet to send"); + } + else + { +#endif /* #ifdef __ANDROID_NDK__ */ + len = tuntap_read(&(eee->device), decrypted_msg, sizeof(decrypted_msg)); +#ifdef __ANDROID_NDK__ + } +#endif /* #ifdef __ANDROID_NDK__ */ + + if((len <= 0) || (len > sizeof(decrypted_msg))) + traceEvent(TRACE_WARNING, "read()=%d [%d/%s]\n", + len, errno, strerror(errno)); + else { + traceEvent(TRACE_INFO, "### Rx L2 Msg (%d) tun -> network", len); + + if ( eee->drop_ipv6_ndp && is_ip6_discovery( decrypted_msg, len ) ) { + traceEvent(TRACE_WARNING, "Dropping unsupported IPv6 neighbour discovery packet"); + } else { + send_packet2net(eee, (char*)decrypted_msg, len); + } + } +} + +/* ***************************************************** */ + + +void readFromIPSocket( n2n_edge_t * eee ) +{ + ipstr_t ip_buf; + macstr_t mac_buf; + char packet[2048], decrypted_msg[2048]; + size_t len; + int data_sent_len; + struct peer_addr sender; + + /* remote -> tun */ + u_int8_t discarded_pkt; + struct n2n_packet_header hdr_storage; + + len = receive_data( &(eee->sinfo), packet, sizeof(packet), &sender, + &discarded_pkt, (char*)(eee->device.mac_addr), + N2N_COMPRESSION_ENABLED, &hdr_storage); + + if(len <= 0) return; + + traceEvent(TRACE_INFO, "### Rx N2N Msg network -> tun"); + + if(discarded_pkt) { + traceEvent(TRACE_INFO, "Discarded incoming pkt"); + } else { + if(len <= 0) + traceEvent(TRACE_WARNING, "receive_data()=%d [%s]\n", len, strerror(errno)); + else { + if(len < N2N_PKT_HDR_SIZE) + traceEvent(TRACE_WARNING, "received packet too short [len=%d]\n", len); + else { + struct n2n_packet_header *hdr = &hdr_storage; + + traceEvent(TRACE_INFO, "Received packet from %s:%hu", + intoa(ntohl(sender.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(sender.port)); + + traceEvent(TRACE_INFO, "Received message [msg_type=%s] from %s [dst mac=%s]", + msg_type2str(hdr->msg_type), + hdr->sent_by_supernode ? "supernode" : "peer", + macaddr_str(hdr->dst_mac, mac_buf, sizeof(mac_buf))); + + if(hdr->version != N2N_PKT_VERSION) { + traceEvent(TRACE_WARNING, + "Received packet with unknown protocol version (%d): discarded\n", + hdr->version); + return; + } + + /* FIX - Add IPv6 support */ + if(hdr->public_ip.addr_type.v4_addr == 0) { + hdr->public_ip.addr_type.v4_addr = sender.addr_type.v4_addr; + hdr->public_ip.port = sender.port; + hdr->public_ip.family = AF_INET; + } + + if(strncmp(hdr->community_name, eee->community_name, COMMUNITY_LEN) != 0) { + traceEvent(TRACE_WARNING, "Received packet with invalid community [expected=%s][received=%s]\n", + eee->community_name, hdr->community_name); + } else { + if(hdr->msg_type == MSG_TYPE_PACKET) { + /* assert: the packet received is destined for device.mac_addr or broadcast MAC. */ + + len -= N2N_PKT_HDR_SIZE; + + /* Decrypt message first */ + len = TwoFishDecryptRaw((u_int8_t *)&packet[N2N_PKT_HDR_SIZE], + (u_int8_t *)decrypted_msg, len, eee->dec_tf); + + if(len > 0) { + if(check_received_packet(eee, decrypted_msg, len) == 0) { + + if ( 0 == memcmp(hdr->dst_mac, eee->device.mac_addr, 6) ) + { + check_peer( eee, hdr ); + } + + data_sent_len = tuntap_write(&(eee->device), (u_char*)decrypted_msg, len); + + if(data_sent_len != len) + traceEvent(TRACE_WARNING, "tuntap_write() [sent=%d][attempted_to_send=%d] [%s]\n", + data_sent_len, len, strerror(errno)); + else { + /* Normal situation. */ + traceEvent(TRACE_INFO, "### Tx L2 Msg -> tun"); + } + } else { + traceEvent(TRACE_WARNING, "Bad destination: message discarded"); + } + } + /* else silently ignore empty packet. */ + + } else if(hdr->msg_type == MSG_TYPE_REGISTER) { + traceEvent(TRACE_INFO, "Received registration request from remote peer [ip=%s:%hu]", + intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(hdr->public_ip.port)); + if ( 0 == memcmp(hdr->dst_mac, (eee->device.mac_addr), 6) ) + { + check_peer( eee, hdr ); + } + + + send_register(eee, &hdr->public_ip, 1); /* Send ACK back */ + } else if(hdr->msg_type == MSG_TYPE_REGISTER_ACK) { + traceEvent(TRACE_NORMAL, "Received REGISTER_ACK from remote peer [ip=%s:%hu]", + intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(hdr->public_ip.port)); + + /* if ( 0 == memcmp(hdr->dst_mac, eee->device.mac_addr, 6) ) */ + { + if ( hdr->sent_by_supernode ) + { + /* Response to supernode registration. Supernode is not in the pending_peers list. */ +#ifdef __ANDROID_NDK__ + eee->sn_wait = 0; + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1; + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } +#endif /* #ifdef __ANDROID_NDK__ */ + } + else + { + /* Move from pending_peers to known_peers; ignore if not in pending. */ + set_peer_operational( eee, hdr ); + } + } + + } else { + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored\n", hdr->msg_type); + return; + } + } + } + } + } +} + +/* ***************************************************** */ + + +#ifdef WIN32 +static DWORD tunReadThread(LPVOID lpArg ) +{ + n2n_edge_t *eee = (n2n_edge_t*)lpArg; + + while(1) { + readFromTAPSocket(eee); + } + + return((DWORD)NULL); +} + +/* ***************************************************** */ + +static void startTunReadThread(n2n_edge_t *eee) { + HANDLE hThread; + DWORD dwThreadId; + + hThread = CreateThread(NULL, /* no security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ + (void*)eee, /* argument to thread function */ + 0, /* use default creation flags */ + &dwThreadId); /* returns the thread identifier */ +} +#endif + +/* ***************************************************** */ + +static void supernode2addr(n2n_edge_t * eee, char* addr) { + char tmpAddr[N2N_EDGE_SN_HOST_SIZE]; + memcpy(tmpAddr, addr, N2N_EDGE_SN_HOST_SIZE); + char *supernode_host = strtok(tmpAddr, ":"); + + if(supernode_host) { + char *supernode_port = strtok(NULL, ":"); + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + int nameerr; + ipstr_t ip_buf; + + if ( supernode_port ) + eee->supernode.port = htons(atoi(supernode_port)); + else + traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ): %s", + addr); + + nameerr = getaddrinfo( supernode_host, NULL, &aihints, &ainfo ); + + if( 0 == nameerr ) + { + struct sockaddr_in * saddr; + + /* ainfo s the head of a linked list if non-NULL. */ + if ( ainfo && (PF_INET == ainfo->ai_family) ) + { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + + eee->supernode.addr_type.v4_addr = saddr->sin_addr.s_addr; + } + else + { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); + } + + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + ainfo = NULL; + } else { + traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s, assuming numeric", supernode_host); + eee->supernode.addr_type.v4_addr = inet_addr(supernode_host); + } + + traceEvent(TRACE_NORMAL, "Using supernode %s:%hu", + intoa(ntohl(eee->supernode.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(eee->supernode.port)); + } else + traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); +} + +/* ***************************************************** */ + +extern int useSyslog; +#ifdef __ANDROID_NDK__ +static int keep_running = 1; +#endif /* #ifdef __ANDROID_NDK__ */ + +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ + +#ifndef __ANDROID_NDK__ +int main(int argc, char* argv[]) { + int opt=0; + u_int16_t local_port = 0 /* any port */; + char *tuntap_dev_name = "edge0"; + char *ip_addr = NULL; + char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; + int mtu = DEFAULT_MTU; + int got_s = 0; + +#ifndef WIN32 + uid_t userid=0; /* root is the only guaranteed ID */ + gid_t groupid=0; /* root is the only guaranteed ID */ + int fork_as_daemon=0; +#endif + + size_t numPurged; + time_t lastStatus=0; + + char * device_mac=NULL; + char * encrypt_key=NULL; + + int i, effectiveargc=0; + char ** effectiveargv=NULL; + char * linebuffer = NULL; + + n2n_edge_t eee; /* single instance for this program */ + + if (-1 == edge_init(&eee) ){ + traceEvent( TRACE_ERROR, "Failed in edge_init" ); + exit(1); + } + + if( getenv( "N2N_KEY" )) { + encrypt_key = strdup( getenv( "N2N_KEY" )); + } + +#ifdef WIN32 + tuntap_dev_name = ""; +#endif + memset(&(eee.supernode), 0, sizeof(eee.supernode)); + eee.supernode.family = AF_INET; + + linebuffer = (char *)malloc(MAX_CMDLINE_BUFFER_LENGTH); + if (!linebuffer) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + exit(1); + } + snprintf(linebuffer, MAX_CMDLINE_BUFFER_LENGTH, "%s",argv[0]); + +#ifdef WIN32 + for(i=0; i COMMUNITY_LEN) + eee.community_name[COMMUNITY_LEN] = '\0'; + break; +#ifndef WIN32 + + case 'u': /* uid */ + { + userid = atoi(optarg); + break; + } + case 'g': /* uid */ + { + groupid = atoi(optarg); + break; + } + case 'f' : /* fork as daemon */ + { + fork_as_daemon = 1; + break; + } +#endif + case 'm' : /* device_mac */ + { + device_mac = strdup(optarg); + break; + } + case 'M' : /* device_mac */ + { + mtu = atoi(optarg); + break; + } + case 'k': /* encrypt key */ + encrypt_key = strdup(optarg); + break; + case 'r': /* enable packet routing across n2n endpoints */ + eee.allow_routing = 1; + break; + case 'l': /* supernode-list */ + snprintf(eee.supernode_ip, sizeof(eee.supernode_ip), "%s", optarg); + supernode2addr(&eee, eee.supernode_ip); + break; +#ifdef __linux__ + case 'd': /* tun-device */ + tuntap_dev_name = strdup(optarg); + break; +#endif + case 't': /* Use HTTP tunneling */ + eee.sinfo.is_udp_socket = 0; + break; + case 'b': + eee.re_resolve_supernode_ip = 1; + break; + case 'p': + local_port = atoi(optarg) & 0xffff; + break; + case 's': /* Subnet Mask */ + if (0 != got_s) { + traceEvent(TRACE_WARNING, "Multiple subnet masks supplied."); + } + strncpy(netmask, optarg, N2N_NETMASK_STR_SIZE); + got_s = 1; + break; + case 'h': /* help */ + help(); + break; + case 'v': /* verbose */ + traceLevel = 3; + break; + } + } + + if(!( +#ifdef __linux__ + tuntap_dev_name && +#endif + eee.community_name && + ip_addr && + eee.supernode.addr_type.v4_addr && + encrypt_key)) + help(); + +#ifndef WIN32 + /* If running suid root then we need to setuid before using the force. */ + setuid( 0 ); + /* setgid( 0 ); */ +#endif + + if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, netmask, device_mac, mtu) < 0) + return(-1); + +#ifndef WIN32 + if ( (userid != 0) || (groupid != 0 ) ) { + traceEvent(TRACE_NORMAL, "Interface up. Dropping privileges to uid=%d, gid=%d", userid, groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + setreuid( userid, userid ); + setregid( groupid, groupid ); + } +#endif + + if(local_port > 0) + traceEvent(TRACE_NORMAL, "Binding to local port %hu", local_port); + + if(edge_init_twofish( &eee, (u_int8_t *)(encrypt_key), strlen(encrypt_key) ) < 0) return(-1); + eee.sinfo.sock = open_socket(local_port, eee.sinfo.is_udp_socket, 0); + if(eee.sinfo.sock < 0) return(-1); + + if( !(eee.sinfo.is_udp_socket) ) { + int rc = connect_socket(eee.sinfo.sock, &(eee.supernode)); + + if(rc == -1) { + traceEvent(TRACE_WARNING, "Error while connecting to supernode\n"); + return(-1); + } + } + +#ifndef WIN32 + if ( fork_as_daemon ) + { + useSyslog=1; /* traceEvent output now goes to syslog. */ + daemon( 0, 0 ); + } +#endif +#else /* #ifdef __ANDROID_NDK__ */ +int start_edge_v1(n2n_edge_status_t* status) { + u_int16_t local_port = 0 /* any port */; + char *tuntap_dev_name = "tun0"; + char ip_addr[N2N_NETMASK_STR_SIZE]=""; + char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; + char device_mac[18]=""; + char *encrypt_key=NULL; + int mgmt_sock = -1; + + size_t numPurged; + time_t lastStatus=0; + + n2n_edge_t eee; /* single instance for this program */ + + if (!status) + { + traceEvent( TRACE_ERROR, "Empty cmd struct" ); + return 1; + } + g_status = status; + n2n_edge_cmd_t* cmd = &status->cmd; + + keep_running = 0; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTING; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + traceLevel = cmd->trace_vlevel; + traceLevel = traceLevel < 0 ? 0 : traceLevel; /* TRACE_ERROR */ + traceLevel = traceLevel > 3 ? 3 : traceLevel; /* TRACE_INFO */ + if (!slog) + { + closeslog(slog); + slog = NULL; + } + slog = initslog(android_log_level(traceLevel), cmd->logpath); + + if (-1 == edge_init(&eee) ) + { + traceEvent( TRACE_ERROR, "Failed in edge_init" ); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + memset(&(eee.supernode), 0, sizeof(eee.supernode)); + eee.supernode.family = AF_INET; + + if (cmd->vpn_fd < 0) { + traceEvent(TRACE_ERROR, "VPN socket is invalid."); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + eee.device.fd = cmd->vpn_fd; + if (cmd->enc_key) + { + encrypt_key = strdup(cmd->enc_key); + traceEvent(TRACE_NORMAL, "encrypt_key = '%s'\n", encrypt_key); + } + if (cmd->ip_addr[0] != '\0') + { + strncpy(ip_addr, cmd->ip_addr, N2N_NETMASK_STR_SIZE); + ip_addr[N2N_NETMASK_STR_SIZE - 1] = '\0'; + } + else + { + traceEvent(TRACE_ERROR, "Ip address is not set."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if (cmd->community[0] != '\0') + { + eee.community_name = cmd->community; + } + else + { + traceEvent(TRACE_ERROR, "Community is not set."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if (cmd->mac_addr[0] != '\0') + { + strncpy(device_mac, cmd->mac_addr, sizeof(device_mac)); + device_mac[sizeof(device_mac) - 1] = '\0'; + } + else + { + strncpy(device_mac, random_device_mac(), sizeof(device_mac)); + traceEvent(TRACE_NORMAL, "random device mac: %s\n", device_mac); + } + eee.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + if (cmd->supernodes[0][0] != '\0') + { + strncpy(eee.supernode_ip, cmd->supernodes[0], N2N_EDGE_SN_HOST_SIZE); + eee.supernode_ip[N2N_EDGE_SN_HOST_SIZE - 1] = '\0'; + } + else + { + traceEvent(TRACE_ERROR, "Supernode is not set."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + eee.re_resolve_supernode_ip = cmd->re_resolve_supernode_ip == 0 ? 0 : 1; + if (cmd->ip_netmask[0] != '\0') + { + strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); + } + local_port = cmd->local_port; + eee.sinfo.is_udp_socket = cmd->http_tunnel == 0 ? 1 : 0; + + supernode2addr(&eee, eee.supernode_ip); + if (!eee.supernode.addr_type.v4_addr) + { + traceEvent(TRACE_ERROR, "Supernode is not resolved."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if(tuntap_open(&(eee.device), tuntap_dev_name, ip_addr, netmask, device_mac, cmd->mtu) < 0) + { + traceEvent(TRACE_ERROR, "Failed in tuntap_open"); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if(local_port > 0) + { + traceEvent(TRACE_NORMAL, "Binding to local port %hu", local_port); + } + + if(edge_init_twofish( &eee, (u_int8_t *)(encrypt_key), encrypt_key ? strlen(encrypt_key) : 0 ) < 0) + { + traceEvent(TRACE_ERROR, "twofish init failed."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + free(encrypt_key); + eee.sinfo.sock = open_socket(local_port, eee.sinfo.is_udp_socket, 0); + if(eee.sinfo.sock < 0) + { + traceEvent(TRACE_ERROR, "Failed to bind main socket port %u", (signed int)local_port); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if(!eee.sinfo.is_udp_socket) + { + int rc = connect_socket(eee.sinfo.sock, &(eee.supernode)); + if(rc == -1) { + traceEvent(TRACE_WARNING, "Error while connecting to supernode\n"); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + } + mgmt_sock = open_socket(N2N_EDGE_MGMT_PORT, 1, 0); + if (mgmt_sock < 0) + { + traceEvent(TRACE_ERROR, "Failed to bind management socket port %u", (signed int)N2N_EDGE_MGMT_PORT); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + + /* set host addr, netmask, mac addr for UIP and init arp*/ + { + int match, i; + int ip[4]; + uip_ipaddr_t ipaddr; + struct uip_eth_addr eaddr; + + match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_sethostaddr(ipaddr); + match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_setnetmask(ipaddr); + for (i = 0; i < 6; ++i) { + eaddr.addr[i] = eee.device.mac_addr[i]; + } + uip_setethaddr(eaddr); + + uip_arp_init(); + } + + keep_running = 1; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + traceEvent(TRACE_NORMAL, "edge started"); + +#endif /* #ifdef __ANDROID_NDK__ */ + + update_registrations(&eee); + + traceEvent(TRACE_NORMAL, ""); + traceEvent(TRACE_NORMAL, "Ready"); + +#ifdef WIN32 + startTunReadThread(&eee); +#endif + + /* Main loop + * + * select() is used to wait for input on either the TAP fd or the UDP/TCP + * socket. When input is present the data is read and processed by either + * readFromIPSocket() or readFromTAPSocket() + */ + +#ifdef __ANDROID_NDK__ + time_t lastArpPeriod=0; +#endif + +#ifdef __ANDROID_NDK__ + keep_running = 1; + while(keep_running) { +#else + while (1) { +#endif /* #ifdef __ANDROID_NDK__ */ + + int rc, max_sock = 0; + fd_set socket_mask; + struct timeval wait_time; + time_t nowTime; + + FD_ZERO(&socket_mask); + FD_SET(eee.sinfo.sock, &socket_mask); +#ifndef WIN32 + FD_SET(eee.device.fd, &socket_mask); + max_sock = max( eee.sinfo.sock, eee.device.fd ); +#endif +#ifdef __ANDROID_NDK__ + FD_SET(mgmt_sock, &socket_mask); + max_sock = max(max_sock, mgmt_sock); +#endif /* #ifdef __ANDROID_NDK__ */ + + wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS; wait_time.tv_usec = 0; + + rc = select(max_sock+1, &socket_mask, NULL, NULL, &wait_time); + nowTime=time(NULL); + + if(rc > 0) + { + /* Any or all of the FDs could have input; check them all. */ + + if(FD_ISSET(eee.sinfo.sock, &socket_mask)) + { + /* Read a cooked socket from the internet socket. Writes on the TAP + * socket. */ + readFromIPSocket(&eee); + } + +#ifdef __ANDROID_NDK__ + if (uip_arp_len != 0) { + readFromTAPSocket(&eee); + uip_arp_len = 0; + } +#endif /* #ifdef __ANDROID_NDK__ */ + +#ifndef WIN32 + if(FD_ISSET(eee.device.fd, &socket_mask)) + { + /* Read an ethernet frame from the TAP socket. Write on the IP + * socket. */ + readFromTAPSocket(&eee); + } +#endif + +#ifdef __ANDROID_NDK__ + if (FD_ISSET(mgmt_sock, &socket_mask)) + { + keep_running = 0; + } +#endif /* #ifdef __ANDROID_NDK__ */ + + } + + update_registrations(&eee); + + numPurged = purge_expired_registrations( &(eee.known_peers) ); + numPurged += purge_expired_registrations( &(eee.pending_peers) ); + if ( numPurged > 0 ) + { + traceEvent( TRACE_NORMAL, "Peer removed: pending=%ld, operational=%ld", + peer_list_size( eee.pending_peers ), peer_list_size( eee.known_peers ) ); + } + + if ( ( nowTime - lastStatus ) > STATUS_UPDATE_INTERVAL ) + { + lastStatus = nowTime; + + traceEvent( TRACE_NORMAL, "STATUS: pending=%ld, operational=%ld", + peer_list_size( eee.pending_peers ), peer_list_size( eee.known_peers ) ); + } + +#ifdef __ANDROID_NDK__ + if ((nowTime - lastArpPeriod) > ARP_PERIOD_INTERVAL) { + uip_arp_timer(); + lastArpPeriod = nowTime; + } +#endif /* #ifdef __ANDROID_NDK__ */ + } /* while */ + + send_deregister( &eee, &(eee.supernode)); + + closesocket(eee.sinfo.sock); +#ifdef __ANDROID_NDK__ + closesocket(mgmt_sock); +#endif /* #ifdef __ANDROID_NDK__ */ + tuntap_close(&(eee.device)); + +#ifdef __ANDROID_NDK__ + traceEvent(TRACE_NORMAL, "Edge stoped."); + if (!slog) { + closeslog(slog); + slog = NULL; + } +#endif /* #ifdef __ANDROID_NDK__ */ + + edge_deinit( &eee ); + + return(0); +} + +#ifdef __ANDROID_NDK__ +int stop_edge_v1(void) +{ + keep_running = 0; + + // quick stop + int fd = open_socket(0, 1, 0); + if (fd < 0) { + return 1; + } + + struct sockaddr_in peer_addr; + peer_addr.sin_family = PF_INET; + peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT); + sendto(fd, "", 1, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in)); + close(fd); + + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + return 0; +} +#endif /* #ifdef __ANDROID_NDK__ */ diff --git a/bundles/n2n_meyerd/n2n_v1/lzoconf.h b/bundles/n2n_meyerd/n2n_v1/lzoconf.h new file mode 100644 index 00000000..cc437f1e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/lzoconf.h @@ -0,0 +1,417 @@ +/* lzoconf.h -- configuration for the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED + +#define LZO_VERSION 0x2030 +#define LZO_VERSION_STRING "2.03" +#define LZO_VERSION_DATE "Apr 30 2008" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +#if !defined(LZO_UINT32_C) +# if (UINT_MAX < LZO_0xffffffffL) +# define LZO_UINT32_C(c) c ## UL +# else +# define LZO_UINT32_C(c) ((c) + 0U) +# endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint should match size_t */ +#if !defined(LZO_UINT_MAX) +# if defined(LZO_ABI_LLP64) /* WIN64 */ +# if defined(LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# else + typedef unsigned long long lzo_uint; + typedef long long lzo_int; +# endif +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* Integral types with 32 bits or more. */ +#if !defined(LZO_UINT32_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint32; + typedef int lzo_int32; +# define LZO_UINT32_MAX UINT_MAX +# define LZO_INT32_MAX INT_MAX +# define LZO_INT32_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint32; + typedef long lzo_int32; +# define LZO_UINT32_MAX ULONG_MAX +# define LZO_INT32_MAX LONG_MAX +# define LZO_INT32_MIN LONG_MIN +# else +# error "lzo_uint32" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32. */ +#if (LZO_UINT_MAX >= LZO_UINT32_MAX) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32 +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +# if (LZO_UINT_MAX <= UINT_MAX) +# define __LZO_MMODEL +# elif defined(LZO_HAVE_MM_HUGE_PTR) +# define __LZO_MMODEL_HUGE 1 +# define __LZO_MMODEL __huge +# else +# define __LZO_MMODEL +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_uint32p lzo_uint32 __LZO_MMODEL * +#define lzo_int32p lzo_int32 __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * +/* deprecated - use `lzo_bytep' instead of `lzo_byte *' */ +#define lzo_byte unsigned char __LZO_MMODEL + +typedef int lzo_bool; + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) +lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) +lzo_adler32(lzo_uint32 _adler, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(lzo_uint32) +lzo_crc32(lzo_uint32 _c, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(const lzo_uint32p) +lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of `size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); +#define LZO_PTR_ALIGN_UP(_ptr,_size) \ + ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility with LZO v1.xx +************************************************************************/ + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL +#define __LZO_DMODEL +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_meyerd/n2n_v1/lzodefs.h b/bundles/n2n_meyerd/n2n_v1/lzodefs.h new file mode 100644 index 00000000..18056372 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/lzodefs.h @@ -0,0 +1,1807 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif /* already included */ + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_meyerd/n2n_v1/minilzo.c b/bundles/n2n_meyerd/n2n_v1/minilzo.c new file mode 100644 index 00000000..6a62b31b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/minilzo.c @@ -0,0 +1,4112 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO +#define LZO_BUILD + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2030) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +# define ACC_LIBC_FREESTANDING 1 +# define ACC_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# define ACC_CFG_NO_UNALIGNED 1 +#endif +#if defined(LZO_ARCH_GENERIC) +# define ACC_ARCH_GENERIC 1 +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# define ACC_ABI_NEUTRAL_ENDIAN 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define ACC_CONFIG_NO_HEADER 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#endif + +#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_BORLANDC && LZO_ARCH_I086) +# pragma option -h +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +# pragma warning(disable: 4514 4710 4711) +#endif + +#if (LZO_CC_SUNPROC) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +#endif + +#if defined(__LZO_MMODEL_HUGE) && (!LZO_HAVE_MM_HUGE_PTR) +# error "this should not happen - check defines for __huge" +#endif + +#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define ACC_WANT_ACC_INCD_H 1 +# define ACC_WANT_ACC_INCE_H 1 +# define ACC_WANT_ACC_INCI_H 1 +#elif 1 +# include +#else +# define ACC_WANT_ACC_INCD_H 1 +#endif + +#if (LZO_ARCH_I086) +# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT +# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) +# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) +# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) +# define __LZO_UINTPTR_T_IS_POINTER 1 + typedef char* lzo_uintptr_t; +# define lzo_uintptr_t lzo_uintptr_t +# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t size_t +# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long +# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned int +# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long long +# else +# define lzo_uintptr_t size_t +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if defined(LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !defined(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !defined(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !defined(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !defined(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if defined(LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if !defined(__lzo_inline) +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +# define __lzo_noinline +#endif + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#if 1 && !defined(LZO_CFG_NO_UNALIGNED) +#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if (LZO_SIZEOF_SHORT == 2) +# define LZO_UNALIGNED_OK_2 +# endif +# if (LZO_SIZEOF_INT == 4) +# define LZO_UNALIGNED_OK_4 +# endif +#endif +#endif + +#if defined(LZO_UNALIGNED_OK_2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2) +#endif +#if defined(LZO_UNALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#elif defined(LZO_ALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +__LZO_EXTERN_C int __lzo_init_done; +__LZO_EXTERN_C const char __lzo_copyright[]; +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# else +# define lzo_uintptr_t acc_uintptr_t +# ifdef __ACC_INTPTR_T_IS_POINTER +# define __LZO_UINTPTR_T_IS_POINTER 1 +# endif +# endif +#endif + +#if (LZO_ARCH_I086) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#elif (LZO_MM_PVP) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) +#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#define LZO_DETERMINISTIC + +#define LZO_DICT_USE_PTR +#if 0 && (LZO_ARCH_I086) +# undef LZO_DICT_USE_PTR +#endif + +#if defined(LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) + p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#elif (LZO_MM_PVP) + p = (lzo_uintptr_t) (ptr); + p = (p << 3) | (p >> 61); +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if defined(__LZO_UINTPTR_T_IS_POINTER) + size_t n = (size_t) ptr; + n = (((n + size - 1) / size) * size) - n; +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Built: " __DATE__ " " __TIME__ " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ +#if (LZO_OS_DOS16 && LZO_CC_TURBOC) + return (lzo_voidp) __lzo_copyright; +#else + return (const lzo_bytep) __lzo_copyright; +#endif +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCMP) + const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCPY) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMMOVE) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMSET) + lzo_hbyte_p p = (lzo_hbyte_p) s; + if __lzo_likely(len > 0) do + *p++ = (unsigned char) c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, c, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif + +#if !defined(__LZO_IN_MINILZO) + +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) + ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) + +#if !defined(__LZO_UINTPTR_T_IS_POINTER) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) + ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + +#endif +#undef ACCCHK_ASSERT + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + union { unsigned char c[2*sizeof(lzo_xint)]; lzo_xint l[2]; } u; + lzo_uintptr_t p; + +#if !defined(LZO_CFG_NO_CONFIG_CHECK) +#if defined(LZO_ABI_BIG_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[sizeof(lzo_xint) - 1] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_ABI_LITTLE_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[0] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_UNALIGNED_OK_2) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_ushortp) (p+1)) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_4) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_uint32p) (p+1)) == 0); +#endif +#endif + + LZO_UNUSED(u); LZO_UNUSED(p); + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +int __lzo_init_done = 0; + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT +#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef ACCCHK_ASSERT + + __lzo_init_done = 1; + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#define do_compress _lzo1x_1_do_compress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#define LZO_NEED_DICT_H +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 8 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 8 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if defined(LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_uint) ((p)-(in))) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if defined(LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) <= 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if defined(LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define DO_COMPRESS lzo1x_1_compress + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + register const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - M2_MAX_LEN - 5; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += 4; + for (;;) + { + register const lzo_bytep m_pos; + lzo_uint m_off; + lzo_uint m_len; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } + else + { + if __lzo_likely(m_pos[2] == ip[2]) + { +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) + { + assert(op - 2 > out); op[-2] |= LZO_BYTE(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (m_pos[3] == ip[3]) +#endif + goto match; + } + else + { +#if 0 +#if 0 + if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else + if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif + { + register lzo_uint t; + + t = lit; + assert(op - 2 > out); op[-2] |= LZO_BYTE(t); + do *op++ = *ii++; while (--t > 0); + assert(ii == ip); + m_off -= 1; + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); + ip += 2; + goto match_done; + } +#endif + } + } + +literal: + UPDATE_I(dict,0,dindex,ip,in); + ++ip; + if __lzo_unlikely(ip >= ip_end) + break; + continue; + +match: + UPDATE_I(dict,0,dindex,ip,in); + if (pd(ip,ii) > 0) + { + register lzo_uint t = pd(ip,ii); + + if (t <= 3) + { + assert(op - 2 > out); + op[-2] |= LZO_BYTE(t); + } + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + assert(ii == ip); + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ || + m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y + || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ + || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif + ) + { + --ip; + m_len = pd(ip, ii); + assert(m_len >= 3); assert(m_len <= M2_MAX_LEN); + + if (m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } + else +#if defined(LZO1X) + { + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + goto m3_m4_offset; + } +#elif defined(LZO1Y) + goto m4_match; +#endif + } + else + { + { + const lzo_bytep end = in_end; + const lzo_bytep m = m_pos + M2_MAX_LEN + 1; + while (ip < end && *m == *ip) + m++, ip++; + m_len = pd(ip, ii); + } + assert(m_len > M2_MAX_LEN); + + if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= 33) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } + else + { +#if defined(LZO1Y) +m4_match: +#endif + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11)); +m3_m4_len: + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + } + +m3_m4_offset: + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + +#if 0 +match_done: +#endif + ii = ip; + if __lzo_unlikely(ip >= ip_end) + break; + } + + *out_len = pd(op, out); + return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_bytep op = out; + lzo_uint t; + + if __lzo_unlikely(in_len <= M2_MAX_LEN + 5) + t = in_len; + else + { + t = do_compress(in,in_len,op,out_len,wrkmem); + op += *out_len; + } + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ + diff --git a/bundles/n2n_meyerd/n2n_v1/minilzo.h b/bundles/n2n_meyerd/n2n_v1/minilzo.h new file mode 100644 index 00000000..0aff50e4 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/minilzo.h @@ -0,0 +1,106 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H + +#define MINILZO_VERSION 0x2030 + +#ifdef __LZOCONF_H +# error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/bundles/n2n_meyerd/n2n_v1/n2n.c b/bundles/n2n_meyerd/n2n_v1/n2n.c new file mode 100644 index 00000000..2aee17ac --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/n2n.c @@ -0,0 +1,966 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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, see + * + * Code contributions courtesy of: + * Richard Andrews + * Massimo Torquati + * + */ + +#include "n2n.h" + +#include "minilzo.h" + +#include + +#if defined(DEBUG) +# define PURGE_REGISTRATION_FREQUENCY 60 +# define REGISTRATION_TIMEOUT 120 +#else /* #if defined(DEBUG) */ +# define PURGE_REGISTRATION_FREQUENCY 60 +# define REGISTRATION_TIMEOUT (60*5) +#endif /* #if defined(DEBUG) */ + + +char broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +char multicast_addr[6] = { 0x01, 0x00, 0x05, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */ + +/* ************************************** */ + +static void print_header( const char * msg, const struct n2n_packet_header * hdr ) +{ + ipstr_t buf; + ipstr_t buf2; + + traceEvent(TRACE_INFO, "%s hdr: public_ip=(%d)%s:%d, private_ip=(%d)%s:%d", msg, + hdr->public_ip.family, + intoa(ntohl(hdr->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(hdr->public_ip.port), + hdr->private_ip.family, + intoa(ntohl(hdr->private_ip.addr_type.v4_addr), buf2, sizeof(buf2)), + ntohs(hdr->private_ip.port) + ); +} + +/* *********************************************** */ + +extern void sockaddr_in2peer_addr(struct sockaddr_in *in, struct peer_addr *out) { + out->family = (u_int8_t)in->sin_family; + out->port = in->sin_port; + out->addr_type.v4_addr = in->sin_addr.s_addr; +} + +/* *********************************************** */ + +extern void peer_addr2sockaddr_in(const struct peer_addr *in, struct sockaddr_in *out) { + out->sin_family = in->family; + out->sin_port = in->port; + out->sin_addr.s_addr = in->addr_type.v4_addr; +} + +/* ************************************** */ + +static +int marshall_peer_addr( u_int8_t * buf, size_t * offset, const struct peer_addr * s ) +{ + /* RA: I'm pretty sure that this is broken. There is no guarantee that the + * peer_addr structure is packed. This will always work between like hosts but + * is almost certainly broken between different host types. */ + memcpy( buf + *offset, s, sizeof(struct peer_addr)); + *offset += sizeof(struct peer_addr); + + return sizeof(struct peer_addr); /* bytes written */ +} + +/* ************************************** */ + +static +int marshall_uint32( u_int8_t * buf, size_t * offset, u_int32_t val ) +{ + buf[*offset + 0] = ((val >> 24) & 0xff); + buf[*offset + 1] = ((val >> 16) & 0xff); + buf[*offset + 2] = ((val >> 8) & 0xff); + buf[*offset + 3] = ((val ) & 0xff); + + *offset += 4; + return 4; +} + +/* ************************************** */ + +int marshall_n2n_packet_header( u_int8_t * buf, const struct n2n_packet_header * hdr ) +{ + size_t offset = 0; + + print_header( "Marshalling ", hdr ); + + *(buf+offset) = hdr->version; + ++offset; + + *(buf+offset) = hdr->msg_type; + ++offset; + + *(buf+offset) = hdr->ttl; + ++offset; + + *(buf+offset) = hdr->sent_by_supernode; + ++offset; + + memcpy( buf+offset, hdr->community_name, COMMUNITY_LEN ); + offset += COMMUNITY_LEN; + + memcpy( buf+offset, hdr->src_mac, 6 ); + offset += 6; + + memcpy( buf+offset, hdr->dst_mac, 6 ); + offset += 6; + + marshall_peer_addr( buf, &offset, &(hdr->public_ip) ); + marshall_peer_addr( buf, &offset, &(hdr->private_ip) ); + + *(buf+offset) = (hdr->pkt_type & 0xff); + ++offset; + + marshall_uint32( buf, &offset, hdr->sequence_id ); + marshall_uint32( buf, &offset, hdr->crc ); + + return offset; +} + +/* ************************************** */ + +static +int unmarshall_peer_addr( struct peer_addr * s, size_t * offset, + const u_int8_t * buf ) +{ + memcpy(s, buf + *offset, sizeof(struct peer_addr)); + *offset += sizeof(struct peer_addr); + return (sizeof(struct peer_addr)); /* bytes written */ +} + +/* ************************************** */ + +static +int unmarshall_uint32( u_int32_t * val, size_t * offset, const u_int8_t * buf ) +{ + *val = ( (buf[*offset + 0] & 0xff) << 24 ); + *val |= ( (buf[*offset + 1] & 0xff) << 16 ); + *val |= ( (buf[*offset + 2] & 0xff) << 8 ); + *val |= ( (buf[*offset + 3] & 0xff) ); + + *offset += 4; + return 4; +} + +/* ************************************** */ + +int unmarshall_n2n_packet_header( struct n2n_packet_header * hdr, const u_int8_t * buf ) +{ + size_t offset=0; + + hdr->version = *(buf + offset); + ++offset; + + hdr->msg_type = *(buf + offset); + ++offset; + + hdr->ttl = *(buf + offset); + ++offset; + + hdr->sent_by_supernode = *(buf + offset); + ++offset; + + memcpy( hdr->community_name, (buf + offset), COMMUNITY_LEN ); + offset += COMMUNITY_LEN; + + memcpy( hdr->src_mac, (buf + offset), 6 ); + offset += 6; + + memcpy( hdr->dst_mac, (buf + offset), 6 ); + offset += 6; + + unmarshall_peer_addr( &(hdr->public_ip), &offset, buf ); + unmarshall_peer_addr( &(hdr->private_ip), &offset, buf ); + + hdr->pkt_type = (*(buf + offset) & 0xff); /* Make sure only 8 bits are copied. */ + ++offset; + + unmarshall_uint32( &(hdr->sequence_id), &offset, buf ); + unmarshall_uint32( &(hdr->crc), &offset, buf ); + + print_header( "Unmarshalled ", hdr ); + + return offset; +} + +/* ************************************** */ + +SOCKET open_socket(u_int16_t local_port, int udp_sock, int server_mode) { + SOCKET sock_fd; + struct sockaddr_in local_address; + int sockopt = 1; + + if((sock_fd = socket(PF_INET, udp_sock ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) { + traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", + strerror(errno), sock_fd); + return(-1); + } + +#ifndef WIN32 + /* fcntl(sock_fd, F_SETFL, O_NONBLOCK); */ +#endif + + setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); + + memset(&local_address, 0, sizeof(local_address)); + local_address.sin_family = AF_INET; + local_address.sin_port = htons(local_port); + local_address.sin_addr.s_addr = INADDR_ANY; + if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) { + traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); + return(-1); + } + + if((!udp_sock) && server_mode) { + if(listen(sock_fd, 255) == -1) { + traceEvent(TRACE_ERROR, "Listen error [%s]\n", strerror(errno)); + return(-1); + } + } + + return(sock_fd); +} + +/* ************************************** */ + +int connect_socket(int sock_fd, struct peer_addr* _dest) { + char *http_header; + int len, rc; + struct sockaddr_in dest; + + peer_addr2sockaddr_in(_dest, &dest); + + /* FIX: add IPv6 support */ + rc = connect(sock_fd, (struct sockaddr*)&dest, sizeof(struct sockaddr_in)); + + if(rc == -1) { + traceEvent(TRACE_WARNING, "connect() error [%s]\n", strerror(errno)); + return(-1); + } + + /* Send dummy http header */ + http_header = "GET / HTTP/1.0\r\n\r\n"; + len = strlen(http_header); + rc = send(sock_fd, http_header, len, 0); + + return((rc == len) ? 0 : -1); +} + + +/* *********************************************** */ + +void send_packet(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *remote_peer, u_int8_t compress_data) { + int data_sent_len; + + data_sent_len = unreliable_sendto(sinfo, + packet, packet_len, remote_peer, compress_data); + + if(data_sent_len != *packet_len) + traceEvent(TRACE_WARNING, + "sendto() [sent=%d][attempted_to_send=%d] [%s]\n", + data_sent_len, *packet_len, strerror(errno)); +} + +/* *********************************************** */ + +int traceLevel = 2 /* NORMAL */; +int useSyslog = 0, syslog_opened = 0; + +#ifdef __ANDROID_NDK__ +slog_t* slog = NULL; +int android_log_level(int lvl) +{ + switch (lvl) { + case 0: // ERROR + return ANDROID_LOG_ERROR; + case 1: // WARNING + return ANDROID_LOG_WARN; + case 2: // NORMAL + return ANDROID_LOG_INFO; + case 3: // INFO + return ANDROID_LOG_VERBOSE; + default: // NORMAL + return ANDROID_LOG_INFO; + } +} +#endif /* #ifdef __ANDROID_NDK__ */ + +#define N2N_TRACE_DATESIZE 32 +void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) { + va_list va_ap; + + if(eventTraceLevel <= traceLevel) { + char buf[2048]; + char out_buf[640]; + char theDate[N2N_TRACE_DATESIZE]; + char *extra_msg = ""; + time_t theTime = time(NULL); +#ifdef WIN32 + int i; +#endif + + /* We have two paths - one if we're logging, one if we aren't + * Note that the no-log case is those systems which don't support it (WIN32), + * those without the headers !defined(USE_SYSLOG) + * those where it's parametrically off... + */ + + memset(buf, 0, sizeof(buf)); + strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); + + va_start (va_ap, format); + vsnprintf(buf, sizeof(buf)-1, format, va_ap); + va_end(va_ap); + + if(eventTraceLevel == 0 /* TRACE_ERROR */) + extra_msg = "ERROR: "; + else if(eventTraceLevel == 1 /* TRACE_WARNING */) + extra_msg = "WARNING: "; + + while(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + +#ifndef WIN32 + if(useSyslog) { + if(!syslog_opened) { + openlog("n2n", LOG_PID, LOG_DAEMON); + syslog_opened = 1; + } + + snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); + syslog(LOG_INFO, "%s", out_buf); + } else { +#ifdef __ANDROID_NDK__ + char * p = strrchr(file, '/'); + file = (p ? p + 1 : file); +#endif /* #ifdef __ANDROID_NDK__ */ + snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf); +#ifdef __ANDROID_NDK__ + slog = writeslog(slog, android_log_level(eventTraceLevel), "n2n_v1", out_buf); +#else /* #ifdef __ANDROID_NDK__ */ + printf("%s\n", out_buf); + fflush(stdout); +#endif /* #ifdef __ANDROID_NDK__ */ + } +#else + /* this is the WIN32 code */ + for(i=strlen(file)-1; i>0; i--) if(file[i] == '\\') { i++; break; }; + snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); + printf("%s\n", out_buf); + fflush(stdout); +#endif + } + +} + +/* *********************************************** */ + +/* addr should be in network order. Things are so much simpler that way. */ +char* intoa(u_int32_t /* host order */ addr, char* buf, u_short buf_len) { + char *cp, *retStr; + u_int byte; + int n; + + cp = &buf[buf_len]; + *--cp = '\0'; + + n = 4; + do { + byte = addr & 0xff; + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) { + *--cp = byte % 10 + '0'; + byte /= 10; + if (byte > 0) + *--cp = byte + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + /* Convert the string to lowercase */ + retStr = (char*)(cp+1); + + return(retStr); +} + +/* *********************************************** */ + +char* macaddr_str(const char *mac, char *buf, int buf_len) { + snprintf(buf, buf_len, "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0] & 0xFF, mac[1] & 0xFF, mac[2] & 0xFF, + mac[3] & 0xFF, mac[4] & 0xFF, mac[5] & 0xFF); + return(buf); +} + +/* *********************************************** */ + +void fill_standard_header_fields(n2n_sock_info_t * sinfo, + struct n2n_packet_header *hdr, char *src_mac) { + socklen_t len = sizeof(hdr->private_ip); + memset(hdr, 0, N2N_PKT_HDR_SIZE); + hdr->version = N2N_PKT_VERSION; + hdr->crc = 0; // FIX + if(src_mac != NULL) memcpy(hdr->src_mac, src_mac, 6); + getsockname(sinfo->sock, (struct sockaddr*)&hdr->private_ip, &len); + hdr->public_ip.family = AF_INET; +} + +/* *********************************************** */ + +void send_ack(n2n_sock_info_t * sinfo, + u_int16_t last_rcvd_seq_id, + struct n2n_packet_header *header, + struct peer_addr *remote_peer, + char *src_mac) { + + /* marshalling double-checked. */ + struct n2n_packet_header hdr; + u_int8_t pkt[ N2N_PKT_HDR_SIZE ]; + size_t len = sizeof(hdr); + size_t len2; + int compress_data = N2N_COMPRESSION_ENABLED; + + fill_standard_header_fields(sinfo, &hdr, src_mac); + hdr.msg_type = MSG_TYPE_ACK_RESPONSE; + hdr.sequence_id = last_rcvd_seq_id; + memcpy(hdr.community_name, header->community_name, COMMUNITY_LEN); + + len2=marshall_n2n_packet_header( pkt, &hdr ); + assert( len2 == len ); + + send_packet(sinfo, (char*)pkt, &len, remote_peer, compress_data); +} + +/* *********************************************** */ + +u_int8_t is_multi_broadcast(char *dest_mac) { + return(((!memcmp(broadcast_addr, dest_mac, 6)) + || (!memcmp(multicast_addr, dest_mac, 3))) ? 1 : 0); +} + +/* *********************************************** */ + +/* http://www.faqs.org/rfcs/rfc908.html */ + +u_int receive_data(n2n_sock_info_t * sinfo, + char *packet, size_t packet_len, + struct peer_addr *from, u_int8_t *discarded_pkt, + char *tun_mac_addr, u_int8_t decompress_data, + struct n2n_packet_header *hdr) { + socklen_t fromlen = sizeof(struct sockaddr_in); + int len; + char *payload, *pkt_type; + macstr_t src_mac_buf; + macstr_t dst_mac_buf; + ipstr_t ip_buf; + ipstr_t from_ip_buf; + + if(sinfo->is_udp_socket) { + struct sockaddr_in _from; + len = recvfrom(sinfo->sock, packet, packet_len, 0, (struct sockaddr*)&_from, &fromlen); + sockaddr_in2peer_addr(&_from, from); + } else { + len = recv(sinfo->sock, packet, 4, 0); + if(len == 4) { + packet[4] = '\0'; + len = atoi(packet); + len = recv(sinfo->sock, packet, len, 0); + } else { + traceEvent(TRACE_WARNING, "Unable to receive n2n packet length"); + return(-1); + } + } + + unmarshall_n2n_packet_header(hdr, (u_int8_t *)packet); + + payload = &packet[N2N_PKT_HDR_SIZE]; + + if(len < 0) { +#ifdef WIN32 + if(WSAGetLastError() != WSAECONNRESET /* http://support.microsoft.com/kb/263823 */ ) { + traceEvent(TRACE_WARNING, "recvfrom returned %d [err=%d]", len, WSAGetLastError()); + } +#endif + return(0); + } else if(len > MIN_COMPRESSED_PKT_LEN) { +#define N2N_DECOMPRESS_BUFSIZE 2048 + char decompressed[N2N_DECOMPRESS_BUFSIZE]; + int rc; + lzo_uint decompressed_len=N2N_DECOMPRESS_BUFSIZE; + size_t insize = len-N2N_PKT_HDR_SIZE; + + if(decompress_data) { + rc = lzo1x_decompress_safe((u_char*)&packet[N2N_PKT_HDR_SIZE], + insize, + (u_char*)decompressed, &decompressed_len, NULL); + + if(rc == LZO_E_OK) + { + traceEvent(TRACE_INFO, "%u bytes decompressed into %u", insize, decompressed_len); + } + else + { + traceEvent(TRACE_WARNING, "Failed to decompress %u byte packet. LZO error=%d", insize, rc ); + return -1; + } + + if(packet_len > decompressed_len) { + memcpy(&packet[N2N_PKT_HDR_SIZE], decompressed, decompressed_len); + len = decompressed_len+N2N_PKT_HDR_SIZE; + } else { + traceEvent(TRACE_WARNING, "Uncompressed packet is too large [decompressed_len=%d]", + decompressed_len); + return(0); + } + } + + (*discarded_pkt) = 0; + + if(!hdr->sent_by_supernode) { + memcpy( &packet[offsetof(struct n2n_packet_header, public_ip)], from, sizeof(struct sockaddr_in) ); + } + + switch(hdr->pkt_type) { + case packet_unreliable_data: + pkt_type = "unreliable data"; + break; + case packet_reliable_data: + pkt_type = "reliable data"; + break; + case packet_ping: + pkt_type = "ping"; + break; + case packet_pong: + pkt_type = "pong"; + break; + default: + pkt_type = "???"; + } + + traceEvent(TRACE_INFO, "+++ Received %s packet [rcvd_from=%s:%d][msg_type=%s][seq_id=%d]", + pkt_type, + intoa(ntohl(from->addr_type.v4_addr), from_ip_buf, sizeof(from_ip_buf)), + ntohs(from->port), msg_type2str(hdr->msg_type), + hdr->sequence_id); + traceEvent(TRACE_INFO, " [src_mac=%s][dst_mac=%s][original_sender=%s:%d]", + macaddr_str(hdr->src_mac, src_mac_buf, sizeof(src_mac_buf)), + macaddr_str(hdr->dst_mac, dst_mac_buf, sizeof(dst_mac_buf)), + intoa(ntohl(hdr->public_ip.addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(hdr->public_ip.port)); + +#ifdef HANDLE_RETRANSMISSION + if((hdr->pkt_type == packet_reliable_data) + && (hdr->msg_type == MSG_TYPE_PACKET)) { + (*discarded_pkt) = handle_ack(sock_fd, is_udp_socket, hdr, + &payload[6], payload, from, tun_mac_addr); + } else + (*discarded_pkt) = 0; +#endif + } else + traceEvent(TRACE_WARNING, "Receive error [%s] or pkt too short [len=%d]\n", + strerror(errno), len); + + return(len); +} + +/* *********************************************** */ + +#if 0 +static u_int32_t queue_packet(struct send_hash_entry *scan, + char *packet, + u_int16_t packet_len) { + struct packet_list *pkt = (struct packet_list*)malloc(sizeof(struct packet_list)); + + if(pkt == NULL) { + traceEvent(TRACE_ERROR, "Not enough memory!"); + return(0); + } + + if((pkt->packet = (char*)malloc(packet_len)) == NULL) { + traceEvent(TRACE_ERROR, "Not enough memory!"); + return(0); + } + + memcpy(pkt->packet, packet, packet_len); + pkt->packet_len = packet_len; + pkt->seq_id = scan->last_seq_id; + pkt->next = scan->unacked_packet_list; + scan->unacked_packet_list = pkt; + scan->num_unacked_pkts++; + return(pkt->seq_id); +} +#endif + +/* *********************************************** */ + +/* Work-memory needed for compression. Allocate memory in units + * of `lzo_align_t' (instead of `char') to make sure it is properly aligned. + */ + +#define HEAP_ALLOC(var,size) \ + lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] + +static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS); + +/* ******************************************************* */ + +u_int send_data(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *to, u_int8_t compress_data) { + char compressed[1650]; + int rc; + lzo_uint compressed_len=0; + struct sockaddr_in destsock; + + if(*packet_len < N2N_PKT_HDR_SIZE) { + traceEvent(TRACE_WARNING, "The packet about to be sent is too short [len=%d]\n", *packet_len); + return(-1); + } + + memcpy(compressed, packet, N2N_PKT_HDR_SIZE); + + peer_addr2sockaddr_in(to, &destsock); + + if(compress_data) { + rc = lzo1x_1_compress((u_char*)&packet[N2N_PKT_HDR_SIZE], + *packet_len - N2N_PKT_HDR_SIZE, + (u_char*)&compressed[N2N_PKT_HDR_SIZE], + &compressed_len, wrkmem); + + if ( 0 == compressed_len ) + { + traceEvent(TRACE_WARNING, "failed to compress %u bytes.", (*packet_len - N2N_PKT_HDR_SIZE) ); + return -1; + } + + compressed_len += N2N_PKT_HDR_SIZE; + + traceEvent(TRACE_INFO, "%u bytes compressed into %u", *packet_len, compressed_len); + /* *packet_len = compressed_len; */ + + if(sinfo->is_udp_socket) { + rc = sendto(sinfo->sock, compressed, compressed_len, 0, + (struct sockaddr*)&destsock, sizeof(struct sockaddr_in)); + } else { + char send_len[5]; + + /* 4 bytes packet length */ + snprintf(send_len, sizeof(send_len), "%04d", (int)compressed_len); + if((rc = send(sinfo->sock, send_len, 4, 0)) != 4) + return(-1); + if((rc = send(sinfo->sock, compressed, compressed_len, 0)) != compressed_len) { + traceEvent(TRACE_WARNING, "send error [%d][%s]", + errno, strerror(errno)); + } + } + } else { + compressed_len = *packet_len; + if(sinfo->is_udp_socket) + rc = sendto(sinfo->sock, packet, compressed_len, 0, + (struct sockaddr*)&destsock, sizeof(struct sockaddr_in)); + else { + char send_len[5]; + + /* 4 bytes packet length */ + snprintf(send_len, sizeof(send_len), "%04d", (int)compressed_len); + if((rc = send(sinfo->sock, send_len, 4, 0)) != 4) + return(-1); + rc = send(sinfo->sock, compressed, compressed_len, 0); + } + + if(rc == -1) { + ipstr_t ip_buf; + + traceEvent(TRACE_WARNING, "sendto() failed while attempting to send data to %s:%d", + intoa(ntohl(to->addr_type.v4_addr), ip_buf, sizeof(ip_buf)), + ntohs(to->port)); + } + } + + if ( rc >= 0) { + traceEvent(TRACE_INFO, "### Tx N2N Msg -> network"); + } + + if(rc == compressed_len) + return(*packet_len); /* fake just to avoid warnings */ + else + return(rc); +} + +/* *********************************************** */ + +u_int reliable_sendto(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *to, u_int8_t compress_data) { + /* char *payload = &packet[N2N_PKT_HDR_SIZE]; */ + struct n2n_packet_header hdr_storage; + struct n2n_packet_header *hdr = &hdr_storage; + macstr_t src_mac_buf; + macstr_t dst_mac_buf; + + /* REVISIT: efficiency of unmarshal + re-marshal just to change a couple of bits. */ + unmarshall_n2n_packet_header( hdr, (u_int8_t *)packet ); + + /* hdr->sequence_id = (hdr->msg_type == MSG_TYPE_PACKET) ? mac2sequence((u_char*)payload, packet, *packet_len) : 0; */ + hdr->sequence_id = 0; + hdr->pkt_type = packet_reliable_data; + + traceEvent(TRACE_INFO, "Sent reliable packet [msg_type=%s][seq_id=%d][src_mac=%s][dst_mac=%s]", + msg_type2str(hdr->msg_type), hdr->sequence_id, + macaddr_str(&packet[6], src_mac_buf, sizeof(src_mac_buf)), + macaddr_str(packet, dst_mac_buf, sizeof(dst_mac_buf))); + + marshall_n2n_packet_header( (u_int8_t *)packet, hdr ); + + return(send_data(sinfo, packet, packet_len, to, compress_data)); +} + +/* *********************************************** */ + +/* unreliable_sendto is passed a fully marshalled, packet. Its purpose is to set + * the unreliable flags but leave the rest of the packet untouched. */ +u_int unreliable_sendto(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *to, u_int8_t compress_data) { + struct n2n_packet_header hdr_storage; + struct n2n_packet_header *hdr = &hdr_storage; + macstr_t src_mac_buf; + macstr_t dst_mac_buf; + + /* REVISIT: efficiency of unmarshal + re-marshal just to change a couple of bits. */ + unmarshall_n2n_packet_header( hdr, (u_int8_t *)packet ); + + hdr->sequence_id = 0; /* Unreliable messages have 0 as sequence number */ + hdr->pkt_type = packet_unreliable_data; + + traceEvent(TRACE_INFO, "Sent unreliable packet [msg_type=%s][seq_id=%d][src_mac=%s][dst_mac=%s]", + msg_type2str(hdr->msg_type), hdr->sequence_id, + macaddr_str(hdr->src_mac, src_mac_buf, sizeof(src_mac_buf)), + macaddr_str(hdr->dst_mac, dst_mac_buf, sizeof(dst_mac_buf))); + + marshall_n2n_packet_header( (u_int8_t *)packet, hdr ); + + return(send_data(sinfo, packet, packet_len, to, compress_data)); +} + +/* *********************************************** */ + +char* msg_type2str(u_short msg_type) { + switch(msg_type) { + case MSG_TYPE_REGISTER: return("MSG_TYPE_REGISTER"); + case MSG_TYPE_DEREGISTER: return("MSG_TYPE_DEREGISTER"); + case MSG_TYPE_PACKET: return("MSG_TYPE_PACKET"); + case MSG_TYPE_REGISTER_ACK: return("MSG_TYPE_REGISTER_ACK"); + case MSG_TYPE_ACK_RESPONSE: return("MSG_TYPE_ACK_RESPONSE"); + } + + return("???"); +} + +/* *********************************************** */ + +void hexdump(char *buf, u_int len) { + u_int i; + + for(i=0; i 0) && ((i % 16) == 0)) printf("\n"); + printf("%02X ", buf[i] & 0xFF); + } + + printf("\n"); +} + +/* *********************************************** */ + +void print_n2n_version() { + printf("Welcome to n2n v.%s for %s\n" + "Built on %s\n" + "Copyright 2007-08 - http://www.ntop.org\n\n", + version, osName, buildDate); +} + +const char* random_device_mac(void) +{ + const char key[] = "0123456789abcdef"; + static char mac[18]; + int i; + + srand(gettid()); + for (i = 0; i < sizeof(mac) - 1; ++i) + { + if ((i + 1) % 3 == 0) { + mac[i] = ':'; + continue; + } + mac[i] = key[random() % sizeof(key)]; + } + mac[sizeof(mac) - 1] = '\0'; + return mac; +} + + +/** Find the peer entry in list with mac_addr equal to mac. + * + * Does not modify the list. + * + * @return NULL if not found; otherwise pointer to peer entry. + */ +struct peer_info * find_peer_by_mac( struct peer_info * list, const char * mac ) +{ + while(list != NULL) + { + if( 0 == memcmp(mac, list->mac_addr, 6) ) + { + return list; + } + list = list->next; + } + + return NULL; +} + + +/** Return the number of elements in the list. + * + */ +size_t peer_list_size( const struct peer_info * list ) +{ + size_t retval=0; + + while ( list ) + { + ++retval; + list = list->next; + } + + return retval; +} + +/** Add new to the head of list. If list is NULL; create it. + * + * The item new is added to the head of the list. New is modified during + * insertion. list takes ownership of new. + */ +void peer_list_add( struct peer_info * * list, + struct peer_info * new ) +{ + new->next = *list; + new->last_seen = time(NULL); + *list = new; +} + + +size_t purge_expired_registrations( struct peer_info ** peer_list ) { + static time_t last_purge = 0; + time_t now = time(NULL); + size_t num_reg = 0; + + if((now - last_purge) < PURGE_REGISTRATION_FREQUENCY) return 0; + + traceEvent(TRACE_INFO, "Purging old registrations"); + + num_reg = purge_peer_list( peer_list, now-REGISTRATION_TIMEOUT ); + + last_purge = now; + traceEvent(TRACE_INFO, "Remove %ld registrations", num_reg); + + return num_reg; +} + +/** Purge old items from the peer_list and return the number of items that were removed. */ +size_t purge_peer_list( struct peer_info ** peer_list, + time_t purge_before ) +{ + struct peer_info *scan; + struct peer_info *prev; + size_t retval=0; + + scan = *peer_list; + prev = NULL; + while(scan != NULL) + { + if(scan->last_seen < purge_before) + { + struct peer_info *next = scan->next; + + if(prev == NULL) + { + *peer_list = next; + } + else + { + prev->next = next; + } + + ++retval; + free(scan); + scan = next; + } + else + { + prev = scan; + scan = scan->next; + } + } + + return retval; +} + +static u_int8_t hex2byte( const char * s ) +{ + char tmp[3]; + tmp[0]=s[0]; + tmp[1]=s[1]; + tmp[2]=0; /* NULL term */ + + return((u_int8_t)strtol( s, NULL, 16 )); +} + +extern int str2mac( u_int8_t * outmac /* 6 bytes */, const char * s ) +{ + size_t i; + + /* break it down as one case for the first "HH", the 5 x through loop for + * each ":HH" where HH is a two hex nibbles in ASCII. */ + + *outmac=hex2byte(s); + ++outmac; + s+=2; /* don't skip colon yet - helps generalise loop. */ + + for (i=1; i<6; ++i ) + { + s+=1; + *outmac=hex2byte(s); + ++outmac; + s+=2; + } + + return 0; /* ok */ +} diff --git a/bundles/n2n_meyerd/n2n_v1/n2n.h b/bundles/n2n_meyerd/n2n_v1/n2n.h new file mode 100644 index 00000000..1e2d96b9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/n2n.h @@ -0,0 +1,308 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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, see + * + * Code contributions courtesy of: + * Babak Farrokhi [FreeBSD port] + * +*/ + +#ifndef _N2N_H_ +#define _N2N_H_ + +/* + tunctl -t tun0 + tunctl -t tun1 + ifconfig tun0 1.2.3.4 up + ifconfig tun1 1.2.3.5 up + ./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello + ./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello + + + tunctl -u UID -t tunX +*/ + +#if defined(__APPLE__) && defined(__MACH__) +#define _DARWIN_ +#endif + +#ifdef WIN32 +#include "win32/n2n_win32.h" +#endif + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#endif + +#ifdef __FreeBSD__ +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define closesocket(a) close(a) +#endif + +#include +#ifdef WIN32 +#include "win32/getopt.h" +#else +#define _GNU_SOURCE +#include +#endif + +#include + +#ifdef WIN32 +#include "win32/wintap.h" +#endif + +#include "twofish.h" + +#ifndef WIN32 +typedef struct tuntap_dev { + int fd; + u_int8_t mac_addr[6]; + u_int32_t ip_addr, device_mask; + u_int mtu; +} tuntap_dev; + +#define SOCKET int +#endif /* #ifndef WIN32 */ + +#define QUICKLZ 1 +#define N2N_PKT_VERSION 1 + +#define MSG_TYPE_REGISTER 1 /* FIX invece di usare il sender del pacchetto scriverlo nel pacchetto stesso */ +#define MSG_TYPE_DEREGISTER 2 +#define MSG_TYPE_PACKET 3 +#define MSG_TYPE_REGISTER_ACK 4 +#define MSG_TYPE_ACK_RESPONSE 5 + +#define COMMUNITY_LEN 16 +#define MIN_COMPRESSED_PKT_LEN 32 + +/* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet + * frames. Doing this will break compatibility with the standard n2n packet + * format so do it only for experimentation. All edges must be built with the + * same value if they are to understand each other. */ +#define N2N_COMPRESSION_ENABLED 1 + +#define DEFAULT_MTU 1400 + +/* Maximum enum value is 255 due to marshalling into 1 byte */ +enum packet_type { + packet_unreliable_data = 0, /* no ACK needed */ + packet_reliable_data, /* needs ACK */ + packet_ping, + packet_pong +}; + +/* All information is always in network byte-order */ +struct peer_addr { + u_int8_t family; + u_int16_t port; + union { + u_int8_t v6_addr[16]; + u_int32_t v4_addr; + } addr_type; +}; + +struct n2n_packet_header { + u_int8_t version, msg_type, ttl, sent_by_supernode; + char community_name[COMMUNITY_LEN], src_mac[6], dst_mac[6]; + struct peer_addr public_ip, private_ip; + enum packet_type pkt_type; + u_int32_t sequence_id; + u_int32_t crc; // FIX - It needs to be handled for detcting forged packets +}; + +int marshall_n2n_packet_header( u_int8_t * buf, const struct n2n_packet_header * hdr ); +int unmarshall_n2n_packet_header( struct n2n_packet_header * hdr, const u_int8_t * buf ); + +#define N2N_PKT_HDR_SIZE (sizeof(struct n2n_packet_header)) + + +/** Common type used to hold stringified IP addresses. */ +typedef char ipstr_t[32]; + +/** Common type used to hold stringified MAC addresses. */ +typedef char macstr_t[32]; + +struct n2n_sock_info +{ + int sock; + char is_udp_socket /*= 1*/; +}; + +typedef struct n2n_sock_info n2n_sock_info_t; + +struct peer_info { + char community_name[COMMUNITY_LEN], mac_addr[6]; + struct peer_addr public_ip, private_ip; + time_t last_seen; + struct peer_info *next; + /* socket */ + n2n_sock_info_t sinfo; +}; + +struct n2n_edge; /* defined in edge.c */ +typedef struct n2n_edge n2n_edge_t; + + +/* ************************************** */ + +#if defined(DEBUG) +#define SOCKET_TIMEOUT_INTERVAL_SECS 5 +#define REGISTER_FREQUENCY 20 /* sec */ +#else /* #if defined(DEBUG) */ +#define SOCKET_TIMEOUT_INTERVAL_SECS 10 +#define REGISTER_FREQUENCY 60 /* sec */ +#endif /* #if defined(DEBUG) */ + +#ifdef __ANDROID_NDK__ +#include +extern int android_log_level(int lvl); +extern slog_t* slog; +#ifndef N2N_LOG_FILEPATH +#define N2N_LOG_FILEPATH "/storage/sdcard0/wang.switchy.hin2n/n2n_v1.log" +#endif /* #ifndef N2N_LOG_FILEPATH */ +#endif /* #ifdef __ANDROID_NDK__ */ +#define TRACE_ERROR 0, __FILE__, __LINE__ +#define TRACE_WARNING 1, __FILE__, __LINE__ +#define TRACE_NORMAL 2, __FILE__, __LINE__ +#define TRACE_INFO 3, __FILE__, __LINE__ + +/* ************************************** */ + +#define SUPERNODE_IP "127.0.0.1" +#define SUPERNODE_PORT 1234 + +/* ************************************** */ + +#ifndef max +#define max(a, b) ((a < b) ? b : a) +#endif + +#ifndef min +#define min(a, b) ((a > b) ? b : a) +#endif + +/* ************************************** */ + +/* Variables */ +// extern TWOFISH *tf; +extern int traceLevel; +extern char broadcast_addr[6]; +extern char multicast_addr[6]; + +/* Functions */ +extern void sockaddr_in2peer_addr(struct sockaddr_in *in, struct peer_addr *out); +extern void peer_addr2sockaddr_in(const struct peer_addr *in, struct sockaddr_in *out); +// extern int init_n2n(u_int8_t *encrypt_pwd, u_int32_t encrypt_pwd_len ); +// extern void term_n2n(); +extern void send_ack(n2n_sock_info_t * sinfo, + u_int16_t last_rcvd_seq_id, + struct n2n_packet_header *header, + struct peer_addr *remote_peer, + char *src_mac); + +extern void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); +extern int tuntap_open(tuntap_dev *device, char *dev, char *device_ip, + char *device_mask, const char * device_mac, int mtu); +extern int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); +extern int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); +extern void tuntap_close(struct tuntap_dev *tuntap); + +extern SOCKET open_socket(u_int16_t local_port, int udp_sock, int server_mode); +extern int connect_socket(int sock_fd, struct peer_addr* dest); + +extern void send_packet(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *remote_peer, + u_int8_t compress_data); +extern char* intoa(u_int32_t addr, char* buf, u_short buf_len); +extern char* macaddr_str(const char *mac, char *buf, int buf_len); +extern int str2mac( u_int8_t * outmac /* 6 bytes */, const char * s ); +extern void fill_standard_header_fields(n2n_sock_info_t * eee, + struct n2n_packet_header *hdr, + char *src_mac); + +extern u_int receive_data(n2n_sock_info_t * sinfo, + char *packet, size_t packet_len, + struct peer_addr *from, u_int8_t *discarded_pkt, + char *tun_mac_addr, u_int8_t decompress_data, + struct n2n_packet_header *hdr); +extern u_int reliable_sendto(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *from, u_int8_t compress_data); +extern u_int unreliable_sendto(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *from, u_int8_t compress_data); +extern u_int send_data(n2n_sock_info_t * sinfo, + char *packet, size_t *packet_len, + const struct peer_addr *to, u_int8_t compress_data); +extern u_int8_t is_multi_broadcast(char *dest_mac); +extern char* msg_type2str(u_short msg_type); +extern void hexdump(char *buf, u_int len); + +void print_n2n_version(); +const char* random_device_mac(void); + + +/* Operations on peer_info lists. */ +struct peer_info * find_peer_by_mac( struct peer_info * list, + const char * mac ); +void peer_list_add( struct peer_info * * list, + struct peer_info * new ); +size_t peer_list_size( const struct peer_info * list ); +size_t purge_peer_list( struct peer_info ** peer_list, + time_t purge_before ); +size_t purge_expired_registrations( struct peer_info ** peer_list ); + +/* version.c */ +extern char *version, *osName, *buildDate; + +#endif /* _N2N_H_ */ diff --git a/bundles/n2n_meyerd/n2n_v1/n2n.spec b/bundles/n2n_meyerd/n2n_v1/n2n.spec new file mode 100644 index 00000000..0e7892ae --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/n2n.spec @@ -0,0 +1,47 @@ +Summary: N2N peer-to-peer virtual private network system. +Name: n2n +Version: 1.3 +Release: 1 +License: GPLv3 +Vendor: ntop.org +Group: None +URL: http://www.ntop.org/n2n +Source0: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%description +N2N is a peer-to-peer virtual private network system. N2N uses the universal +TUNTAP interface to create TAP network interfaces to an encrypted virtual +LAN. Members of a community share a common encryption key which allows echange +of data. The supernode is used for peer discovery and initial packet relay +before direct peer-to-peer exchange is established. +Once direct packet exchange is established, the supernode is not required. + +%prep + +%setup -q + +echo -e "\n *** Building ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE} ***\n" + +%build +make + +%install +make PREFIX=${RPM_BUILD_ROOT}/usr install + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,-) + /usr/bin/supernode + /usr/sbin/edge +%doc /usr/share/man/man1/supernode.1.gz +%doc /usr/share/man/man8/edge.8.gz + + +%changelog +* Sat May 3 2008 Richard Andrews - +- Initial build. + diff --git a/bundles/n2n_meyerd/n2n_v1/scripts/mk_SRPM.sh b/bundles/n2n_meyerd/n2n_v1/scripts/mk_SRPM.sh new file mode 100644 index 00000000..2b1b3743 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/scripts/mk_SRPM.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +set -x + +BASE=`pwd` + +TARFILE=`${BASE}/scripts/mk_tar.sh` + +test -f ${TARFILE} + +echo "Building SRPM" +# -ts means build source RPM from tarfile +rpmbuild -ts ${TARFILE} + +echo "Done" diff --git a/bundles/n2n_meyerd/n2n_v1/scripts/mk_deb.sh b/bundles/n2n_meyerd/n2n_v1/scripts/mk_deb.sh new file mode 100644 index 00000000..42d86916 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/scripts/mk_deb.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +set -x + +BASE=`pwd` + +TARFILE=`${BASE}/scripts/mk_tar.sh` +TEMPDIR="build_deb" + +test -f ${TARFILE} + +echo "Building .deb" + +if [ -d ${TEMPDIR} ]; then + echo "Removing ${TEMPDIR} directory" + rm -rf ${TEMPDIR} >&2 +fi + +mkdir ${TEMPDIR} + +pushd ${TEMPDIR} + +tar xzf ${TARFILE} #At original location + +cd n2n* + +dpkg-buildpackage -rfakeroot + +popd + +echo "Done" diff --git a/bundles/n2n_meyerd/n2n_v1/scripts/mk_tar.sh b/bundles/n2n_meyerd/n2n_v1/scripts/mk_tar.sh new file mode 100644 index 00000000..539a5655 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/scripts/mk_tar.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +function exit_fail() +{ + echo "$1" + exit 1 +} + +PACKAGE="n2n" +PKG_VERSION="1.3" +PKG_AND_VERSION="${PACKAGE}-${PKG_VERSION}" + +TEMPDIR="tmp" + +SOURCE_MANIFEST=" +README +edge.c +lzoconf.h +lzodefs.h +Makefile +minilzo.c +minilzo.h +n2n.c +n2n.h +n2n.spec +supernode.c +tuntap_linux.c +tuntap_freebsd.c +tuntap_osx.c +twofish.c +twofish.h +edge.8 +supernode.1 +debian/changelog +debian/compat +debian/control +debian/copyright +debian/n2n.dirs +debian/n2n.docs +debian/n2n.install +debian/n2n.manpages +debian/README.Debian +debian/rules +" + +BASE=`pwd` + +for F in ${SOURCE_MANIFEST}; do + test -e $F || exit_fail "Cannot find $F. Maybe you're in the wrong directory. Please execute from n2n directory."; >&2 +done + +echo "Found critical files. Proceeding." >&2 + +if [ -d ${TEMPDIR} ]; then + echo "Removing ${TEMPDIR} directory" + rm -rf ${TEMPDIR} >&2 +fi + +mkdir ${TEMPDIR} >&2 + +pushd ${TEMPDIR} >&2 + +echo "Creating staging directory ${PWD}/${PKG_AND_VERSION}" >&2 + +if [ -d ${PKG_AND_VERSION} ] ; then + echo "Removing ${PKG_AND_VERSION} directory" + rm -rf ${PKG_AND_VERSION} >&2 +fi + +mkdir ${PKG_AND_VERSION} + +pushd ${BASE} >&2 + +echo "Copying in files" >&2 +for F in ${SOURCE_MANIFEST}; do + cp --parents -a $F ${TEMPDIR}/${PKG_AND_VERSION}/ +done + +popd >&2 + +TARFILE="${PKG_AND_VERSION}.tar.gz" +echo "Creating ${TARFILE}" >&2 +tar czf ${BASE}/${TARFILE} ${PKG_AND_VERSION} + +popd >&2 + +rm -rf ${TEMPDIR} >&2 + +echo ${BASE}/${TARFILE} diff --git a/bundles/n2n_meyerd/n2n_v1/supernode.1 b/bundles/n2n_meyerd/n2n_v1/supernode.1 new file mode 100644 index 00000000..863c4984 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/supernode.1 @@ -0,0 +1,40 @@ +.TH supernode 1 "Jan 3, 2009" "revision 3679" "USER COMMANDS" +.SH NAME +supernode \- n2n supernode daemon +.SH SYNOPSIS +.B supernode \-l [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Supernode is a node introduction registry, +broadcast conduit and packet relay node for the n2n system. On startup supernode +begins listening on the specified UDP port for node registrations, and other +packets to route. The supernode can service any number of communities and routes +packets only between members of the same community. The supernode does not hold +the community encryption key and so cannot snoop or inject packets into the +community. +.PP +Supernode can service a number of n2n communities concurrently. Traffic does not +cross between communities. +.PP +All logging goes to stdout. +.SH OPTIONS +.TP +\-l +listen on the given UDP port +.TP +\-v +use verbose logging +.SH EXAMPLES +.TP +.B supernode -l 7654 -v +Start supernode listening on UDP port 7654 with verbose output. +.PP +.SH RESTART +When suprenode restarts it loses all registration information from associated +edge nodes. It can take up to five minutes for the edge nodes to re-register and +normal traffic flow to resume. +.SH EXIT STATUS +supernode is a daemon and any exit is an error +.SH AUTHOR +Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner +.SH SEE ALSO +ifconfig(8) edge(8) diff --git a/bundles/n2n_meyerd/n2n_v1/supernode.c b/bundles/n2n_meyerd/n2n_v1/supernode.c new file mode 100644 index 00000000..2f2d6b9a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/supernode.c @@ -0,0 +1,528 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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, see + * +*/ + +#include "n2n.h" + +struct tx_stats +{ + size_t pkts; + size_t errors; +}; + + +/* *********************************************** */ + +static void help() { + print_n2n_version(); + printf("supernode -l [-v] [-h]\n"); + exit(0); +} + +/* *********************************************** */ + +static struct peer_info *known_peers = NULL; +static struct tx_stats supernode_stats = {0,0}; + +/* *********************************************** */ + +/** Turn a REGISTER request around and send a REGISTER_ACK packet back to the + * sender. + * + * This needs to be done for all incoming REGISTER packets to keep firewalls + * open + */ +static void send_register_ack( n2n_sock_info_t * sinfo, + const struct peer_addr *destination_peer, + const struct n2n_packet_header * reqhdr ) +{ + struct n2n_packet_header hdr; + u_int8_t pkt[N2N_PKT_HDR_SIZE]; + size_t len = sizeof(hdr); + + fill_standard_header_fields(sinfo, &hdr, NULL /* zero src MAC */ ); + hdr.sent_by_supernode = 1; + hdr.msg_type = MSG_TYPE_REGISTER_ACK; + memcpy( hdr.community_name, reqhdr->community_name, COMMUNITY_LEN); + memcpy( hdr.dst_mac, reqhdr->src_mac, 6); /* turn it around */ + /* leave IP sockets unfilled. */ + + marshall_n2n_packet_header( pkt, &hdr ); + send_packet(sinfo, (char *)pkt, &len, destination_peer, N2N_COMPRESSION_ENABLED); +} + +static void register_peer(struct n2n_packet_header *hdr, + struct peer_addr *sender, + n2n_sock_info_t * sinfo) { + struct peer_info *scan = known_peers; + ipstr_t buf, buf1; + macstr_t mac_buf; + + send_register_ack( sinfo, sender, hdr ); /* keep firewalls open */ + + while(scan != NULL) { + if((strcmp(scan->community_name, hdr->community_name) == 0) + && (memcmp(&scan->mac_addr, hdr->src_mac, 6) == 0)) { + + scan->last_seen = time(NULL); + if ( ( 0 != memcmp(&scan->public_ip, sender, sizeof(struct peer_addr)) ) || + ( 0 != memcmp(&scan->private_ip, &hdr->private_ip, sizeof(struct peer_addr)) ) ) + { + /* Something is actually different. */ + memcpy(&scan->public_ip, sender, sizeof(struct peer_addr)); + memcpy(&scan->private_ip, &hdr->private_ip, sizeof(struct peer_addr)); + + /* Overwrite existing peer */ + traceEvent(TRACE_NORMAL, "Re-registered node [public_ip=(%d)%s:%hu][private_ip=%s:%hu][mac=%s][community=%s]", + scan->public_ip.family, + intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(scan->public_ip.port), + intoa(ntohl(scan->private_ip.addr_type.v4_addr), buf1, sizeof(buf1)), + ntohs(scan->private_ip.port), + macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), + scan->community_name); + } + + return; /* Found the registration entry so stop. */ + } + + scan = scan->next; + } + + /* FIX mettere un limite alla lista dei peer */ + + scan = (struct peer_info*)calloc(1, sizeof(struct peer_info)); + memcpy(scan->community_name, hdr->community_name, COMMUNITY_LEN); + memcpy(&scan->public_ip, sender, sizeof(struct peer_addr)); + memcpy(&scan->private_ip, &hdr->private_ip, sizeof(struct peer_addr)); + memcpy(&scan->mac_addr, hdr->src_mac, 6); + scan->last_seen = time(NULL); // FIX aggiungere un timeout + scan->next = known_peers; + scan->sinfo = *sinfo; + known_peers = scan; + + traceEvent(TRACE_NORMAL, "Registered new node [public_ip=(%d)%s:%d][private_ip=%s:%d][mac=%s][community=%s]", + scan->public_ip.family, + intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(scan->public_ip.port), + intoa(ntohl(scan->private_ip.addr_type.v4_addr), buf1, sizeof(buf1)), + ntohs(scan->private_ip.port), + macaddr_str(scan->mac_addr, mac_buf, sizeof(mac_buf)), + scan->community_name); +} + +/* *********************************************** */ + +static void deregister_peer(struct n2n_packet_header *hdr, + struct peer_addr *sender) { + struct peer_info *scan = known_peers, *prev = NULL; + ipstr_t buf, buf1; + + while(scan != NULL) { + if((strcmp(scan->community_name, hdr->community_name) == 0) + && (memcmp(&scan->mac_addr, hdr->src_mac, 6) == 0)) { + /* Overwrite existing peer */ + if(prev == NULL) + known_peers = scan->next; + else + prev->next = scan->next; + + traceEvent(TRACE_INFO, "Degistered node [public_ip=%s:%hu][private_ip=%s:%hu]", + intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(scan->public_ip.port), + intoa(ntohl(scan->private_ip.addr_type.v4_addr), buf1, sizeof(buf1)), + ntohs(scan->private_ip.port)); + + free(scan); + return; + } + + scan = scan->next; + } + + traceEvent(TRACE_WARNING, "Unable to delete specified peer [%s:%hu]", + intoa(ntohl(sender->addr_type.v4_addr), buf, sizeof(buf)), + ntohs(sender->port)); +} + +/* *********************************************** */ + +/* *********************************************** */ + +static const struct option long_options[] = { + { "community", required_argument, NULL, 'c' }, + { "listening-port", required_argument, NULL, 'l' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +/* *********************************************** */ + + +/** Forward a L2 packet to every edge registered for the community of the + * originator. + * + * @return number of copies of the packet sent + */ +static size_t broadcast_packet(char *packet, u_int packet_len, + struct peer_addr *sender, + n2n_sock_info_t * sinfo, + struct n2n_packet_header *hdr ) +{ + size_t numsent=0; + struct peer_info *scan; + + scan = known_peers; + while(scan != NULL) { + if((strcmp(scan->community_name, hdr->community_name) == 0) + && (memcmp(sender, &scan->public_ip, sizeof(struct peer_addr)) /* No L3 self-send */) ) + { + int data_sent_len; + size_t len = packet_len; + + data_sent_len = send_data( &(scan->sinfo), packet, &len, &scan->public_ip, 0); + + if(data_sent_len != len) + { + ++(supernode_stats.errors); + traceEvent(TRACE_WARNING, "sendto() [sent=%d][attempted_to_send=%d] [%s]\n", + data_sent_len, len, strerror(errno)); + } + else + { + ipstr_t buf; + ipstr_t buf1; + + ++numsent; + ++(supernode_stats.pkts); + traceEvent(TRACE_INFO, "Sent multicast message to remote node [%s:%hu][mac=%s]", + intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(scan->public_ip.port), + macaddr_str(scan->mac_addr, buf1, sizeof(buf1))); + } + } + + scan = scan->next; + } /* while */ + + + return numsent; +} + + +/** Forward a L2 packet. This may involve a broadcast operation. + * + * Rules are as follows: + * + * 1. If the dest MAC is a multicast address, broadcast to all edges in the + * community. + * + * 2. If the dest MAC is known forward to the destination edge only. + * Else broadcast to all edges in the community. + * + * @return number of copies of the packet sent + */ +static size_t forward_packet(char *packet, u_int packet_len, + struct peer_addr *sender, + n2n_sock_info_t * sinfo, + struct n2n_packet_header *hdr ) +{ + size_t numsent=0; + u_int8_t is_dst_broad_multi_cast; + struct peer_info *scan; + + ipstr_t buf; + ipstr_t buf1; + + hdr->ttl++; /* FIX discard packets with a high TTL */ + is_dst_broad_multi_cast = is_multi_broadcast(hdr->dst_mac); + + /* Put the original packet sender (public) address */ + memcpy(&hdr->public_ip, sender, sizeof(struct peer_addr)); + hdr->sent_by_supernode = 1; + + marshall_n2n_packet_header( (u_int8_t *)packet, hdr ); + + + if ( is_dst_broad_multi_cast ) + { + traceEvent(TRACE_INFO, "Broadcasting. Multicast address [mac=%s]", + macaddr_str(hdr->dst_mac, buf, sizeof(buf))); + + numsent = broadcast_packet( packet, packet_len, sender, sinfo, hdr ); + } + else + { + scan = find_peer_by_mac( known_peers, hdr->dst_mac ); + if ( scan ) + { + int data_sent_len; + size_t len = packet_len; + + data_sent_len = send_data( &(scan->sinfo), packet, &len, &scan->public_ip, 0); + + if(data_sent_len != len) + { + ++(supernode_stats.errors); + traceEvent(TRACE_WARNING, "sendto() [sent=%d][attempted_to_send=%d] [%s]\n", + data_sent_len, len, strerror(errno)); + } + else { + ++(supernode_stats.pkts); + traceEvent(TRACE_INFO, "Sent message to remote node [%s:%hu][mac=%s]", + intoa(ntohl(scan->public_ip.addr_type.v4_addr), buf, sizeof(buf)), + ntohs(scan->public_ip.port), + macaddr_str(scan->mac_addr, buf1, sizeof(buf1))); + } + + numsent = 1; + } + else + { + traceEvent(TRACE_INFO, "Broadcasting because unknown dest [mac=%s]", + macaddr_str(hdr->dst_mac, buf, sizeof(buf))); + numsent = broadcast_packet( packet, packet_len, sender, sinfo, hdr ); + } + } + + return numsent; +} + +static void handle_packet(char *packet, u_int packet_len, + struct peer_addr *sender, + n2n_sock_info_t * sinfo) { + ipstr_t buf; + + traceEvent(TRACE_INFO, "Received message from node [%s:%hu]", + intoa(ntohl(sender->addr_type.v4_addr), buf, sizeof(buf)), + ntohs(sender->port)); + + if(packet_len < N2N_PKT_HDR_SIZE) + traceEvent(TRACE_WARNING, "Received packet too short [len=%d]\n", packet_len); + else { + struct n2n_packet_header hdr_storage; + struct n2n_packet_header *hdr = &hdr_storage; + + unmarshall_n2n_packet_header( hdr, (u_int8_t *)packet ); + + if(hdr->version != N2N_PKT_VERSION) { + traceEvent(TRACE_WARNING, + "Received packet with unknown protocol version (%d): discarded\n", + hdr->version); + return; + } + + if(hdr->msg_type == MSG_TYPE_REGISTER) + { + register_peer(hdr, sender, sinfo); + } + else if(hdr->msg_type == MSG_TYPE_DEREGISTER) { + deregister_peer(hdr, sender); + } else if(hdr->msg_type == MSG_TYPE_PACKET) { + forward_packet( packet, packet_len, sender, sinfo, hdr ); + } else { + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored\n", + hdr->msg_type); + } + } +} + +/* *********************************************** */ + +static +#ifdef WIN32 +DWORD tcpReadThread(LPVOID lpArg) +#else + void* tcpReadThread(void *lpArg) +#endif +{ + n2n_sock_info_t sinfo; + char c[1600]; + int new_line = 0; + + sinfo.sock=(int)lpArg; + sinfo.is_udp_socket=0; /* TCP in this case */ + + traceEvent(TRACE_NORMAL, "Handling sock_fd %d", sinfo.sock); + + while(1) { + int rc; + + if((rc = recv(sinfo.sock, c, 2, 0)) > 0) { + if((c[0] == '\r') && (c[1] == '\n')) { + if(!new_line) + new_line = 1; + else + break; /* Double \r\n\r\n, the http header is over */ + } else + printf("%c%c [%d][%d] ", c[0], c[1], c[0], c[1]); fflush(stdout); + } else { + traceEvent(TRACE_NORMAL, "recv() error [rc=%d][%s]", rc, strerror(errno)); + break; + } + } + + /* Beginning of n2n protocol over TCP */ + c[5] = 0; + + while(1) { + int rc; + + // FIX: add select + if((rc = recv(sinfo.sock, c, 4, 0)) == 4) { + int len = atoi(c); + socklen_t from_len = sizeof(struct sockaddr_in ); + struct sockaddr_in from; + + /* Check packet length */ + if((len <= 0) || (len >= 1600)) break; + rc = recvfrom(sinfo.sock, c, len, 0, (struct sockaddr*)&from, &from_len); + + if((rc <= 0) || (rc != len)) + break; + else { + struct peer_addr _from; + + sockaddr_in2peer_addr(&from, &_from); + handle_packet(c, len, &_from, &sinfo); + } + } else + break; + } + + closesocket(sinfo.sock); +#ifdef WIN32 + return(0); +#else + return(NULL); +#endif +} + + +/* *********************************************** */ + +static void startTcpReadThread(int sock_fd) { +#ifdef WIN32 + HANDLE hThread; + DWORD dwThreadId; + + hThread = CreateThread(NULL, /* no security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tcpReadThread, /* thread function */ + (void*)sock_fd, /* argument to thread function */ + 0, /* use default creation flags */ + &dwThreadId); /* returns the thread identifier */ +#else + int rc; + pthread_t threadId; + + rc = pthread_create(&threadId, NULL, tcpReadThread, (void*)sock_fd); +#endif +} + +/* *********************************************** */ + +int main(int argc, char* argv[]) { + int opt; + u_int16_t local_port = 0; + n2n_sock_info_t udp_sinfo; + n2n_sock_info_t tcp_sinfo; + +#ifdef WIN32 + initWin32(); +#endif + + optarg = NULL; + while((opt = getopt_long(argc, argv, "l:vh", long_options, NULL)) != EOF) { + switch (opt) { + case 'l': /* local-port */ + local_port = atoi(optarg) & 0xffff; + break; + case 'h': /* help */ + help(); + break; + case 'v': /* verbose */ + traceLevel = 3; + break; + } + } + + if(!(local_port)) + help(); + + udp_sinfo.is_udp_socket=1; + udp_sinfo.sock = open_socket(local_port, 1, 0); + if(udp_sinfo.sock < 0) return(-1); + + tcp_sinfo.is_udp_socket=0; + tcp_sinfo.sock = open_socket(local_port, 0, 1); + if(tcp_sinfo.sock < 0) return(-1); + + traceEvent(TRACE_NORMAL, "Supernode ready: listening on port %hu [TCP/UDP]", local_port); + + while(1) { + int rc, max_sock; + fd_set socket_mask; + struct timeval wait_time; + + FD_ZERO(&socket_mask); + max_sock = max(udp_sinfo.sock, tcp_sinfo.sock); + FD_SET(udp_sinfo.sock, &socket_mask); + FD_SET(tcp_sinfo.sock, &socket_mask); + + wait_time.tv_sec = 10; wait_time.tv_usec = 0; + rc = select(max_sock+1, &socket_mask, NULL, NULL, &wait_time); + + if(rc > 0) { + if(FD_ISSET(udp_sinfo.sock, &socket_mask)) { + char packet[2048]; + size_t len; + struct peer_addr sender; + u_int8_t discarded_pkt; + struct n2n_packet_header hdr; + + len = receive_data( &udp_sinfo, packet, sizeof(packet), &sender, &discarded_pkt, NULL, 0, &hdr); + + if(len <= 0) + traceEvent(TRACE_WARNING, "recvfrom()=%d [%s]\n", len, strerror(errno)); + else { + handle_packet(packet, len, &sender, &udp_sinfo); + } + } else if(FD_ISSET(tcp_sinfo.sock, &socket_mask)) { + struct sockaddr from; + int from_len = sizeof(from); + int new_sock = accept(tcp_sinfo.sock, (struct sockaddr*)&from, + (socklen_t*)&from_len); + + if(new_sock < 0) { + traceEvent(TRACE_WARNING, "TCP connection accept() failed [%s]\n", strerror(errno)); + } else { + startTcpReadThread(new_sock); + } + } + } + + purge_expired_registrations( &known_peers ); + } /* while */ + + closesocket(udp_sinfo.sock); + closesocket(tcp_sinfo.sock); + + return(0); +} diff --git a/bundles/n2n_meyerd/n2n_v1/tuntap_freebsd.c b/bundles/n2n_meyerd/n2n_v1/tuntap_freebsd.c new file mode 100644 index 00000000..95308be4 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/tuntap_freebsd.c @@ -0,0 +1,125 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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 see see + */ + +#include "n2n.h" + +#ifdef __FreeBSD__ + +void tun_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_FREEBSD_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tun_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +#endif diff --git a/bundles/n2n_meyerd/n2n_v1/tuntap_linux.c b/bundles/n2n_meyerd/n2n_v1/tuntap_linux.c new file mode 100644 index 00000000..a1d20fba --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/tuntap_linux.c @@ -0,0 +1,122 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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, see +*/ + +#include "n2n.h" + +#ifdef __linux__ + +static void read_mac(char *ifname, char *mac_addr) { + int _sock, res; + struct ifreq ifr; + macstr_t mac_addr_buf; + + memset (&ifr,0,sizeof(struct ifreq)); + + /* Dummy socket, just to make ioctls with */ + _sock=socket(PF_INET, SOCK_DGRAM, 0); + strcpy(ifr.ifr_name, ifname); + res = ioctl(_sock,SIOCGIFHWADDR,&ifr); + if (res<0) { + perror ("Get hw addr"); + } else + memcpy(mac_addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6); + + traceEvent(TRACE_NORMAL, "Interface %s has MAC %s", + ifname, + macaddr_str(mac_addr, mac_addr_buf, sizeof(mac_addr_buf))); + close(_sock); +} + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver then uses ifconfig + * to configure address/mask and MTU. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + char *tuntap_device = "/dev/net/tun"; +#define N2N_LINUX_SYSTEMCMD_SIZE 128 + char buf[N2N_LINUX_SYSTEMCMD_SIZE]; + struct ifreq ifr; + int rc; + + device->fd = open(tuntap_device, O_RDWR); + if(device->fd < 0) { + printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), errno); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); + + if(rc < 0) { + traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + + if ( device_mac ) + { + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s hw ether %s", + ifr.ifr_name, device_mac ); + system(buf); + traceEvent(TRACE_INFO, "Setting MAC: %s", buf); + } + + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", + ifr.ifr_name, device_ip, device_mask, mtu); + system(buf); + traceEvent(TRACE_INFO, "Bringing up: %s", buf); + + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + read_mac(dev, (char*)device->mac_addr); + return(device->fd); +} + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +#endif /* #ifdef __linux__ */ diff --git a/bundles/n2n_meyerd/n2n_v1/tuntap_osx.c b/bundles/n2n_meyerd/n2n_v1/tuntap_osx.c new file mode 100644 index 00000000..5a785bde --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/tuntap_osx.c @@ -0,0 +1,125 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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 see see + */ + +#include "n2n.h" + +#ifdef _DARWIN_ + +void tuntap_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_OSX_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_OSX_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +#endif diff --git a/bundles/n2n_meyerd/n2n_v1/twofish.c b/bundles/n2n_meyerd/n2n_v1/twofish.c new file mode 100644 index 00000000..73a1a8e0 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/twofish.c @@ -0,0 +1,1031 @@ +/* $Id: twofish.c,v 2.0 2002/08/11 22:32:25 fknobbe Exp $ + * + * + * Copyright (C) 1997-2000 The Cryptix Foundation Limited. + * Copyright (C) 2000 Farm9. + * Copyright (C) 2001 Frank Knobbe. + * All rights reserved. + * + * For Cryptix code: + * Use, modification, copying and distribution of this software is subject + * the terms and conditions of the Cryptix General Licence. You should have + * received a copy of the Cryptix General Licence along with this library; + * if not, you can download a copy from http://www.cryptix.org/ . + * + * For Farm9: + * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and + * ciphertext stealing technique, added AsciiTwofish class for easy encryption + * decryption of text strings + * + * Frank Knobbe : + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_SOURCE__ +#define __TWOFISH_LIBRARY_SOURCE__ + +#include +#include +#include +#include +#include +#include "twofish.h" + + +bool TwoFish_srand=TRUE; /* if TRUE, first call of TwoFishInit will seed rand(); */ +/* of TwoFishInit */ + +/* Fixed 8x8 permutation S-boxes */ +static const u_int8_t TwoFish_P[2][256] = + { + { /* p0 */ + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0 + }, + { /* p1 */ + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 + } + }; + +static bool TwoFish_MDSready=FALSE; +static u_int32_t TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */ + + +#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0)) +#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0)) + +#define TwoFish_Mx_1(x) ((u_int32_t)(x)) /* force result to dword so << will work */ +#define TwoFish_Mx_X(x) ((u_int32_t)((x)^TwoFish_LFSR2(x))) /* 5B */ +#define TwoFish_Mx_Y(x) ((u_int32_t)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */ +#define TwoFish_RS_rem(x) { u_int8_t b=(u_int8_t)(x>>24); u_int32_t g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; u_int32_t g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; } + +/*#define TwoFish__b(x,N) (((u_int8_t *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */ + +#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of u_int32_t */ +#define TwoFish_b1(x) TwoFish__b(x,1) +#define TwoFish_b2(x) TwoFish__b(x,2) +#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of u_int32_t */ + +u_int8_t TwoFish__b(u_int32_t x,int n) +{ n&=3; + while(n-->0) + x>>=8; + return (u_int8_t)x; +} + + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ + +TWOFISH *TwoFishInit(const u_int8_t *userkey, u_int32_t keysize) +{ TWOFISH *tfdata; + int i,x,m; + u_int8_t tkey[TwoFish_KEY_LENGTH+40]; + + memset( tkey, 0, TwoFish_KEY_LENGTH+40 ); + tfdata=(TWOFISH *)malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */ + if(tfdata!=NULL) + { + + /* Changes here prevented a dangerous random key segment for keys of length < TwoFish_KEY_LENGTH */ + if(keysize > 0) + { + memcpy( tkey, userkey, keysize ); /* The rest will be zeros */ + } + else + { + memcpy( tkey, TwoFish_DEFAULT_PW, TwoFish_DEFAULT_PW_LEN ); /* if no key defined, use default password */ + } + + /* This loop is awful - surely a loop on memcpy() would be clearer and more efficient */ + for(i=0,x=0,m=keysize;ikey[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */ + if(x==m) + x=0; + } + + if(!TwoFish_MDSready) + _TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */ + _TwoFish_MakeSubKeys(tfdata); /* generate subkeys */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC */ + tfdata->output=NULL; /* nothing to output yet */ + tfdata->dontflush=FALSE; /* reset decrypt skip block flag */ + if(TwoFish_srand) + { + TwoFish_srand=FALSE; + /* REVISIT: BbMaj7 : Should choose something with less predictability + * particularly for embedded targets with no real-time clock. */ + srand((unsigned int)time(NULL)); + } + } + return tfdata; /* return the data pointer */ +} + + +void TwoFishDestroy(TWOFISH *tfdata) +{ if(tfdata!=NULL) + free(tfdata); +} + + +/* en/decryption with CBC mode */ +u_int32_t _TwoFish_CryptRawCBC(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata) +{ u_int32_t rl; + + rl=len; /* remember how much data to crypt. */ + while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */ + { _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */ + in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */ + out+=TwoFish_BLOCK_SIZE; + len-=TwoFish_BLOCK_SIZE; + } + if(len>0) /* if we have less than a block left... */ + _TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */ + if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */ + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */ + /* ...remaining bytes of the buffer */ + return rl; +} + +/* en/decryption on one block only */ +u_int32_t _TwoFish_CryptRaw16(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata) +{ /* qBlockPlain already zero'ed through ResetCBC */ + memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */ + _TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */ + memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */ + return TwoFish_BLOCK_SIZE; +} + +/* en/decryption without reset of CBC and output assignment */ +u_int32_t _TwoFish_CryptRaw(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata) +{ + if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */ + { if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */ + return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */ + else + return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */ + } + return 0; +} + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +u_int32_t TwoFishEncryptRaw(u_int8_t *in, + u_int8_t *out, + u_int32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */ +} + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +u_int32_t TwoFishDecryptRaw(u_int8_t *in, + u_int8_t *out, + u_int32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */ +} + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishFree(TWOFISH *tfdata) +{ if(tfdata->output!=NULL) /* if a valid buffer is present... */ + { free(tfdata->output); /* ...then we free it for you... */ + tfdata->output=NULL; /* ...and mark as such. */ + } +} + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishSetOutput(u_int8_t *outp,TWOFISH *tfdata) +{ tfdata->output=outp; /* (do we really need a function for this?) */ +} + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer that would be required + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ + +void *TwoFishAlloc(u_int32_t len,bool binhex,bool decrypt,TWOFISH *tfdata) +{ + /* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */ + if(decrypt) /* if decrypting... */ + { if(binhex) /* ...and input is binhex encoded... */ + len/=2; /* ...use half as much for output. */ + len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */ + } + else + { len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */ + if(binhex) + len*=2; /* ...and doubled if output is to be binhexed. */ + } + tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */ + + return tfdata->output; /* ...and return to caller. */ +} + +/* bin2hex and hex2bin conversion */ +void _TwoFish_BinHex(u_int8_t *buf,u_int32_t len,bool bintohex) +{ u_int8_t *pi,*po,c; + + if(bintohex) + { for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */ + { c=*pi; /* grab value. */ + c&=15; /* use lower 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po--=c; /* set the lower nibble. */ + c=*pi; /* grab value again. */ + c>>=4; /* right shift 4 bits. */ + c&=15; /* make sure we only have 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po=c; /* set the higher nibble. */ + } /* and keep going. */ + } + else + { for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */ + { c=tolower(*pi++)-'0'; /* grab higher nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po=c<<4; /* left shit 4 bits. */ + c=tolower(*pi)-'0'; /* grab lower nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po|=c; /* and add to value. */ + } + } +} + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +u_int32_t TwoFishEncrypt(u_int8_t *in, + u_int8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ u_int32_t ilen,olen; + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { tfdata->output=*out; /* set output buffer. */ + tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */ + tfdata->header.length[0]= (u_int8_t)(ilen); + tfdata->header.length[1]= (u_int8_t)(ilen>>8); + tfdata->header.length[2]= (u_int8_t)(ilen>>16); + tfdata->header.length[3]= (u_int8_t)(ilen>>24); + memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */ + olen=TwoFish_BLOCK_SIZE; /* set output counter. */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag */ + _TwoFish_BlockCrypt((u_int8_t *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */ + olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */ + if(binhex) /* if binhex... */ + { _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */ + olen*=2; /* ...and size twice as large. */ + } + tfdata->output=*out; + return olen; + } + } + return 0; +} + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +u_int32_t TwoFishDecrypt(u_int8_t *in, + u_int8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ u_int32_t ilen,elen,olen; + const u_int8_t cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC; + u_int8_t *tbuf; + + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { if(binhex) /* if binhex... */ + { _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */ + ilen/=2; /* ...and size half as much. */ + } + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */ + + tbuf=(u_int8_t *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */ + if(tbuf==NULL) + return 0; + tfdata->output=tbuf; /* set output to temp buffer. */ + + olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */ + memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */ + tfdata->output=*out; + for(elen=0;elenheader.magic[elen]!=cmagic[elen]) + break; + if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */ + { elen=(tfdata->header.length[0]) | + (tfdata->header.length[1])<<8 | + (tfdata->header.length[2])<<16 | + (tfdata->header.length[3])<<24; /* .. we know how much to expect. */ + if(elen>olen) /* adjust if necessary. */ + elen=olen; + memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */ + free(tbuf); + return elen; + } + free(tbuf); + } + } + return 0; +} + +void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */ +{ u_int32_t m1[2]; + u_int32_t mX[2]; + u_int32_t mY[2]; + u_int32_t i, j; + + for (i = 0; i < 256; i++) + { j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */ + m1[0] = j; + mX[0] = TwoFish_Mx_X( j ) & 0xFF; + mY[0] = TwoFish_Mx_Y( j ) & 0xFF; + + j = TwoFish_P[1][i] & 0xFF; + m1[1] = j; + mX[1] = TwoFish_Mx_X( j ) & 0xFF; + mY[1] = TwoFish_Mx_Y( j ) & 0xFF; + + TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */ + mX[TwoFish_P_00] << 8 | + mY[TwoFish_P_00] << 16 | + mY[TwoFish_P_00] << 24; + TwoFish_MDS[1][i] = mY[TwoFish_P_10] | + mY[TwoFish_P_10] << 8 | + mX[TwoFish_P_10] << 16 | + m1[TwoFish_P_10] << 24; + TwoFish_MDS[2][i] = mX[TwoFish_P_20] | + mY[TwoFish_P_20] << 8 | + m1[TwoFish_P_20] << 16 | + mY[TwoFish_P_20] << 24; + TwoFish_MDS[3][i] = mX[TwoFish_P_30] | + m1[TwoFish_P_30] << 8 | + mY[TwoFish_P_30] << 16 | + mX[TwoFish_P_30] << 24; + } + TwoFish_MDSready=TRUE; +} + + +void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */ +{ u_int32_t k64Cnt = TwoFish_KEY_LENGTH / 8; + u_int32_t k32e[4]; /* even 32-bit entities */ + u_int32_t k32o[4]; /* odd 32-bit entities */ + u_int32_t sBoxKey[4]; + u_int32_t offset,i,j; + u_int32_t A, B, q=0; + u_int32_t k0,k1,k2,k3; + u_int32_t b0,b1,b2,b3; + + /* split user key material into even and odd 32-bit entities and */ + /* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */ + + + for (offset=0,i=0,j=k64Cnt-1;i<4 && offsetkey[offset++]; + k32e[i]|= tfdata->key[offset++]<<8; + k32e[i]|= tfdata->key[offset++]<<16; + k32e[i]|= tfdata->key[offset++]<<24; + k32o[i] = tfdata->key[offset++]; + k32o[i]|= tfdata->key[offset++]<<8; + k32o[i]|= tfdata->key[offset++]<<16; + k32o[i]|= tfdata->key[offset++]<<24; + sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */ + } + + /* compute the round decryption subkeys for PHT. these same subkeys */ + /* will be used in encryption but will be applied in reverse order. */ + i=0; + while(i < TwoFish_TOTAL_SUBKEYS) + { A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */ + q += TwoFish_SK_BUMP; + + B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */ + q += TwoFish_SK_BUMP; + + B = B << 8 | B >> 24; + + A += B; + tfdata->subKeys[i++] = A; /* combine with a PHT */ + + A += B; + tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL); + } + + /* fully expand the table for speed */ + k0 = sBoxKey[0]; + k1 = sBoxKey[1]; + k2 = sBoxKey[2]; + k3 = sBoxKey[3]; + + for (i = 0; i < 256; i++) + { b0 = b1 = b2 = b3 = i; + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)]; + tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)]; + tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)]; + tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3); + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys */ + tfdata->sBox[ 2*i ]= + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^ + TwoFish_b0(k1)]) ^ TwoFish_b0(k0)]; + + tfdata->sBox[ 2*i+1]= + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^ + TwoFish_b1(k1)]) ^ TwoFish_b1(k0)]; + + tfdata->sBox[0x200+2*i ]= + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^ + TwoFish_b2(k1)]) ^ TwoFish_b2(k0)]; + + tfdata->sBox[0x200+2*i+1]= + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^ + TwoFish_b3(k1)]) ^ TwoFish_b3(k0)]; + } + } +} + + +/** + * Encrypt or decrypt exactly one block of plaintext in CBC mode. + * Use "ciphertext stealing" technique described on pg. 196 + * of "Applied Cryptography" to encrypt the final partial + * (i.e. <16 byte) block if necessary. + * + * jojo: the "ciphertext stealing" requires we read ahead and have + * special handling for the last two blocks. Because of this, the + * output from the TwoFish algorithm is handled internally here. + * It would be better to have a higher level handle this as well as + * CBC mode. Unfortunately, I've mixed the two together, which is + * pretty crappy... The Java version separates these out correctly. + * + * fknobbe: I have reduced the CBC mode to work on memory buffer only. + * Higher routines should use an intermediate buffer and handle + * their output seperately (mainly so the data can be flushed + * in one chunk, not seperate 16 byte blocks...) + * + * @param in The plaintext. + * @param out The ciphertext + * @param size how much to encrypt + * @param tfdata: Pointer to the global data structure containing session keys. + * @return none + */ +void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,u_int32_t size,int decrypt,TWOFISH *tfdata) +{ u_int8_t PnMinusOne[TwoFish_BLOCK_SIZE]; + u_int8_t CnMinusOne[TwoFish_BLOCK_SIZE]; + u_int8_t CBCplusCprime[TwoFish_BLOCK_SIZE]; + u_int8_t Pn[TwoFish_BLOCK_SIZE]; + u_int8_t *p,*pout; + u_int32_t i; + + /* here is where we implement CBC mode and cipher block stealing */ + if(size==TwoFish_BLOCK_SIZE) + { /* if we are encrypting, CBC means we XOR the plain text block with the */ + /* previous cipher text block before encrypting */ + if(!decrypt && tfdata->qBlockDefined) + { for(p=in,i=0;iqBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */ + } + else + memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */ + + /* TwoFish block level encryption or decryption */ + _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); + + /* if we are decrypting, CBC means we XOR the result of the decryption */ + /* with the previous cipher text block to get the resulting plain text */ + if(decrypt && tfdata->qBlockDefined) + { for (p=out,i=0;iqBlockPlain[i]; + } + + /* save the input and output blocks, since CBC needs these for XOR */ + /* operations */ + _TwoFish_qBlockPush(Pn,out,tfdata); + } + else + { /* cipher block stealing, we are at Pn, */ + /* but since Cn-1 must now be replaced with CnC' */ + /* we pop it off, and recalculate Cn-1 */ + + if(decrypt) + { /* We are on an odd block, and had to do cipher block stealing, */ + /* so the PnMinusOne has to be derived differently. */ + + /* First we decrypt it into CBC and C' */ + _TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata); + + /* we then xor the first few bytes with the "in" bytes (Cn) */ + /* to recover Pn, which we put in out */ + for(p=in,pout=out,i=0;iprevCipher[i]; + + /* So at this point, out has PnMinusOne */ + _TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(out,size,tfdata); + } + else + { _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata); + memset(Pn,0,TwoFish_BLOCK_SIZE); + memcpy(Pn,in,size); + for(i=0;iqBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */ + } + tfdata->qBlockDefined=FALSE; + } +} + +void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata) +{ if(tfdata->qBlockDefined) + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE); + tfdata->qBlockDefined=TRUE; +} + +void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata) +{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE ); + memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE ); + tfdata->qBlockDefined=FALSE; +} + +/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */ +void _TwoFish_ResetCBC(TWOFISH *tfdata) +{ tfdata->qBlockDefined=FALSE; + memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE); +} + +void _TwoFish_FlushOutput(u_int8_t *b,u_int32_t len,TWOFISH *tfdata) +{ u_int32_t i; + + for(i=0;idontflush;i++) + *tfdata->output++ = *b++; + tfdata->dontflush=FALSE; +} + +void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata) +{ u_int32_t x0,x1,x2,x3; + u_int32_t k,t0,t1,R; + + + x0=*in++; + x0|=(*in++ << 8 ); + x0|=(*in++ << 16); + x0|=(*in++ << 24); + x1=*in++; + x1|=(*in++ << 8 ); + x1|=(*in++ << 16); + x1|=(*in++ << 24); + x2=*in++; + x2|=(*in++ << 8 ); + x2|=(*in++ << 16); + x2|=(*in++ << 24); + x3=*in++; + x3|=(*in++ << 8 ); + x3|=(*in++ << 16); + x3|=(*in++ << 24); + + if(decrypt) + { x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */ + x1 ^= tfdata->subKeys[5]; + x2 ^= tfdata->subKeys[6]; + x3 ^= tfdata->subKeys[7]; + + k = 7+(TwoFish_ROUNDS*2); + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x3 = x3 >> 1 | x3 << 31; + x2 = x2 << 1 | x2 >> 31; + x2 ^= t0 + t1 + tfdata->subKeys[k--]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x1 = x1 >> 1 | x1 << 31; + x0 = x0 << 1 | x0 >> 31; + x0 ^= t0 + t1 + tfdata->subKeys[k--]; + } + + x2 ^= tfdata->subKeys[0]; + x3 ^= tfdata->subKeys[1]; + x0 ^= tfdata->subKeys[2]; + x1 ^= tfdata->subKeys[3]; + } + else + { x0 ^= tfdata->subKeys[0]; + x1 ^= tfdata->subKeys[1]; + x2 ^= tfdata->subKeys[2]; + x3 ^= tfdata->subKeys[3]; + + k = 8; + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x2 ^= t0 + t1 + tfdata->subKeys[k++]; + x2 = x2 >> 1 | x2 << 31; + x3 = x3 << 1 | x3 >> 31; + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x0 ^= t0 + t1 + tfdata->subKeys[k++]; + x0 = x0 >> 1 | x0 << 31; + x1 = x1 << 1 | x1 >> 31; + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + } + + x2 ^= tfdata->subKeys[4]; + x3 ^= tfdata->subKeys[5]; + x0 ^= tfdata->subKeys[6]; + x1 ^= tfdata->subKeys[7]; + } + + *out++ = (u_int8_t)(x2 ); + *out++ = (u_int8_t)(x2 >> 8); + *out++ = (u_int8_t)(x2 >> 16); + *out++ = (u_int8_t)(x2 >> 24); + + *out++ = (u_int8_t)(x3 ); + *out++ = (u_int8_t)(x3 >> 8); + *out++ = (u_int8_t)(x3 >> 16); + *out++ = (u_int8_t)(x3 >> 24); + + *out++ = (u_int8_t)(x0 ); + *out++ = (u_int8_t)(x0 >> 8); + *out++ = (u_int8_t)(x0 >> 16); + *out++ = (u_int8_t)(x0 >> 24); + + *out++ = (u_int8_t)(x1 ); + *out++ = (u_int8_t)(x1 >> 8); + *out++ = (u_int8_t)(x1 >> 16); + *out++ = (u_int8_t)(x1 >> 24); +} + +/** + * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box + * 32-bit entity from two key material 32-bit entities. + * + * @param k0 1st 32-bit entity. + * @param k1 2nd 32-bit entity. + * @return Remainder polynomial generated using RS code + */ +u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1) +{ u_int32_t i,r; + + for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */ + TwoFish_RS_rem(r); + r ^= k0; + for(i=0;i<4;i++) + TwoFish_RS_rem(r); + + return r; +} + +u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32) +{ u_int8_t b0,b1,b2,b3; + u_int32_t k0,k1,k2,k3,result = 0; + + b0=TwoFish_b0(x); + b1=TwoFish_b1(x); + b2=TwoFish_b2(x); + b3=TwoFish_b3(x); + k0=k32[0]; + k1=k32[1]; + k2=k32[2]; + k3=k32[3]; + + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3); + + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys (optimize for this case) */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)]; + break; + } + return result; +} + +u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x) +{ return lsBox[ TwoFish_b0(x)<<1 ]^ + lsBox[ ((TwoFish_b1(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b2(x)<<1) ]^ + lsBox[0x200+((TwoFish_b3(x)<<1)|1)]; +} + +u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x) +{ return lsBox[ (TwoFish_b3(x)<<1) ]^ + lsBox[ ((TwoFish_b0(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b1(x)<<1) ]^ + lsBox[0x200+((TwoFish_b2(x)<<1)|1)]; +} + +u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R) +{ return lsBox[ 2*TwoFish__b(x,R ) ]^ + lsBox[ 2*TwoFish__b(x,R+1)+1]^ + lsBox[0x200+2*TwoFish__b(x,R+2) ]^ + lsBox[0x200+2*TwoFish__b(x,R+3)+1]; +} + + +#endif + +/* ******************************************* */ +#if defined TWOFISH_UNIT_TEST +#include + +#define TEST_DATA_SIZE 327 + +int main(int argc, char* argv[]) +{ + int i; + int n; + + char outbuf[4096]; + char * outp = outbuf; + + u_int8_t key[] = { 0xfc, 0x77, 0x1a, 0xda, 0xaa }; + TWOFISH *tfa = TwoFishInit( key, 5 ); + TWOFISH *tfb = TwoFishInit( key, 5 ); + + u_int8_t out[2048], out2[2048]; + u_int8_t in[TEST_DATA_SIZE]; + + for ( i=0; i: + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_HEADER__ +#define __TWOFISH_LIBRARY_HEADER__ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !FALSE +#endif +#ifndef bool +#define bool int +#endif + +#ifdef WIN32 +#include "win32/n2n_win32.h" +#endif + +/* Constants */ + +#define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */ +#define TwoFish_DEFAULT_PW_LEN 32 +#define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */ + +enum +{ TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */ + /* User 256, other key sizes have not been tested. */ + /* (But should work. I substitutes as much as */ + /* I could with this define.) */ + TwoFish_ROUNDS = 16, + TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */ + TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */ + TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS, + TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8, + TwoFish_SK_BUMP = 0x01010101, + TwoFish_SK_ROTL = 9, + TwoFish_P_00 = 1, + TwoFish_P_01 = 0, + TwoFish_P_02 = 0, + TwoFish_P_03 = TwoFish_P_01 ^ 1, + TwoFish_P_04 = 1, + TwoFish_P_10 = 0, + TwoFish_P_11 = 0, + TwoFish_P_12 = 1, + TwoFish_P_13 = TwoFish_P_11 ^ 1, + TwoFish_P_14 = 0, + TwoFish_P_20 = 1, + TwoFish_P_21 = 1, + TwoFish_P_22 = 0, + TwoFish_P_23 = TwoFish_P_21 ^ 1, + TwoFish_P_24 = 0, + TwoFish_P_30 = 0, + TwoFish_P_31 = 1, + TwoFish_P_32 = 1, + TwoFish_P_33 = TwoFish_P_31 ^ 1, + TwoFish_P_34 = 1, + TwoFish_GF256_FDBK = 0x169, + TwoFish_GF256_FDBK_2 = 0x169 / 2, + TwoFish_GF256_FDBK_4 = 0x169 / 4, + TwoFish_RS_GF_FDBK = 0x14D, /* field generator */ + TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */ +}; + + +/* Global data structure for callers */ + +typedef struct +{ + u_int32_t sBox[4 * 256]; /* Key dependent S-box */ + u_int32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */ + u_int8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */ + u_int8_t *output; /* Pointer to output buffer */ + u_int8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */ + u_int8_t qBlockCrypt[TwoFish_BLOCK_SIZE]; + u_int8_t prevCipher[TwoFish_BLOCK_SIZE]; + struct /* Header for crypt functions. Has to be at least one block long. */ + { u_int32_t salt; /* Random salt in first block (will salt the rest through CBC) */ + u_int8_t length[4]; /* The amount of data following the header */ + u_int8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */ + } header; + bool qBlockDefined; + bool dontflush; +} TWOFISH; + +#ifndef __TWOFISH_LIBRARY_SOURCE__ + +extern bool TwoFish_srand; /* if set to TRUE (default), first call of TwoFishInit will seed rand(); */ + /* call of TwoFishInit */ +#endif + + +/**** Public Functions ****/ + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ +TWOFISH *TwoFishInit(const u_int8_t *userkey, u_int32_t keysize ); + + +/* TwoFish Destroy + * + * Nothing else but a free... + * + * Input: Pointer to the TwoFish structure. + * + */ +void TwoFishDestroy(TWOFISH *tfdata); + + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer as required. + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ +void *TwoFishAlloc(u_int32_t len,bool binhex,bool decrypt,TWOFISH *tfdata); + + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishFree(TWOFISH *tfdata); + + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishSetOutput(u_int8_t *outp,TWOFISH *tfdata); + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +u_int32_t TwoFishEncryptRaw(u_int8_t *in,u_int8_t *out,u_int32_t len,TWOFISH *tfdata); + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +u_int32_t TwoFishDecryptRaw(u_int8_t *in,u_int8_t *out,u_int32_t len,TWOFISH *tfdata); + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +u_int32_t TwoFishEncrypt(u_int8_t *in,u_int8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +u_int32_t TwoFishDecrypt(u_int8_t *in,u_int8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/**** Private Functions ****/ + +u_int8_t TwoFish__b(u_int32_t x,int n); +void _TwoFish_BinHex(u_int8_t *buf,u_int32_t len,bool bintohex); +u_int32_t _TwoFish_CryptRawCBC(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata); +u_int32_t _TwoFish_CryptRaw16(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata); +u_int32_t _TwoFish_CryptRaw(u_int8_t *in,u_int8_t *out,u_int32_t len,bool decrypt,TWOFISH *tfdata); +void _TwoFish_PrecomputeMDSmatrix(void); +void _TwoFish_MakeSubKeys(TWOFISH *tfdata); +void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata); +void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata); +void _TwoFish_ResetCBC(TWOFISH *tfdata); +void _TwoFish_FlushOutput(u_int8_t *b,u_int32_t len,TWOFISH *tfdata); +void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,u_int32_t size,int decrypt,TWOFISH *tfdata); +void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata); +u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1); +u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32); +u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x); +u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x); +u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R); + + +#endif diff --git a/bundles/n2n_meyerd/n2n_v1/version.c b/bundles/n2n_meyerd/n2n_v1/version.c new file mode 100644 index 00000000..42f43c12 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/version.c @@ -0,0 +1,3 @@ +const char * version = N2N_VERSION; +const char * osName = N2N_OSNAME; +const char * buildDate = __DATE__ " " __TIME__; diff --git a/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.sln b/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.sln new file mode 100644 index 00000000..024d46a9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge", "n2n.vcproj", "{4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "supernode", "supernode\supernode.vcproj", "{1F7F0E45-7DE9-4CE2-845F-38D59C2E4F51}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.Build.0 = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.ActiveCfg = Release|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.Build.0 = Release|Win32 + {1F7F0E45-7DE9-4CE2-845F-38D59C2E4F51}.Debug|Win32.ActiveCfg = Debug|Win32 + {1F7F0E45-7DE9-4CE2-845F-38D59C2E4F51}.Debug|Win32.Build.0 = Debug|Win32 + {1F7F0E45-7DE9-4CE2-845F-38D59C2E4F51}.Release|Win32.ActiveCfg = Release|Win32 + {1F7F0E45-7DE9-4CE2-845F-38D59C2E4F51}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.suo b/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.suo new file mode 100644 index 0000000000000000000000000000000000000000..aae212bdc7603fcc776941462dec540d87901d0e GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.vcproj b/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.vcproj new file mode 100644 index 00000000..25370024 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/DotNet/n2n.vcproj @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_meyerd/n2n_v1/win32/getopt.c b/bundles/n2n_meyerd/n2n_v1/win32/getopt.c new file mode 100644 index 00000000..6bbb735a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/getopt.c @@ -0,0 +1,1074 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include +#ifdef WIN32 +#include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT<_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +#ifndef DARWIN +char *optarg; +#endif + + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +#ifndef DARWIN +int optind = 1; +#endif + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +#ifndef DARWIN +#ifdef WIN32 +int opterr = 0; +#else +int opterr = 1; +#endif +#endif + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ +#ifndef DARWIN +int optopt = '?'; +#endif + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +#ifndef WIN32 +# if HAVE_STRING_H +# include +# else +# include +# endif +#endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt____ (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ + diff --git a/bundles/n2n_meyerd/n2n_v1/win32/getopt.h b/bundles/n2n_meyerd/n2n_v1/win32/getopt.h new file mode 100644 index 00000000..b0147e9d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/bundles/n2n_meyerd/n2n_v1/win32/getopt1.c b/bundles/n2n_meyerd/n2n_v1/win32/getopt1.c new file mode 100644 index 00000000..3d264f2d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/getopt1.c @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/bundles/n2n_meyerd/n2n_v1/win32/n2n_win32.h b/bundles/n2n_meyerd/n2n_v1/win32/n2n_win32.h new file mode 100644 index 00000000..36f8ed36 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/n2n_win32.h @@ -0,0 +1,74 @@ +/* + + (C) 2007 - Luca Deri + +*/ + +#ifndef _N2N_WIN32_H_ +#define _N2N_WIN32_H_ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "wintap.h" + +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +typedef unsigned char u_int8_t; +typedef int int32_t; +typedef short int16_t; +typedef char int8_t; + +#define snprintf _snprintf +#define strdup _strdup + +#define socklen_t int + +#define ETHER_ADDR_LEN 6 +/* + * Structure of a 10Mb/s Ethernet header. + */ +struct ether_header { + u_char ether_dhost[ETHER_ADDR_LEN]; + u_char ether_shost[ETHER_ADDR_LEN]; + u_short ether_type; +}; + +/* ************************************* */ + +struct ip { +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#else + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif + u_char ip_tos; /* type of service */ + short ip_len; /* total length */ + u_short ip_id; /* identification */ + short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + + +/* ************************************* */ + +typedef struct tuntap_dev { + HANDLE device_handle; + char *device_name; + char *ifName; + OVERLAPPED overlap_read, overlap_write; + u_int8_t mac_addr[6]; + u_int32_t ip_addr, device_mask; + u_int mtu; +} tuntap_dev; + +#endif \ No newline at end of file diff --git a/bundles/n2n_meyerd/n2n_v1/win32/wintap.c b/bundles/n2n_meyerd/n2n_v1/win32/wintap.c new file mode 100644 index 00000000..503e4e16 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/wintap.c @@ -0,0 +1,283 @@ +/* + (C) 2007-08 - Luca Deri +*/ + +#include "../n2n.h" +#include "n2n_win32.h" + +/* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 1518 + +void initWin32() { + WSADATA wsaData; + int err; + + err = WSAStartup(MAKEWORD(2, 2), &wsaData ); + if( err != 0 ) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("FATAL ERROR: unable to initialise Winsock 2.x."); + exit(-1); + } +} + +int open_wintap(struct tuntap_dev *device, + char *device_ip, char *device_mask, + char *device_mac, int mtu) { + HKEY key, key2; + LONG rc; + char regpath[1024], cmd[256]; + char adapterid[1024]; + char adaptername[1024]; + char tapname[1024]; + long len; + int found = 0; + int err, i; + ULONG status = TRUE; + + memset(device, 0, sizeof(struct tuntap_dev)); + device->device_handle = INVALID_HANDLE_VALUE; + device->device_name = NULL; + device->ifName = NULL; + device->ip_addr = inet_addr(device_ip); + + /* Open registry and look for network adapters */ + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: [rc=%d]\n", rc); + exit(-1); + } + + for (i = 0; ; i++) { + len = sizeof(adapterid); + if(RegEnumKeyEx(key, i, (LPCWSTR)adapterid, &len, 0, 0, 0, NULL)) + break; + + /* Find out more about this adapter */ + + _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adaptername); + err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); + + RegCloseKey(key2); + + if(err) + continue; + + if(device->device_name) { + if(!strcmp(device->device_name, adapterid)) { + found = 1; + break; + } else + continue; + } + + if(device->ifName) { + if(!strcmp(device->ifName, adaptername)) { + found = 1; + break; + } else + continue; + } + + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, + 0, /* Don't let other processes share or open + the resource until the handle's been closed */ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(device->device_handle != INVALID_HANDLE_VALUE) { + found = 1; + break; + } + } + + RegCloseKey(key); + + if(!found) { + printf("No Windows tap device found!\n"); + exit(0); + } + + /* ************************************** */ + + if(!device->device_name) + device->device_name = _strdup(adapterid); + + if(!device->ifName) + device->ifName = _strdup(adaptername); + + /* Try to open the corresponding tap device->device_name */ + + if(device->device_handle == INVALID_HANDLE_VALUE) { + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device->device_name); + device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + } + + if(device->device_handle == INVALID_HANDLE_VALUE) { + printf("%s (%s) is not a usable Windows tap device\n", device->device_name, device->ifName); + exit(-1); + } + + /* Get MAC address from tap device->device_name */ + + if(!DeviceIoControl(device->device_handle, TAP_IOCTL_GET_MAC, + device->mac_addr, sizeof(device->mac_addr), + device->mac_addr, sizeof(device->mac_addr), &len, 0)) { + printf("Could not get MAC address from Windows tap %s (%s)\n", + device->device_name, device->ifName); + return -1; + } + + device->mtu = mtu; + + printf("Open device [name=%s][ip=%s][ifName=%s][MTU=%d][mac=%02X:%02X:%02X:%02X:%02X:%02X]\n", + device->device_name, device_ip, device->ifName, device->mtu, + device->mac_addr[0] & 0xFF, + device->mac_addr[1] & 0xFF, + device->mac_addr[2] & 0xFF, + device->mac_addr[3] & 0xFF, + device->mac_addr[4] & 0xFF, + device->mac_addr[5] & 0xFF); + + /* ****************** */ + + printf("Setting %s device address...\n", device->ifName); + + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" static %s %s", + device->ifName, device_ip, device_mask); + + if(system(cmd) == 0) { + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + printf("Device %s set to %s/%s\n", + device->ifName, device_ip, device_mask); + } else + printf("WARNING: Unable to set device %s IP address [%s]\n", + device->ifName, cmd); + + /* ****************** */ + + if(device->mtu != DEFAULT_MTU) + printf("WARNING: MTU set is not supported on Windows\n"); + + /* set driver media status to 'connected' (i.e. set the interface up) */ + if (!DeviceIoControl (device->device_handle, TAP_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), + &status, sizeof (status), &len, NULL)) + printf("WARNING: Unable to enable TAP adapter\n"); + + /* + * Initialize overlapped structures + */ + device->overlap_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device->overlap_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!device->overlap_read.hEvent || !device->overlap_write.hEvent) { + return -1; + } + + return(0); +} + +/* ************************************************ */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD read_size, last_err; + + ResetEvent(tuntap->overlap_read.hEvent); + if (ReadFile(tuntap->device_handle, buf, len, &read_size, &tuntap->overlap_read)) { + //printf("tun_read(len=%d)\n", read_size); + return read_size; + } + switch (last_err = GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_read.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_read, &read_size, FALSE); + return read_size; + break; + default: + printf("GetLastError() returned %d\n", last_err); + break; + } + + return -1; +} +/* ************************************************ */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD write_size; + + //printf("tun_write(len=%d)\n", len); + + ResetEvent(tuntap->overlap_write.hEvent); + if (WriteFile(tuntap->device_handle, + buf, + len, + &write_size, + &tuntap->overlap_write)) { + //printf("DONE tun_write(len=%d)\n", write_size); + return write_size; + } + switch (GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_write.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_write, + &write_size, FALSE); + return write_size; + break; + default: + break; + } + + return -1; +} + +/* ************************************************ */ + +int tuntap_open(tuntap_dev *device, char *dev, char *device_ip, + char *device_mask, const char * device_mac, int mtu) { + return(open_wintap(device, device_ip, device_mask, device_mac, mtu)); +} + +/* ************************************************ */ + +void tuntap_close(struct tuntap_dev *tuntap) { + CloseHandle(tuntap->device_handle); +} + +/* ************************************************ */ + +#if 0 +int main(int argc, char* argv[]) { + struct tuntap_dev tuntap; + int i; + int mtu = 1400; + + printf("Welcome to n2n\n"); + initWin32(); + open_wintap(&tuntap, "1.2.3.20", "255.255.255.0", mtu); + + for(i=0; i<10; i++) { + u_char buf[MTU]; + int rc; + + rc = tun_read(&tuntap, buf, sizeof(buf)); + buf[0]=2; + buf[1]=3; + buf[2]=4; + + printf("tun_read returned %d\n", rc); + rc = tun_write(&tuntap, buf, rc); + printf("tun_write returned %d\n", rc); + } + // rc = tun_open (device->device_name, IF_MODE_TUN); + WSACleanup (); + return(0); +} + +#endif diff --git a/bundles/n2n_meyerd/n2n_v1/win32/wintap.h b/bundles/n2n_meyerd/n2n_v1/win32/wintap.h new file mode 100644 index 00000000..ba83d12e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v1/win32/wintap.h @@ -0,0 +1,67 @@ +/* + (C) 2007 - Luca Deri +*/ + +#ifndef _WINTAP_H_ +#define _WINTAP_H_ + +#undef UNICODE +#undef _UNICODE +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include + + + +//=============================================== +// This file is included both by OpenVPN and +// the TAP-Win32 driver and contains definitions +// common to both. +//=============================================== + +//============= +// TAP IOCTLs +//============= + +#define TAP_CONTROL_CODE(request,method) \ + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + +#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) +#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) +#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) +#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) +#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) +#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) + +//================= +// Registry keys +//================= + +#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +//====================== +// Filesystem prefixes +//====================== + +#define USERMODEDEVICEDIR "\\\\.\\Global\\" +#define SYSDEVICEDIR "\\Device\\" +#define USERDEVICEDIR "\\DosDevices\\Global\\" +#define TAPSUFFIX ".tap" + +//========================================================= +// TAP_COMPONENT_ID -- This string defines the TAP driver +// type -- different component IDs can reside in the system +// simultaneously. +//========================================================= + +#define TAP_COMPONENT_ID "tap0801" + +extern void initWin32(); + +#endif \ No newline at end of file diff --git a/bundles/n2n_meyerd/n2n_v2/CMakeLists.txt b/bundles/n2n_meyerd/n2n_v2/CMakeLists.txt new file mode 100644 index 00000000..75fde2a7 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/CMakeLists.txt @@ -0,0 +1,162 @@ +project(n2n) +cmake_minimum_required(VERSION 2.6) + +# N2n information +set(N2N_VERSION 2.1.0) +set(N2N_OSNAME ${CMAKE_SYSTEM}) + +# N2n specific params +if(NOT DEFINED N2N_OPTION_AES) +if(NOT WIN32) +set(N2N_OPTION_AES ON) +else(NOT WIN32) +set(N2N_OPTIONS_AES OFF) +endif(NOT WIN32) +endif(NOT DEFINED N2N_OPTION_AES) + +add_definitions(-DN2N_VERSION=\"${N2N_VERSION}\" -DN2N_OSNAME=\"${N2N_OSNAME}\") + +if(N2N_OPTION_AES) +add_definitions(-DN2N_HAVE_AES) +endif(N2N_OPTION_AES) + +# Build information +if(NOT DEFINED BUILD_SHARED_LIBS) +set(BUILD_SHARED_LIBS OFF) +endif(NOT DEFINED BUILD_SHARED_LIBS) + +if(NOT DEFINED CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE None) +endif(NOT DEFINED CMAKE_BUILD_TYPE) +#set(CMAKE_BUILD_TYPE Debug) +#set(CMAKE_BUILD_TYPE Release) + +#Ultrasparc64 users experiencing SIGBUS should try the following gcc options +#(thanks to Robert Gibbon) +#PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs + +#for macOS, find openssl installed by Homebrew +# cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .. +if(APPLE) +find_package(openssl REQUIRED) +endif(APPLE) + +# None +if(NOT WIN32) +set(CMAKE_C_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs -fPIC") +set(CMAKE_CXX_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") +# Debug +set(CMAKE_C_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +# Release +set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") +endif(NOT WIN32) + +#for macOS, add openssl include dir +if(APPLE) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${OPENSSL_INCLUDE_DIR}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${OPENSSL_INCLUDE_DIR}") +endif(APPLE) + +## DEBUG FOR CMAKE +#message(${N2N_VERSION}) +#message(${N2N_OSNAME}) +##message(${CMAKE_BUILD_TYPE}) +#message(${N2N_OPTION_AES}) +## DEBUG FOR CMAKE + +add_library(n2n n2n.c + n2n_keyfile.c + wire.c + minilzo.c + twofish.c + transform_null.c + transform_tf.c + transform_aes.c + tuntap_freebsd.c + tuntap_netbsd.c + tuntap_linux.c + tuntap_osx.c + version.c + ) + +if(NOT WIN32) +add_library(scm unix-scm.c) +target_link_libraries(n2n scm) +endif(NOT WIN32) + +if(WIN32) +add_subdirectory(win32) +add_library(scm win32/win-scm.c) +target_link_libraries(n2n n2n_win32) +endif(WIN32) + +if(N2N_OPTION_AES) +target_link_libraries(n2n crypto) +endif(N2N_OPTION_AES) + +# For Solaris (or OpenSolaris?) +#target_link_libraries(n2n socket nsl) + +add_executable(edge edge.c) +target_link_libraries(edge n2n) + +add_executable(supernode sn.c) +target_link_libraries(supernode n2n) + +add_executable(n2n_test n2n_test.c) +target_link_libraries(n2n_test n2n) + +add_executable(benchmark benchmark.c) +target_link_libraries(benchmark n2n) + +add_executable(benchmark_hashtable benchmark_hashtable.c) +target_link_libraries(benchmark_hashtable n2n) + +install(TARGETS edge supernode + RUNTIME DESTINATION sbin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + +# Documentation +if(DEFINED UNIX) +add_dependencies(n2n doc) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/edge.8.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/edge.8 > ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DEPENDS ${PROJECT_SOURCE_DIR}/edge.8 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/supernode.1 > ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DEPENDS ${PROJECT_SOURCE_DIR}/supernode.1 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/n2n_v2.7 > ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz + DEPENDS ${PROJECT_SOURCE_DIR}/n2n_v2.7 + ) + +add_custom_target(doc DEPENDS ${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz + ) + +set_source_files_properties(${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz + PROPERTIES GENERATED 1) + +install(FILES ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DESTINATION /usr/share/man8) +install(FILES ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DESTINATION /usr/share/man1) +install(FILES ${PROJECT_BINARY_DIR}/doc/n2n_v2.7.gz + DESTINATION /usr/share/man7) + +install(PROGRAMS ${PROJECT_SOURCE_DIR}/munin/n2n-supernode + DESTINATION /usr/share/munin/plugins) + +endif(DEFINED UNIX) diff --git a/bundles/n2n_meyerd/n2n_v2/COPYING b/bundles/n2n_meyerd/n2n_v2/COPYING new file mode 100644 index 00000000..b33b35d0 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + n2n Copyright (C) 2007-08 Luca Deri + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_meyerd/n2n_v2/HACKING b/bundles/n2n_meyerd/n2n_v2/HACKING new file mode 100644 index 00000000..0154552b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/HACKING @@ -0,0 +1,259 @@ +file: HACKING + +Last updated: 2010-01-01 09:55 UTC + +-------- +(C) 2008-2010 - Richard Andrews + +This program and document 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 3 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 see see + +-------- + + +This file describes the internals of n2n. Read this before starting to modify +the code. Because coding examples may be present in this document it is licensed +under the GPL rather than FDL. + + +SYMMETRIC NAT +------------- + +Symmetric NAT is a form of firewall NAT in which an UDP packets are only passed +back to an inside host socket when the return packets originate from the outside +socket to which the initiating UDP packets were sent. This means that when an +inside host sends UDP to some outside socket; other hosts cannot piggyback on +this opening in the firewall to send data to the inside host. + +When two inside hosts are both behind symmetric NAT, peer-to-peer packet +exchange is not possible via n2n. These hosts will require the supernode to +relay packets. + + +ARP CACHE +--------- + +n2n makes use of the host operating system's own ARP cache. Each edge node +allocates a random MAC address to itself. This MAC is constant for the life of +the edge process. ARP packets are passed around as broadcast ethernet packets +over n2n and these packets cause the native ARP cache to be updated. + +Edge nodes send gratuitous ARP packets on startup. See GRATUITOUS ARP below. + + +REGISTRATION AND PEER-TO-PEER COMMUNICATION SETUP +------------------------------------------------- + +A and B are edge nodes with public sockets Apub and Bpub; and private network +addresses A and B respectively. S is the supernode. + +A sends {REGISTER,Amac} to S. S registers {Amac->Apub}. +B sends {REGISTER,Bmac} to S. S registers {Bmac->Bpub}. + +Now ping from A to B. + +A sends broadcast "arp who-has B" to S. S relays the packet to all known edge +nodes. B replies "B at Bmac" to supernode which forwards this to A. So now ping +A->B is known to be ping Amac(A)->Bmac(B). Note: gratuitous arp also requires +discussion. + +In response to receiving the arp reply, Apub sends {REGISTER,Amac} to Bpub. If +Bpub receives the request it sends back {REGISTER_ACK,Amac} and also sends its +own {REGISTER,Bmac} request. + +In response to receiving the "arp who-has", Bpub sends {REGISTER,Bmac} to Apub. + +Now the OS has received the arp reply and sends ICMP to Bmac(B) via the tunnel +on A. A looks up Bmac in the peers list and encapsulates the packet to Bpub or +the supernode if the MAC is not found. + +We assume that between two edge nodes, if Bpub receives a packet from Apub then +Apub can receive a packet from Bpub. This is the symmetric NAT case. Note: In +the symmetric NAT case, the public socket for a MAC address will be different +for direct contact when compared to information from the supernode. + +When two edge nodes are both behind symmetric NAT they cannot establish direct +communication. + +If A receives {REGISTER,Bmac} from B, A adds {Bmac->Bpub} to its peers list +knowing that Bmac is now reachable via that public socket. Similarly if B +receives {REGISTER,Amac} from A. + +The supernode never forwards REGISTER messages because the public socket seen by +the supervisor for some edge (eg. A) may be different to the socket seen by +another edge due to the actions of symmetric NAT (alocating a new public socket +for the new outbound UDP "connection"). + + +EDGE REGISTRATION DESIGN AMMENDMENTS (starting from 2008-04-10) +------------------------------------ + + * Send REGISTER on rx of PACKET or REGISTER only when dest_mac == device MAC +(do not send REGISTER on Rx of broadcast packets). + * After sending REGISTER add the new peer to pending_peers list; but + * Don't send REGISTER to a peer in pending_peers list + * Remove old entries from pending_peers at regular intervals + * On rx of REGISTER_ACK, move peer from pending_peers to known_peers for direct +comms and set last_seen=now + * On rx of any packet set last_seen=now in the known_peers entry (if it +exists); but do not add a new entry. + * If the public socket address for a known_peers entry changes, deleted it and +restart registration to the new peer. + * Peer sockets provided by the supernode are ignored unless no other entry +exists. Direct peer-to-peer sockets are always given more priority as the +supernode socket will not be usable for direct contact if the peer is behind +symmetric NAT. + + +The pending_peers list concept is to prevent massive registration traffic when +supernode relay is in force - this would occur if REGISTER was sent for every +incident packet sent via supernode. Periodic REGISTER attempts will still occur; +not for every received packet. In the case where the peer cannot be contacted +(eg. both peers behind symmetric NAT), then there will still be periodic +attempts. Suggest a pending timeout of about 60 sec. + +A peer is only considered operational for peer-to-peer sending when a +REGISTER_ACK is returned. Once operational the peer is kept operational while +any direct packet communications are occurring. REGISTER is not required to +keep the path open through any firewalls; just some activity in one direction. + +After an idle period; the peer should be deleted from the known_peers list. We +should not try to re-register when this time expires. If there is no data to +send then forget the peer. This helps scalability. + +If a peer wants to be remembered it can send gratuitous ARP traffic which will +keep its entry in the known_peers list of any peers which already have the +entry. + + + + +peer = find_by_src_mac( hdr, known_peers ); /* return NULL or entry */ + +if ( peer ) +{ + peer_last_seen = time(NULL); +} +else +{ + if ( ! is_broadcast( hdr ) ) /* ignore broadcasts */ + { + if ( IS_REGISTER_ACK( hdr ) ) + { + /* move from pending to known_peers */ + set_peer_operational( hdr ); + } + else + { + /* add to pending and send REGISTER - ignore if in pending. */ + try_send_register( hdr ) + } + } +} + + +(Notes): + + * In testing it was noted that if a symmetric NAT firewall shuts down the UDP +association but the known_peers registration is still active, then the peer +becomes unreachable until the known_peers registration is deleted. Suggest two +ways to mitigate this problem: + (a) make the known_peers purge timeout a config paramter; + (b) send packets direct and via supernode if the registration is older than + eg. 60 sec. + + +GRATUITOUS ARP +-------------- + +In addition to the ARP who-has mechanism noted above, two edge nodes can become +aware of one another by gratuitous ARP. A gratuitous ARP packet is a broadcast +packet sent by a node for no other purpose than to announce its presence and +identify its MAC and IP address. Gratuitous ARP packets are to keep ARP caches +up to date so contacting the host will be faster after an long idle time. + + +MAN PAGES +--------- + +Look at a non-installed man page like this (linux/UNIX): + +nroff -man edge.8 | less + + +common header FORMAT +-------------------- + +All message encoding and decoding is contained in wire.c. + + 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Version=2 ! TTL ! Flags ! PktType ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Community : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +PACKET message FORMAT +--------------------- + +The PACKET message is of main concern as it is the most frequently transferred +as it contains encapsulated ethernet packets. For these, PktFormat is set to +n2n_packet and it goes on as follows: + +If the N2N_FLAGS_SOCKET-Flag is set, the socket of the original sender of the +packet is encoded next. IPv4 or IPv6 is determined by the Socket Flags. + +Socket encoding for IPv4 takes 8 bytes and looks as follows: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 0 ! Socket Flags (v=IPv4) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Destination IPv4 Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +For IPv6 it takes 20 bytes: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 0 ! Socket Flags (v=IPv6) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Destination IPv6 Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +After that, if the N2N_FLAGS_LOCAL_SOCKET-Flag is set, yet another socket +(using the same format as above) will follow (used for bypassing the +behind-same-nat problem) + +Finally, the last part of the packet looks like this: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Transform ID ! Payload ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 : ... Payload ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 : ... Payload ... + +------- + +January 2010 - Richard Andrews diff --git a/bundles/n2n_meyerd/n2n_v2/INSTALL b/bundles/n2n_meyerd/n2n_v2/INSTALL new file mode 100644 index 00000000..69ca5ac2 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/INSTALL @@ -0,0 +1,63 @@ +New install procedure, using cmake. + +Customize CMakeLists.txt + +$ cmake ./ +$ make + + + + +!!! DEPRECATED !!! + + +INSTALL + +To build the programs: + +$ make + +To install the programs and man pages: + +$ make install + +or + +$ make PREFIX=/usr/local install + + +RPM Package +----------- + +These steps should work with RPM based Linux distributions since rpmbuild was +split from the rpm utility (c RedHat 9). + + +To build an RPM the easy way follow these steps. + +1. Build SRPM + +$ cd n2n +$ scripts/mk_SRPM.sh + +Look for where the src.rpm file was put ( "Wrote:" ). + +2. Build binary RPM from SRPM + +$ rpm -i path/to/n2n-.src.rpm +$ rpmbuild -bb n2n.spec + + +All this can be done as non-root user if you have a ~/.rpmmacros file with this +line in it: + +%_topdir /home/username/rpmtopdir + + +To build an RPM the hard way follow these steps. + +$ cp -a n2ndir n2n-2.0 +$ tar czf n2n-2.0.tar.gz n2n-2.0 +$ mv n2n-2.0.tar.gz /usr/src/redhat/SOURCES +$ cp n2ndir/n2n.spec /usr/src/redhat/SPECS +$ rpmbuild -bb n2n.spec diff --git a/bundles/n2n_meyerd/n2n_v2/NEW_FEATURES.txt b/bundles/n2n_meyerd/n2n_v2/NEW_FEATURES.txt new file mode 100644 index 00000000..9efc5875 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/NEW_FEATURES.txt @@ -0,0 +1,6 @@ + +Between 2.0.x and 2.1.x + +* Better ming Windows build support. +* Added -E flag to allow multicast ethernet traffic. + diff --git a/bundles/n2n_meyerd/n2n_v2/README b/bundles/n2n_meyerd/n2n_v2/README new file mode 100644 index 00000000..f21422b0 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/README @@ -0,0 +1,111 @@ + + +Edge node +--------- + +You need to start an edge node on each host you want to connect with the *same* +community. + +0. become root + +1. create tun device +# tunctl -t tun0 + +3. enable the edge process +# ./edge -d n2n0 -c mynetwork -k encryptme -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw + or +# N2N_KEY=encryptme ./edge -d n2n0 -c mynetwork -u 99 -g 99 -m 3C:A0:12:34:56:78 -a 1.2.3.4 -l a.b.c.d:xyw + +Once you have this worked out, you can add the "-f" option to make edge detach +and run as a daemon. + +Note that -u, -g and -f options are not available for Windows. + +Supernode +-------- + +You need to start the supernode once + +1. ./supernode -l 1234 -v + + +Dropping Root Privileges and SUID-Root Executables (UNIX) +-------------------------------------------------- + +The edge node uses superuser privileges to create a TAP network interface +device. Once this is created root privileges are not required and can constitute +a security hazard if there is some way for an attacker to take control of an +edge process while it is running. Edge will drop to a non-privileged user if you +specify the -u and -g options. These are numeric IDs. Consult +/etc/passwd. + +You may choose to install edge SUID-root to do this: + +1. Become root +2. chown root:root edge +3. chmod +s edge +done + +Any user can now run edge. You may not want this, but it may be convenient and +safe if your host has only one login user. + + +Running As a Daemon (UNIX) +------------------- + +Unless given "-f" as a command line option, edge will call daemon(3) after +successful setup. This causes the process to fork a child which closes stdin, +stdout and stderr then sets itself as process group leader. When this is done, +the edge command returns immediately and you will only see the edge process in +the process listings, eg. from ps or top. + +If the edge command returns 0 then the daemon started successfully. If it +returns non-zero then edge failed to start up for some reason. When edge starts +running as a daemon, all logging goes to syslog daemon.info facility. + + +IPv6 Support +------------ + +n2n supports the carriage of IPv6 packets within the n2n tunnel. N2n does not +yet use IPv6 for transport between edges and supernodes. + +To make IPv6 carriage work you need to manually add IPv6 addresses to the TAP +interfaces at each end. There is currently no way to specify an IPv6 address on +the edge command line. + +eg. under linux: + +on hostA: +[hostA] # /sbin/ip -6 addr add fc00:abcd:1234::7/48 dev n2n0 + +on hostB: +[hostB] # /sbin/ip -6 addr add fc00:abcd:1234::6/48 dev n2n0 + +You may find it useful to make use of tunctl from the uml-utilities +package. Tunctl allow you to bring up a TAP interface and configure addressing +prior to starting edge. It also allows edge to be restarted without the +interface closing (which would normally affect routing tables). + +Once the IPv6 addresses are configured and edge started, IPv6 neighbor discovery +packets flow (get broadcast) and IPv6 entities self arrange. Test your IPv6 +setup with ping6 - the IPv6 ping command. + + +Performance Notes +----------------- + +The time taken to perform a ping test for various ciphers is given below: + +Test: ping -f -l 8 -s 800 -c 10000 + +AES (-O0) 11820 +TF (-O0) 25761 + +TF (-O2) 20554 + +AES (-O3) 12532 +TF (-O3) 14046 +NULL (-O3) 10659 + +(C) 2007-2010 - Luca Deri , Richard Andrews diff --git a/bundles/n2n_meyerd/n2n_v2/android/tuntap_android.c b/bundles/n2n_meyerd/n2n_v2/android/tuntap_android.c new file mode 100644 index 00000000..11e49224 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/android/tuntap_android.c @@ -0,0 +1,113 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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, see +*/ + +#include "../n2n.h" + +#ifdef __ANDROID_NDK__ +#include +#include +#include + +n2n_edge_status_t* g_status; + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver then uses ifconfig + * to configure address/mask and MTU. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i, n_matched; + unsigned int mac[6]; + + n_matched = sscanf(device_mac, "%x:%x:%x:%x:%x:%x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + if (n_matched != 6) { + return -1; + } + memset(device->mac_addr, 0, sizeof(device->mac_addr)); + for (i = 0; i < 6; i++) + device->mac_addr[i] = mac[i]; + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->mtu = mtu; + strncpy(device->dev_name, dev, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); + return device->fd; +} + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + int rlen = read(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + if ((rlen <= 0) || (rlen > N2N_PKT_BUF_SIZE - UIP_LLH_LEN)) + { + return rlen; + } + uip_buf = buf; + uip_len = rlen; + uip_arp_out(); + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) + { + traceEvent(TRACE_DEBUG, "ARP request packets are sent instead of packets"); + } + + return uip_len; +} + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + int rlen; + uip_buf = buf; + uip_len = len; + if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_IP)) { + rlen = write(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN); + return rlen <= 0 ? rlen : rlen + UIP_LLH_LEN; + } else if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if (uip_len > 0) { + uip_arp_len = uip_len; + memcpy(uip_arp_buf, uip_buf, uip_arp_len); + traceEvent(TRACE_DEBUG, "ARP reply packet prepare to send"); + } + return len; + } + + errno = EINVAL; + return -1; +} + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +void tuntap_get_address(struct tuntap_dev *tuntap) { +} + +#endif /* #ifdef __ANDROID_NDK__ */ diff --git a/bundles/n2n_meyerd/n2n_v2/benchmark.c b/bundles/n2n_meyerd/n2n_v2/benchmark.c new file mode 100644 index 00000000..0541095c --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/benchmark.c @@ -0,0 +1,108 @@ +#include "n2n_wire.h" +#include "n2n_transforms.h" +#include "n2n.h" + +#ifndef WIN32 +#include +#endif +#include +#include +#include + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; + +/* Prototypes */ +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ); + +int main( int argc, char * argv[] ) +{ + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + n2n_trans_op_t transop_null; + + n2n_common_t cmn; + n2n_PACKET_t pkt; + n2n_community_t c; + + struct timeval t1; + struct timeval t2; + + unsigned long int i; + size_t n; + size_t idx; + size_t rem; + ssize_t nw; + unsigned long int tdiff; + + transop_null_init( &transop_null ); + memset(c,0,sizeof(N2N_COMMUNITY_SIZE)); + + n=10000; + memcpy( c, "abc123def456", 12 ); + + gettimeofday( &t1, NULL ); + for(i=0; i %lu nsec each) %u.%06u -> %u.%06u.\n", i, tdiff, (tdiff *1000)/i, (uint32_t)t1.tv_sec, (uint32_t)t1.tv_usec, (uint32_t)t2.tv_sec, (uint32_t)t2.tv_usec ); + + return 0; +} + +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) +{ + /* n2n_mac_t destMac={0,1,2,3,4,5}; */ + n2n_common_t cmn; + n2n_PACKET_t pkt; + size_t idx; + + + memset( &cmn, 0, sizeof(cmn) ); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy( cmn.community, c, N2N_COMMUNITY_SIZE ); + + memset( &pkt, 0, sizeof(pkt) ); + + idx=0; + encode_PACKET( pktbuf, &idx, &cmn, &pkt ); + traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx ); + + return idx; +} diff --git a/bundles/n2n_meyerd/n2n_v2/benchmark_hashtable.c b/bundles/n2n_meyerd/n2n_v2/benchmark_hashtable.c new file mode 100644 index 00000000..e1d2e848 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/benchmark_hashtable.c @@ -0,0 +1,25 @@ +#include "n2n_wire.h" +#include "n2n_transforms.h" +#include "n2n.h" + +#ifndef WIN32 +#include +#endif +#include +#include +#include + +int main(int argc, char** argv) { + peer_info_t* testpeers[PEER_HASH_TAB_SIZE]; + struct sglib_hashed_peer_info_t_iterator it; + peer_info_t *ll; + + sglib_hashed_peer_info_t_init(testpeers); + + for(ll=sglib_hashed_peer_info_t_it_init(&it, testpeers); ll!=NULL; ll=sglib_hashed_peer_info_t_it_next(&it)) { + sglib_hashed_peer_info_t_delete(testpeers, ll); + free(ll); + } + return 0; +} + diff --git a/bundles/n2n_meyerd/n2n_v2/cmake/CMakeToolchainFileMingw32.cmake b/bundles/n2n_meyerd/n2n_v2/cmake/CMakeToolchainFileMingw32.cmake new file mode 100644 index 00000000..0f1f7b3c --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/cmake/CMakeToolchainFileMingw32.cmake @@ -0,0 +1,17 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER i686-mingw32-gcc) +SET(CMAKE_CXX_COMPILER i686-mingw32-g++) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH ${HOME}/win_n2n/mingw32/) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + diff --git a/bundles/n2n_meyerd/n2n_v2/debian/README.Debian b/bundles/n2n_meyerd/n2n_v2/debian/README.Debian new file mode 100644 index 00000000..700c74ec --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/README.Debian @@ -0,0 +1,7 @@ +n2n for Debian +-------------- + +This package depends on the kernel having the TUN/TAP driver configured in using +CONFIG_TUN=yes. + + -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 diff --git a/bundles/n2n_meyerd/n2n_v2/debian/changelog b/bundles/n2n_meyerd/n2n_v2/debian/changelog new file mode 100644 index 00000000..bd31a4f2 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/changelog @@ -0,0 +1,27 @@ +n2n (2.1.0-1) unstable; urgency=low + + * Split package in two. + * Move manpage for edge to section 8. + * Install manpage for n2n_v2 to section 7. + * Create init.d files for the daemons. + + -- Kim Hansen Sun, 04 Apr 2010 21:40:46 +0200 + +n2n (2.0-1) hardy; urgency=low + + * New upstream release + + -- Richard Andrews Tue, 30 Oct 2009 22:26:04 +1100 + +n2n (1.3-1) hardy; urgency=low + + * New upstream release + + -- Richard Andrews Fri, 30 Jan 2009 23:49:56 +1100 + +n2n (1.2-1) unstable; urgency=low + + * Initial release + + -- Richard Andrews Thu, 10 Jul 2008 22:38:02 +1000 + diff --git a/bundles/n2n_meyerd/n2n_v2/debian/compat b/bundles/n2n_meyerd/n2n_v2/debian/compat new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/compat @@ -0,0 +1 @@ +5 diff --git a/bundles/n2n_meyerd/n2n_v2/debian/control b/bundles/n2n_meyerd/n2n_v2/debian/control new file mode 100644 index 00000000..1bdb6faa --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/control @@ -0,0 +1,51 @@ +Source: n2n +Section: net +Priority: extra +Maintainer: Jean-Baptiste Denis +Build-Depends: cdbs, debhelper (>= 5), libc6-dev (>= 2.0), dpatch, gcc, libssl-dev +Standards-Version: 3.7.2 + +Package: n2n +Architecture: any +Depends: n2n-edge, n2n-supernode +Description: dummy package for transition purposes + A dummy package for transition purposes that depends on n2n-edge and + n2n-supernode + +Package: n2n-edge +Architecture: any +Suggests: uml-utilities +Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: n2n (<< 2.1.0-1) +Replaces: n2n (<< 2.1.0-1) +Description: a layer-two peer-to-peer virtual private network (VPN) + n2n is a layer-two peer-to-peer virtual private network (VPN) which allows + users to exploit features typical of P2P applications at network instead of + application level. This means that users can gain native IP visibility (e.g. + two PCs belonging to the same n2n network can ping each other) and be + reachable with the same network IP address regardless of the network where + they currently belong. In a nutshell, as OpenVPN moved SSL from application + (e.g. used to implement the https protocol) to network protocol, n2n moves + P2P from application to network level. + . + Edge is the edge node daemon for n2n which creates a TAP interface to expose + the n2n virtual LAN. + +Package: n2n-supernode +Architecture: any +Suggests: n2n-edge +Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: n2n (<< 2.1.0-1) +Replaces: n2n (<< 2.1.0-1) +Description: a layer-two peer-to-peer virtual private network (VPN) + n2n is a layer-two peer-to-peer virtual private network (VPN) which allows + users to exploit features typical of P2P applications at network instead of + application level. This means that users can gain native IP visibility (e.g. + two PCs belonging to the same n2n network can ping each other) and be + reachable with the same network IP address regardless of the network where + they currently belong. In a nutshell, as OpenVPN moved SSL from application + (e.g. used to implement the https protocol) to network protocol, n2n moves + P2P from application to network level. + . + Supernode is a node introduction registry, broadcast conduit and packet relay + node for the n2n system. diff --git a/bundles/n2n_meyerd/n2n_v2/debian/copyright b/bundles/n2n_meyerd/n2n_v2/debian/copyright new file mode 100644 index 00000000..38346ce9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/copyright @@ -0,0 +1,23 @@ +This package was debianized by Jean-Baptiste Denis on +Thu, 20 Nov 2008 23:53:02 +1000. + +It was downloaded from http://www.ntop.org/n2n/ + +Upstream Author(s): + + Luca Deri + Richard Andrews + +Copyright: + + Copyright (C) 2008 Luca Deri + Copyright (C) 2008 Richard Andrews + +License: + + GPLv3 + +The Debian packaging is (C) 2008, Richard Andrews , +Luca Deri and is licensed under the GPLv3, see +`/usr/share/common-licenses/GPL-3'. + diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.default b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.default new file mode 100644 index 00000000..86bc8288 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.default @@ -0,0 +1,34 @@ +# Config file for the n2n edge node daemon. + +# Sets the n2n community name. All edges within the same community appear on +# the same LAN (layer 2 network segment). Community name is 16 bytes in length. +N2N_COMMUNITY="MyCommunityName" + +# Sets the twofish encryption key from ASCII text. All edges communicating must +# use the same key and community name. +N2N_KEY="MySecretCode" + +# Sets the n2n supernode IP address to register to. +#N2N_SN_HOST="localhost" +#N2N_SN_PORT="7654" + +# Hostname supplied to 'getent' to look up configuration. +#HOSTNAME=`uname -n` + +# IP & MAC addresses settings accoring to 'getent' +# ( set via nss which means where +# '/etc/nsswitch.conf' says $HOSTNAME can be found ) +# ( MAC not required ) +#N2N_IP_ADDR=`getent hosts $HOSTNAME | awk '{print $1}'` +#N2N_IP="static:$N2N_IP_ADDR" +#N2N_MAC=`getent ethers $HOSTNAME | awk '{print $1}'` + +# -r Enable packet forwarding +# -b Periodically resolve supernode IP (resolution often fails at boot-time) +# -E Accept muilticast MAC addresses + +DAEMON_OPTS="-r -b -E" + +# Uncomment this to get edge node started. +#N2N_EDGE_CONFIG_DONE="yes" + diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.docs b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.docs new file mode 100644 index 00000000..e845566c --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.docs @@ -0,0 +1 @@ +README diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.init b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.init new file mode 100644 index 00000000..57c374d7 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.init @@ -0,0 +1,156 @@ +#! /bin/bash +### BEGIN INIT INFO +# Provides: n2n-edge +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: n2n-edge +# Description: Start n2n edge node daemon +### END INIT INFO + +# Init script for n2n edge node +# Copyright (C) 2010 Kim Hansen +# Refactor (C) 2017 Dale MM0HGW +# +# 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 3 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, see . + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="n2n edge" +NAME=n2n-edge +DAEMON=/usr/sbin/edge +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Check config +if [ -z "$N2N_EDGE_CONFIG_DONE" ] +then + echo "Warning: n2n-edge not configured, edit config file in /etc/default/$NAME." 1>&2 + exit 0 +fi + +# Load default values +if [ -z $HOSTNAME ]; then + HOSTNAME=`uname -n` +fi +if [ -z ${N2N_SN_HOST+x} ]; then + N2N_SN_HOST=localhost; +fi +if [ -z ${N2N_SN_PORT+x} ]; then + N2N_SN_PORT=7654; +fi +DAEMON_ARGS="$DAEMON_ARGS -l $N2N_SN_HOST:$N2N_SN_PORT" +if [ -z ${N2N_IP+x} ]; then + N2N_IP_ADDR=`getent hosts $HOSTNAME | awk '{print $1}'` + N2N_IP="static:$N2N_IP_ADDR" +fi +if [ -z $N2N_IP ]; then + N2N_IP="dhcp:0.0.0.0" +fi +DAEMON_ARGS="$DAEMON_ARGS -a $N2N_IP"; +if [ -z ${N2N_MAC+x} ]; then + N2N_MAC=`getent ethers $HOSTNAME | awk '{print $1}'`; +fi +if ! [ -z $N2N_MAC ]; then + DAEMON_ARGS="$DAEMON_ARGS -m $N2N_MAC"; +fi +DAEMON_ARGS="$DAEMON_ARGS -c $N2N_COMMUNITY" + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --user nobody --exec $DAEMON --test \ + || return 1 + export N2N_KEY + start-stop-daemon --start --quiet --user nobody --exec $DAEMON -- \ + -u $(id -u nobody) -g $(id -g nobody) $DAEMON_ARGS \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user nobody --exec $DAEMON +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + restart|force-reload) + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +true # Set exit status to 0 (succes) diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.install b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.install new file mode 100644 index 00000000..2d0bd7c9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.install @@ -0,0 +1 @@ +edge /usr/sbin diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.manpages b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.manpages new file mode 100644 index 00000000..2fa385ba --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-edge.manpages @@ -0,0 +1,2 @@ +edge.8 +n2n_v2.7 diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.default b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.default new file mode 100644 index 00000000..bb222602 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.default @@ -0,0 +1,9 @@ +# Config file for the n2n supernode daemon. + +#N2N_SN_PORT=7654 + +DAEMON_OPTS="" + +# Uncomment this to get edge node started. +#N2N_SN_CONFIG_DONE="yes" + diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.init b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.init new file mode 100644 index 00000000..1641caa9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.init @@ -0,0 +1,126 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: n2n-supernode +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: n2n-supernode +# Description: Start n2n supernode +### END INIT INFO + +# Init script for n2n supernode +# Copyright (C) 2010 Kim Hansen +# Refactor (C) 2017 Dale MM0HGW +# +# 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 3 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, see . + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="n2n supernode" +NAME=n2n-supernode +DAEMON=/usr/sbin/supernode +DAEMON_ARGS="" +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Set defaults +if [ -z $N2N_SN_PORT ]; then N2N_SN_PORT=7654; fi +DAEMON_ARGS="$DAEMON_ARGS -l $N2N_SN_PORT" + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --user nobody --exec $DAEMON --test \ + || return 1 + start-stop-daemon --start --quiet --user nobody --chuid nobody --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --user nobody --exec $DAEMON +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + restart|force-reload) + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +true # Set exit status to 0 (succes) diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.install b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.install new file mode 100644 index 00000000..28fa2249 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.install @@ -0,0 +1 @@ +supernode /usr/sbin diff --git a/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.manpages b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.manpages new file mode 100644 index 00000000..6ebfb37b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/n2n-supernode.manpages @@ -0,0 +1 @@ +supernode.1 diff --git a/bundles/n2n_meyerd/n2n_v2/debian/rules b/bundles/n2n_meyerd/n2n_v2/debian/rules new file mode 100644 index 00000000..0bbc9b8d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/debian/rules @@ -0,0 +1,5 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/makefile.mk + diff --git a/bundles/n2n_meyerd/n2n_v2/edge.8 b/bundles/n2n_meyerd/n2n_v2/edge.8 new file mode 100644 index 00000000..dd0e2a21 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/edge.8 @@ -0,0 +1,221 @@ +.TH edge 8 "17 Mar 2010" "n2n-2.1" "SUPERUSER COMMANDS" +.SH NAME +edge \- n2n edge node daemon +.SH SYNOPSIS +.B edge +[\-d ] \-a \-c {\-k |\-K } +[\-s ] \-l +[\-p ] [\-u ] [\-g ] [-f] [\-m ] [\-r] [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Edge is the edge node daemon for n2n which +creates a TAP interface to expose the n2n virtual LAN. On startup n2n creates +the TAP interface and configures it then registers with the supernode so it can +begin to find other nodes in the community. +.PP +.SH OPTIONS +.TP +\-d +sets the TAP device name as seen in ifconfig. Only available on Linux. +.TP +\-a {|static:|dhcp:0.0.0.0} +sets the n2n virtual LAN IP address being claimed. This is a private IP +address. All IP addresses in an n2n community typical belong to the same /24 +network (ie. only the last octet of the IP addresses varies). If DHCP is used to +assign interface addresses then specify the address as +.B -a dhcp:0.0.0.0 +.TP +\-b +cause edge to perform hostname resolution for the supernode address each time +the supernode is periodically contacted. This can cause reliability problems +because all packet processing stops while the supernode address is resolved +which might take 15 seconds. +.TP +\-c +sets the n2n community name. All edges within the same community appear on the +same LAN (layer 2 network segment). Community name is 16 bytes in length. A name +smaller than this is padded with 0x00 bytes and a name longer than this is +truncated to take the first 16 bytes. +.TP +\-h +write usage then exit. +.TP +\-i +interval that is needed to keep the holes in the NAT open. This is used as an +interval for registration messages sent to the supernode. It is also used by +other edges to know when they need to reregister. +.TP +\-k +sets the twofish encryption key from ASCII text (see also N2N_KEY in +ENVIRONMENT). All edges communicating must use the same key and community +name. If neither -k nor -K is used to specify a key source then edge uses +cleartext mode (no encryption). The -k and -K options are mutually exclusive. +.TP +\-K +Reads a key-schedule file and populates the internal transform +operations with the data found there. This mechanism allows keys to roll at +pre-determined times for a group of hosts. Accurate time synchronisation is not +required as older keys can be decoded for some time after expiry. If neither -k +nor -K is used to specify a key source then edge uses cleartext mode (no +encryption). The -k and -K options are mutually exclusive. +.TP +\-l : +sets the n2n supernode IP address and port to register to. Up to 2 supernodes +can be specified by two invocations of -l :. eg. +.B edge -l 12.34.56.78:7654 -l 98.76.54.32:7654 +. +.TP +\-L +adds a local ip address which is sent to other nodes on registration. The nodes +will then try to register both with the address seen by the supernode and the +local address. This can be used to circumvent the behind-same-nat problem. The +local_ip value can either be an IP address, or the value "auto" which will try +to guess a valid local ip automatically. The local ip can also be changed via +the management interface. +.TP +\-p +binds edge to the given UDP port. Useful for keeping the same external socket +across restarts of edge. This allows peer edges which know the edge socket to +continue p2p operation without going back to the supernode. +.TP +\-t +binds the edge management system to the given UDP port. Default 5644. Use this +if you need to run multiple instance of edge; or something is bound to that +port. +.TP +\-u +causes the edge process to drop to the given user ID when privileges are no +longer required (UNIX). +.TP +\-g +causes the edge process to drop to the given group ID when privileges are no +longer required (UNIX). +.TP +\-f +disables daemon mode (UNIX) and causes edge to run in the foreground. +.TP +\-m +start the TAP interface with the given MAC address. This is highly recommended +as it means the same address will be used if edge stops and restarts. If this is +not done, the ARP caches of all peers will be wrong and packets will not flow to +this edge until the next ARP refresh. +.TP +\-M +set the MTU of the edge interface in bytes. MTU is the largest packet fragment +size allowed to be moved throught the interface. The default is 1400. +.TP +\-s +set the netmask of edge interface in IPv4 dotted decimal notation. The default +is 255.255.255.0 (ie. /24). +.TP +\-r +enable IP packet forwarding/routing through the n2n virtual LAN. Without this +option, IP packets arriving over n2n are dropped if not for the -a (or +DHCP assigned) IP address of the edge interface. +.TP +\-E +accept packets destined for multicast ethernet MAC addresses. These addresses +are used in multicast ethernet and IPv6 neighbour discovery. If this option is +not present these multicast packets are discarded as most users do not need or +understand them. +.TP +\-v +more verbose logging (may be specified several times for more verbosity). +.SH ENVIRONMENT +.TP +.B N2N_KEY +set the encryption key so it is not visible on the command line +.SH EXAMPLES +.TP +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-p 50001 \-l 123.121.120.119:7654 + +Start edge with TAP device n2n0 on community "mynetwork" with community +supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to +50001. Use "encryptme" as the single permanent shared encryption key. Assign MAC +address DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 +after the TAP device is successfull configured. +.PP +Add the -f option to stop edge running as a daemon. +.PP +Somewhere else setup another edge with similar parameters, eg. + +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP +Now you can ping from 192.168.254.5 to 192.168.254.7. +.PP +The MAC address (-m ) and virtual IP address (-a ) must be different +on all edges in the same community. + +.SH KEY SCHEDULE FILES +(See +.B n2n_v2(7) +for more details). + +The -K option reads a key schedule file. + +.B edge \-d n2n0 \-c mynetwork \-K /path/to/file \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP + +The key schedule file consists of line, one per key in the schedule. The purpose +of key schedules is to encourage regular changing of the encryption keys used by +a community. The file structure also allows for full binary keys to be specified +as compared to the ASCII keys allowed by the single key injection. Each key line +consists of the following: + +.B + + and are ASCII decimal values of the UNIX times during which the +key is valid. is the index of the transform that applies +to. is some text which is parsed by the transform module to derive the +key for that line. + +Supported values are: +.TP +2 = TwoFish + has the form _. eg. + +.B 1252327945 1252328305 2 602_3d7c7769b34b2a4812f8c0e9d87ce9 + +This specifies security association number 602 and a 16-octet key of numeric +value 0x3d7c7769b34b2a4812f8c0e9d87ce9. is a 32-bit unsigned integer which +is used to identify the encryption key to the receiver. The SA number is sent +unencrypted so the receiver may find the correct key from the key +schedule. is up to 16 octets although shorter keys are allowed. + +.TP +3 = AES-CBC + has the form _. Same rules as TwoFish. + +.SH CLEARTEXT MODE +If neither +.B -k +nor +.B -K +is specified then edge uses cleartext mode. In cleartext mode there is no +transform of the packet data it is simply encrypted. This is useful for +debugging n2n as packet contents can be seen clearly. + +To prevent accidental exposure of data, edge only enters cleartext mode when no +keying parameters are specified. In the case where keying parameters are +specified but no valid keys can be determined, edge exits with an error at +startup. If all keys become invalid while running, edge continues to encode +using the last key that was valid. + +.SH MANAGEMENT INTERFACE +Edge provides a very simple management system on UDP port 5644. Send a newline +to receive a status output. Send 'reload' to cause re-read of the +keyfile. Send 'stop' to cause edge to exit cleanly. + +.SH EXIT STATUS +edge is a daemon and any exit is an error. +.SH AUTHORS +.TP +Richard Andrews +andrews (at) ntop.org - n2n-1 maintainer and main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - original author of n2n +.TP +Don Bindner +(--) - significant contributions to n2n-1 +.SH SEE ALSO +ifconfig(8) supernode(1) tunctl(8) n2n_v2(7) diff --git a/bundles/n2n_meyerd/n2n_v2/edge.c b/bundles/n2n_meyerd/n2n_v2/edge.c new file mode 100644 index 00000000..db628754 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/edge.c @@ -0,0 +1,3238 @@ +/** + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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 see see + * + * Code contributions courtesy of: + * Don Bindner + * Sylwester Sosnowski + * Wilfried "Wonka" Klaebe + * Lukasz Taczuk + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" +#include +#include +#include "minilzo.h" + +#ifndef __ANDROID_NDK__ +#include "scm.h" + +int n2n_main(int, char **); +int n2n_stop(void *); + +struct SCM_def sd = { + .name = "edge", + .desc = "edge - n2n VPN Edge node", + .main = n2n_main, + .stop = n2n_stop, +}; +#endif /* __ANDROID_NDK__ */ + +#ifdef __ANDROID_NDK__ +#include +#include +#endif /* __ANDROID_NDK__ */ + +#if defined(DEBUG) +#define SOCKET_TIMEOUT_INTERVAL_SECS 5 +#define DEFAULT_HOLEPUNCH_INTERVAL 20 /* sec */ +#else /* #if defined(DEBUG) */ +#define SOCKET_TIMEOUT_INTERVAL_SECS 5 +#define DEFAULT_HOLEPUNCH_INTERVAL 25 /* sec */ +#endif /* #if defined(DEBUG) */ + +#define REGISTER_SUPER_INTERVAL_MIN 10 /* sec */ +#define REGISTER_SUPER_INTERVAL_MAX 120 /* sec */ + +#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ +#define TRANSOP_TICK_INTERVAL (10) /* sec */ + +#define LOCALIP_UPDATE_INTERVAL (30) /* sec. How long it usually takes to re-resolve local socket. */ + +#define STAT_CALC_INTERVAL (10) /* sec. Calculate the bps values in roughly this interval steps */ + +/** maximum length of command line arguments */ +#define MAX_CMDLINE_BUFFER_LENGTH 4096 + +/** maximum length of a line in the configuration file */ +#define MAX_CONFFILE_LINE_LENGTH 1024 + +#define N2N_PATHNAME_MAXLEN 256 +#define N2N_MAX_TRANSFORMS 16 +#define N2N_EDGE_MGMT_PORT 5644 + +/** Positions in the transop array where various transforms are stored. + * + * Used by transop_enum_to_index(). See also the transform enumerations in + * n2n_transforms.h */ +#define N2N_TRANSOP_NULL_IDX 0 +#define N2N_TRANSOP_TF_IDX 1 +#define N2N_TRANSOP_AESCBC_IDX 2 +/* etc. */ + + + +/* Work-memory needed for compression. Allocate memory in units + * of `lzo_align_t' (instead of `char') to make sure it is properly aligned. + */ + +/* #define HEAP_ALLOC(var,size) \ */ +/* lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] */ + +/* static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS); */ + +/* ******************************************************* */ + +#define N2N_EDGE_SN_HOST_SIZE 48 +#define N2N_EDGE_LOCAL_IP_SIZE 48 + +typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; +typedef char n2n_local_ip_t[N2N_EDGE_LOCAL_IP_SIZE]; + +#define N2N_EDGE_NUM_SUPERNODES 2 +#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ + + +/** Main structure type for edge. */ +struct n2n_edge +{ + int daemon; /**< Non-zero if edge should detach and run in the background. */ + uint8_t re_resolve_supernode_ip; + + n2n_sock_t supernode; + n2n_sock_t local_sock; + + size_t sn_idx; /**< Currently active supernode. */ + size_t sn_num; /**< Number of supernode addresses defined. */ + n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES]; + n2n_local_ip_t local_ip_str; /** storing a local ip socket */ + int local_sock_ena; /** > 0 if local_sock is enabled */ + int sn_wait; /**< Whether we are waiting for a supernode response. */ + + n2n_community_t community_name; /**< The community. 16 full octets. */ + char keyschedule[N2N_PATHNAME_MAXLEN]; + int null_transop; /**< Only allowed if no key sources defined. */ + + int udp_sock; + int udp_mgmt_sock; /**< socket for status info. */ + + tuntap_dev device; /**< All about the TUNTAP device */ + int dyn_ip_mode; /**< Interface IP address is dynamically allocated, eg. DHCP. */ + int allow_routing; /**< Accept packet no to interface address. */ + int drop_multicast; /**< Multicast ethernet addresses. */ + + n2n_trans_op_t transop[N2N_MAX_TRANSFORMS]; /* one for each transform at fixed positions */ + size_t tx_transop_idx; /**< The transop to use when encoding. */ + + struct peer_info * known_peers[PEER_HASH_TAB_SIZE]; /**< Edges we are connected to. */ + struct peer_info * pending_peers[PEER_HASH_TAB_SIZE]; /**< Edges we have tried to register with. */ + time_t last_register_req; /**< Check if time to re-register with super*/ + size_t holepunch_interval; /**< Time distance after last_register_req at which to re-register. */ + time_t last_purge; /** last time clients were purged **/ + time_t last_p2p; /**< Last time p2p traffic was received. */ + time_t last_sup; /**< Last time a packet arrived from supernode. */ + size_t sup_attempts; /**< Number of remaining attempts to this supernode. */ + n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */ + + time_t start_time; /**< For calculating uptime */ + + /* Statistics */ + size_t tx_p2p; + size_t tx_bit_p2p; + size_t tx_bps_p2p; + size_t rx_p2p; + size_t rx_bit_p2p; + size_t rx_bps_p2p; + size_t tx_sup; + size_t tx_bit_sup; + size_t tx_bps_sup; + size_t rx_sup; + size_t rx_bit_sup; + size_t rx_bps_sup; +}; + +/** Return the IP address of the current supernode in the ring. */ +static const char * supernode_ip( const n2n_edge_t * eee ) +{ + return (eee->sn_ip_array)[eee->sn_idx]; +} + + +static void supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addr); +static int localip2addr(n2n_sock_t * l_ip, + const n2n_local_ip_t local_ip_strIn, int local_port); +static int set_localip(n2n_edge_t * eee); + +static void send_packet2net(n2n_edge_t * eee, + uint8_t *decrypted_msg, size_t len); + + +/* ************************************** */ + +/* parse the configuration file */ +static int readConfFile(const char * filename, char * const linebuffer) { + struct stat stats; + FILE * fd; + char * buffer = NULL; + + buffer = (char *)malloc(MAX_CONFFILE_LINE_LENGTH); + if (!buffer) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return -1; + } + + if (stat(filename, &stats)) { + if (errno == ENOENT) + traceEvent(TRACE_ERROR, "parameter file %s not found/unable to access\n", filename); + else + traceEvent(TRACE_ERROR, "cannot stat file %s, errno=%d\n",filename, errno); + free(buffer); + return -1; + } + + fd = fopen(filename, "rb"); + if (!fd) { + traceEvent(TRACE_ERROR, "Unable to open parameter file '%s' (%d)...\n",filename,errno); + free(buffer); + return -1; + } + while(fgets(buffer, MAX_CONFFILE_LINE_LENGTH,fd)) { + char * p = NULL; + + /* strip out comments */ + p = strchr(buffer, '#'); + if (p) *p ='\0'; + + /* remove \n */ + p = strchr(buffer, '\n'); + if (p) *p ='\0'; + + /* strip out heading spaces */ + p = buffer; + while(*p == ' ' && *p != '\0') ++p; + if (p != buffer) strncpy(buffer,p,strlen(p)+1); + + /* strip out trailing spaces */ + while(strlen(buffer) && buffer[strlen(buffer)-1]==' ') + buffer[strlen(buffer)-1]= '\0'; + + /* check for nested @file option */ + if (strchr(buffer, '@')) { + traceEvent(TRACE_ERROR, "@file in file nesting is not supported\n"); + free(buffer); + return -1; + } + if ((strlen(linebuffer)+strlen(buffer)+2)< MAX_CMDLINE_BUFFER_LENGTH) { + strncat(linebuffer, " ", 1); + strncat(linebuffer, buffer, strlen(buffer)); + } else { + traceEvent(TRACE_ERROR, "too many argument"); + free(buffer); + return -1; + } + } + + free(buffer); + fclose(fd); + + return 0; +} + +/* Create the argv vector */ +/* FIXME + * - this function does not handle quoted parameters + * Worse still, by this point, we have removed any indications of what the + * original params were - so quote handling performed by the shell is gone.. + */ +static char ** buildargv(int * effectiveargc, char * const linebuffer) { + const int INITIAL_MAXARGC = 16; /* Number of args + NULL in initial argv */ + int maxargc; + int argc=0; + char ** argv; + char * buffer, * buff; + + *effectiveargc = 0; + buffer = (char *)calloc(1, strlen(linebuffer)+2); + if (!buffer) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return NULL; + } + strncpy(buffer, linebuffer,strlen(linebuffer)); + + maxargc = INITIAL_MAXARGC; + argv = (char **)malloc(maxargc * sizeof(char*)); + if (argv == NULL) { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + return NULL; + } + buff = buffer; + while(buff) { + char * p = strchr(buff,' '); + if (p) { + *p='\0'; + argv[argc++] = strdup(buff); + while(*++p == ' ' && *p != '\0'); + buff=p; + if (argc >= maxargc) { + maxargc *= 2; + argv = (char **)realloc(argv, maxargc * sizeof(char*)); + if (argv == NULL) { + traceEvent(TRACE_ERROR, "Unable to re-allocate memory"); + free(buffer); + return NULL; + } + } + } else { + argv[argc++] = strdup(buff); + break; + } + } + free(buffer); + *effectiveargc = argc; + return argv; +} + + + +/* ************************************** */ + + +/** Initialise an edge to defaults. + * + * This also initialises the NULL transform operation opstruct. + */ +static int edge_init(n2n_edge_t * eee) +{ +#ifdef WIN32 + initWin32(); +#endif + memset(eee, 0, sizeof(n2n_edge_t)); + eee->start_time = time(NULL); + + transop_null_init( &(eee->transop[N2N_TRANSOP_NULL_IDX]) ); + transop_twofish_init( &(eee->transop[N2N_TRANSOP_TF_IDX] ) ); + transop_aes_init( &(eee->transop[N2N_TRANSOP_AESCBC_IDX] ) ); + + eee->tx_transop_idx = N2N_TRANSOP_NULL_IDX; /* No guarantee the others have been setup */ + + eee->daemon = 1; /* By default run in daemon mode. */ + eee->re_resolve_supernode_ip = 0; + /* keyschedule set to NULLs by memset */ + /* community_name set to NULLs by memset */ + eee->null_transop = 0; + eee->udp_sock = -1; + eee->udp_mgmt_sock = -1; + eee->dyn_ip_mode = 0; + eee->allow_routing = 0; + eee->drop_multicast = 1; + eee->local_sock_ena = 0; + sglib_hashed_peer_info_t_init(eee->known_peers); + sglib_hashed_peer_info_t_init(eee->pending_peers); + eee->last_register_req = 0; + eee->holepunch_interval = DEFAULT_HOLEPUNCH_INTERVAL; + eee->last_p2p = 0; + eee->last_sup = 0; + eee->last_purge = 0; + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; + eee->tx_bit_p2p = 0; + eee->tx_bit_sup = 0; + eee->rx_bit_p2p = 0; + eee->rx_bit_sup = 0; + + if(lzo_init() != LZO_E_OK) + { + traceEvent(TRACE_ERROR, "LZO compression error"); + return(-1); + } + + return(0); +} + + + +/* Called in main() after options are parsed. */ +static int edge_init_twofish( n2n_edge_t * eee, uint8_t *encrypt_pwd, uint32_t encrypt_pwd_len ) +{ + return transop_twofish_setup( &(eee->transop[N2N_TRANSOP_TF_IDX]), 0, encrypt_pwd, encrypt_pwd_len ); +} + + +/** Find the transop op-struct for the transform enumeration required. + * + * @return - index into the transop array, or -1 on failure. + */ +static int transop_enum_to_index( n2n_transform_t id ) +{ + switch (id) + { + case N2N_TRANSFORM_ID_TWOFISH: + return N2N_TRANSOP_TF_IDX; + break; + case N2N_TRANSFORM_ID_NULL: + return N2N_TRANSOP_NULL_IDX; + break; + case N2N_TRANSFORM_ID_AESCBC: + return N2N_TRANSOP_AESCBC_IDX; + break; + default: + return -1; + } +} + + +/** Called periodically to roll keys and do any periodic maintenance in the + * tranform operations state machines. */ +static int n2n_tick_transop( n2n_edge_t * eee, time_t now ) +{ + n2n_tostat_t tst; + size_t trop = eee->tx_transop_idx; + + /* Tests are done in order that most preferred transform is last and causes + * tx_transop_idx to be left at most preferred valid transform. */ + tst = (eee->transop[N2N_TRANSOP_NULL_IDX].tick)( &(eee->transop[N2N_TRANSOP_NULL_IDX]), now ); + tst = (eee->transop[N2N_TRANSOP_AESCBC_IDX].tick)( &(eee->transop[N2N_TRANSOP_AESCBC_IDX]), now ); + if ( tst.can_tx ) + { + traceEvent( TRACE_DEBUG, "can_tx AESCBC (idx=%u)", (unsigned int)N2N_TRANSOP_AESCBC_IDX ); + trop = N2N_TRANSOP_AESCBC_IDX; + } + + tst = (eee->transop[N2N_TRANSOP_TF_IDX].tick)( &(eee->transop[N2N_TRANSOP_TF_IDX]), now ); + if ( tst.can_tx ) + { + traceEvent( TRACE_DEBUG, "can_tx TF (idx=%u)", (unsigned int)N2N_TRANSOP_TF_IDX ); + trop = N2N_TRANSOP_TF_IDX; + } + + if ( trop != eee->tx_transop_idx ) + { + eee->tx_transop_idx = trop; + traceEvent( TRACE_NORMAL, "Chose new tx_transop_idx=%u", (unsigned int)(eee->tx_transop_idx) ); + } + + return 0; +} + + + +/** Read in a key-schedule file, parse the lines and pass each line to the + * appropriate trans_op for parsing of key-data and adding key-schedule + * entries. The lookup table of time->trans_op is constructed such that + * encoding can be passed to the correct trans_op. The trans_op internal table + * will then determine the best SA for that trans_op from the key schedule to + * use for encoding. */ +static int edge_init_keyschedule( n2n_edge_t * eee ) +{ + +#define N2N_NUM_CIPHERSPECS 32 + + int retval = -1; + ssize_t numSpecs=0; + n2n_cipherspec_t specs[N2N_NUM_CIPHERSPECS]; + size_t i; + time_t now = time(NULL); + + numSpecs = n2n_read_keyfile( specs, N2N_NUM_CIPHERSPECS, eee->keyschedule ); + + if ( numSpecs > 0 ) + { + traceEvent( TRACE_NORMAL, "keyfile = %s read -> %d specs.\n", optarg, (signed int)numSpecs); + + for ( i=0; i < (size_t)numSpecs; ++i ) + { + int idx; + + idx = transop_enum_to_index( specs[i].t ); + + switch (idx) + { + case N2N_TRANSOP_TF_IDX: + case N2N_TRANSOP_AESCBC_IDX: + { + retval = (eee->transop[idx].addspec)( &(eee->transop[idx]), + &(specs[i]) ); + break; + } + default: + retval = -1; + } + + if (0 != retval) + { + traceEvent( TRACE_ERROR, "keyschedule failed to add spec[%u] to transop[%d].\n", + (unsigned int)i, idx); + + return retval; + } + } + + n2n_tick_transop( eee, now ); + } + else + { + traceEvent( TRACE_ERROR, "Failed to process '%s'", eee->keyschedule ); + } + + return retval; +} + + +/** Deinitialise the edge and deallocate any owned memory. */ +static void edge_deinit(n2n_edge_t * eee) +{ + if ( eee->udp_sock >=0 ) + { + closesocket( eee->udp_sock ); + } + + if ( eee->udp_mgmt_sock >= 0 ) + { + closesocket(eee->udp_mgmt_sock); + } + + clear_hashed_peer_info_t_list( eee->pending_peers ); + clear_hashed_peer_info_t_list( eee->known_peers ); + + (eee->transop[N2N_TRANSOP_TF_IDX].deinit)(&eee->transop[N2N_TRANSOP_TF_IDX]); + (eee->transop[N2N_TRANSOP_NULL_IDX].deinit)(&eee->transop[N2N_TRANSOP_NULL_IDX]); +} + +static void readFromIPSocket( n2n_edge_t * eee ); + +static void readFromMgmtSocket( n2n_edge_t * eee, int * keep_running ); + +static void help() { + print_n2n_version(0 /* no trace */); + + printf("edge " +#if defined(N2N_CAN_NAME_IFACE) + "-d " +#endif /* #if defined(N2N_CAN_NAME_IFACE) */ + "-a [static:|dhcp:] " + "-c " + "[-k | -K ] " + "[-s ] " +#if defined(N2N_HAVE_SETUID) + "[-u -g ]" +#endif /* #ifndef N2N_HAVE_SETUID */ + +#if defined(N2N_HAVE_DAEMON) + "[-f]" +#endif /* #if defined(N2N_HAVE_DAEMON) */ + "[-m ]" + "\n" + "-l " + "[-p ] [-M ] " + "[-r] [-E] [-v] [-t ] [-b] [-h]\n\n"); + +#ifdef __linux__ + printf("-d | tun device name\n"); +#endif + + printf("-a | Set interface address. For DHCP use '-r -a dhcp:0.0.0.0'\n"); + printf("-c | n2n community name the edge belongs to.\n"); + printf("-k | Encryption key (ASCII) - also N2N_KEY=. Not with -K.\n"); + printf("-K | Specify a key schedule file to load. Not with -k.\n"); + printf("-s | Edge interface netmask in dotted decimal notation (255.255.255.0).\n"); + printf("-l | Supernode IP:port\n"); + printf("-L | Add local ip to bypass between same nat problem\n"); + printf("-i | Set the NAT hole-punch interval (default 20seconds)\n"); + printf("-b | Periodically resolve supernode IP\n"); + printf(" : (when supernodes are running on dynamic IPs)\n"); + printf("-p | Fixed local UDP port.\n"); +#ifndef WIN32 + printf("-u | User ID (numeric) to use when privileges are dropped.\n"); + printf("-g | Group ID (numeric) to use when privileges are dropped.\n"); +#endif /* ifndef WIN32 */ +#ifdef N2N_HAVE_DAEMON + printf("-f | Do not fork and run as a daemon; rather run in foreground.\n"); +#endif /* #ifdef N2N_HAVE_DAEMON */ + printf("-m | Fix MAC address for the TAP interface (otherwise it may be random)\n" + " : eg. -m 01:02:03:04:05:06\n"); + printf("-M | Specify n2n MTU of edge interface (default %d).\n", DEFAULT_MTU); + printf("-r | Enable packet forwarding through n2n community.\n"); + printf("-E | Accept multicast MAC addresses (default=drop).\n"); + printf("-v | Make more verbose. Repeat as required.\n"); + printf("-t | Management UDP Port (for multiple edges on a machine).\n"); + + printf("\nEnvironment variables:\n"); + printf(" N2N_KEY | Encryption key (ASCII). Not with -K or -k.\n" ); + + exit(0); +} + + +/** Send a datagram to a socket defined by a n2n_sock_t */ +static ssize_t sendto_sock( int fd, const void * buf, size_t len, const n2n_sock_t * dest ) +{ + n2n_sock_str_t sockbuf; + struct sockaddr_in peer_addr; + ssize_t sent; + + fill_sockaddr( (struct sockaddr *) &peer_addr, + sizeof(peer_addr), + dest ); + + sent = sendto( fd, buf, len, 0/*flags*/, + (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in) ); + if ( sent < 0 ) + { + char * c = strerror(errno); + traceEvent( TRACE_ERROR, "sendto %s failed (%d) %s", + sock_to_cstr( sockbuf, dest ), errno, c ); + } + else + { + traceEvent( TRACE_DEBUG, "sendto sent=%d to ", (signed int)sent ); + } + + return sent; +} + + +/** Send a REGISTER packet to another edge. */ +static void send_register( n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_mac_t dstMac) +{ + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_REGISTER_t reg = {{0}}; + n2n_sock_str_t sockbuf; + + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register; + cmn.flags = 0; + memcpy( cmn.community, eee->community_name, N2N_COMMUNITY_SIZE ); + + /* NOTE: Encoding should probably not be done here but in + * encode_REGISTER (lukas) */ + idx=0; + encode_uint32( reg.cookie, &idx, 123456789 ); + idx=0; + encode_mac( reg.srcMac, &idx, eee->device.mac_addr ); + if(dstMac) { + idx=0; + encode_mac( reg.dstMac, &idx, dstMac ); + } + + idx=0; + encode_REGISTER( pktbuf, &idx, &cmn, ® ); + + traceEvent( TRACE_INFO, "send REGISTER %s", + sock_to_cstr( sockbuf, remote_peer ) ); + + + sendto_sock( eee->udp_sock, pktbuf, idx, remote_peer ); +} + +/** Send a QUERY_PEER packet to the current supernode. */ +static void send_query_peer( n2n_edge_t * eee, + const n2n_mac_t dstMac) +{ + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_QUERY_PEER_t query = {{0}}; + + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_query_peer; + cmn.flags = 0; + memcpy( cmn.community, eee->community_name, N2N_COMMUNITY_SIZE ); + + idx=0; + encode_mac( query.srcMac, &idx, eee->device.mac_addr ); + idx=0; + encode_mac( query.targetMac, &idx, dstMac ); + + idx=0; + encode_QUERY_PEER( pktbuf, &idx, &cmn, &query ); + + traceEvent( TRACE_INFO, "send QUERY_PEER to supernode" ); + + sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) ); +} + +/** Send a REGISTER_SUPER packet to the current supernode. */ +static void send_register_super( n2n_edge_t * eee, + const n2n_sock_t * supernode) +{ + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_REGISTER_SUPER_t reg = {0}; + n2n_sock_str_t sockbuf; + + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register_super; + cmn.flags = 0; + memcpy( cmn.community, eee->community_name, N2N_COMMUNITY_SIZE ); + + for( idx=0; idx < N2N_COOKIE_SIZE; ++idx ) + { + eee->last_cookie[idx] = rand() % 0xff; + } + + reg.aflags = 0; + memcpy( reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE ); + reg.auth.scheme=0; /* No auth yet */ + reg.timeout = eee->holepunch_interval; + + idx=0; + encode_mac( reg.edgeMac, &idx, eee->device.mac_addr ); + + if(eee->local_sock_ena) { + reg.aflags |= N2N_AFLAGS_LOCAL_SOCKET; + reg.local_sock = eee->local_sock; + } + + idx=0; + encode_REGISTER_SUPER( pktbuf, &idx, &cmn, ® ); + + traceEvent( TRACE_INFO, "send REGISTER_SUPER to %s", + sock_to_cstr( sockbuf, supernode ) ); + + + sendto_sock( eee->udp_sock, pktbuf, idx, supernode ); +} + + +/** Send a REGISTER_ACK packet to a peer edge. */ +static void send_register_ack( n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_REGISTER_t * reg ) +{ + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn; + n2n_REGISTER_ACK_t ack; + n2n_sock_str_t sockbuf; + + memset(&cmn, 0, sizeof(cmn) ); + memset(&ack, 0, sizeof(reg) ); + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register_ack; + cmn.flags = 0; + memcpy( cmn.community, eee->community_name, N2N_COMMUNITY_SIZE ); + + memset( &ack, 0, sizeof(ack) ); + memcpy( ack.cookie, reg->cookie, N2N_COOKIE_SIZE ); + memcpy( ack.srcMac, eee->device.mac_addr, N2N_MAC_SIZE ); + memcpy( ack.dstMac, reg->srcMac, N2N_MAC_SIZE ); + + idx=0; + encode_REGISTER_ACK( pktbuf, &idx, &cmn, &ack ); + + traceEvent( TRACE_INFO, "send REGISTER_ACK %s", + sock_to_cstr( sockbuf, remote_peer ) ); + + + sendto_sock( eee->udp_sock, pktbuf, idx, remote_peer ); +} + + +/** NOT IMPLEMENTED + * + * This would send a DEREGISTER packet to a peer edge or supernode to indicate + * the edge is going away. + */ +static void send_deregister(n2n_edge_t * eee, + n2n_sock_t * remote_peer) +{ + /* Marshall and send message */ +} + + +static int is_empty_ip_address( const n2n_sock_t * sock ); +static void update_peer_address(n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t when); +void check_peer( n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer ); +void establish_connection( n2n_edge_t * eee, + const n2n_mac_t mac ); +void set_peer_operational( n2n_edge_t * eee, + const n2n_mac_t mac, + const n2n_sock_t * peer ); + + + +/** Start the registration process. + * + * If the peer is already in pending_peers, ignore the request. + * If not in pending_peers, add it and query info about it from supernode + * + * If hdr is for a direct peer-to-peer packet, try to register back to sender + * even if the MAC is in pending_peers. This is because an incident direct + * packet indicates that peer-to-peer exchange should work so more aggressive + * registration can be permitted (once per incoming packet) as this should only + * last for a small number of packets.. + * + * Called from the main loop when Rx a packet for our device mac. + */ +void establish_connection( n2n_edge_t * eee, + const n2n_mac_t mac ) +{ + struct peer_info * scan = find_peer_by_mac( eee->pending_peers, mac ); + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + if ( NULL == scan ) + { + time_t now = time(NULL); + scan = calloc( 1, sizeof( struct peer_info ) ); + + memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); + scan->num_sockets = 0; + scan->sock = eee->supernode; + scan->last_seen = now; /* Don't change this it marks the pending peer for removal. */ + + sglib_hashed_peer_info_t_add(eee->pending_peers, scan); + + traceEvent( TRACE_DEBUG, "=== new pending %s -> %s", + macaddr_str( mac_buf, scan->mac_addr ), + sock_to_cstr( sockbuf, &scan->sock ) ); + + traceEvent( TRACE_INFO, "Pending peers list size=%u", + (unsigned int)hashed_peer_list_t_size( eee->pending_peers ) ); + + /* trace Sending REGISTER */ + + send_query_peer(eee, scan->mac_addr); + scan->last_sent_query = now; + + /* pending_peers now owns scan. */ + } + else + { + } +} + + +/** Update the last_seen time for this peer, or get registered. */ +void check_peer( n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer) +{ + peer_info_t scan; + memcpy(scan.mac_addr, mac, sizeof(n2n_mac_t)); + + if (sglib_hashed_peer_info_t_find_member(eee->known_peers, &scan) == NULL) + { + /* Not in known_peers - start the REGISTER process. */ + establish_connection( eee, mac ); + } + else + { + /* Already in known_peers. */ + update_peer_address( eee, from_supernode, mac, peer, time(NULL) ); + } +} + + +/* Move the peer from the pending_peers list to the known_peers lists. + * + * peer must be a pointer to an element of the pending_peers list. + * + * Called by main loop when Rx a REGISTER_ACK. + */ +void set_peer_operational( n2n_edge_t * eee, + const n2n_mac_t mac, + const n2n_sock_t * peer ) +{ + peer_info_t tmp; + peer_info_t *scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + traceEvent( TRACE_INFO, "set_peer_operational: %s -> %s", + macaddr_str( mac_buf, mac), + sock_to_cstr( sockbuf, peer ) ); + + memcpy(tmp.mac_addr, mac, sizeof(n2n_mac_t)); + + scan = sglib_hashed_peer_info_t_find_member(eee->pending_peers, &tmp); + + if(scan) { + /* Remove scan from pending_peers. */ + sglib_hashed_peer_info_t_delete(eee->pending_peers, scan); + + /* Add scan to known_peers. */ + sglib_hashed_peer_info_t_add(eee->known_peers, scan); + + + scan->sock = *peer; + + traceEvent( TRACE_DEBUG, "=== new peer %s -> %s", + macaddr_str( mac_buf, scan->mac_addr), + sock_to_cstr( sockbuf, &scan->sock ) ); + + traceEvent( TRACE_INFO, "Pending peers list size=%u", + (unsigned int)hashed_peer_list_t_size( eee->pending_peers ) ); + + traceEvent( TRACE_INFO, "Operational peers list size=%u", + (unsigned int)hashed_peer_list_t_size( eee->known_peers ) ); + + + scan->last_seen = time(NULL); + } + else + { + traceEvent( TRACE_DEBUG, "Failed to find sender in pending_peers." ); + } +} + + +n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static int is_empty_ip_address( const n2n_sock_t * sock ) +{ + const uint8_t * ptr=NULL; + size_t len=0; + size_t i; + + if ( AF_INET6 == sock->family ) + { + ptr = sock->addr.v6; + len = 16; + } + else + { + ptr = sock->addr.v4; + len = 4; + } + + for (i=0; iknown_peers, &tmp); + + if ( scan == NULL ) + { + /* Not in known_peers. */ + return; + } + + if ( 0 != sock_equal( &(scan->sock), peer)) + { + if ( 0 == from_supernode ) + { + traceEvent( TRACE_NORMAL, "Peer changed %s: %s -> %s", + macaddr_str( mac_buf, scan->mac_addr ), + sock_to_cstr(sockbuf1, &(scan->sock)), + sock_to_cstr(sockbuf2, peer) ); + + /* The peer has changed public socket. It can no longer be assumed to be reachable. */ + /* Remove the peer. */ + sglib_hashed_peer_info_t_delete(eee->known_peers, scan); + dealloc_peer(scan); + + establish_connection( eee, mac ); + } + else + { + /* Don't worry about what the supernode reports, it could be seeing + * a different socket. */ + /* anyways, the packet came from supernode. That is potential + * trouble... just in case we will send a register back to the + * origin */ + send_register( eee, &(scan->sock), scan->mac_addr ); + } + } + else + { + /* Found and unchanged. */ + if(!from_supernode) + scan->last_seen = when; + } +} + +#if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */ + + + +static char gratuitous_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* Ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* Hw Size */ + 0x04, /* Protocol Size */ + 0x00, 0x01, /* ARP Request */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x00, 0x00, 0x00, 0x00, /* Src IP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ + 0x00, 0x00, 0x00, 0x00 /* Target IP */ +}; + + +/** Build a gratuitous ARP packet for a /24 layer 3 (IP) network. */ +static int build_gratuitous_arp(char *buffer, uint16_t buffer_len) { + if(buffer_len < sizeof(gratuitous_arp)) return(-1); + + memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); + memcpy(&buffer[6], device.mac_addr, 6); + memcpy(&buffer[22], device.mac_addr, 6); + memcpy(&buffer[28], &device.ip_addr, 4); + + /* REVISIT: BbMaj7 - use a real netmask here. This is valid only by accident + * for /24 IPv4 networks. */ + buffer[31] = 0xFF; /* Use a faked broadcast address */ + memcpy(&buffer[38], &device.ip_addr, 4); + return(sizeof(gratuitous_arp)); +} + +/** Called from update_supernode_reg to periodically send gratuitous ARP + * broadcasts. */ +static void send_grat_arps(n2n_edge_t * eee,) { + char buffer[48]; + size_t len; + + traceEvent(TRACE_NORMAL, "Sending gratuitous ARP..."); + len = build_gratuitous_arp(buffer, sizeof(buffer)); + send_packet2net(eee, buffer, len); + send_packet2net(eee, buffer, len); /* Two is better than one :-) */ +} +#endif /* #if defined(DUMMY_ID_00001) */ + + + + +/** @brief Check to see if we should re-register with the supernode. + * + * This is frequently called by the main loop. + */ +static void update_supernode_reg( n2n_edge_t * eee, time_t nowTime ) +{ + if ( eee->sn_wait && ( nowTime > (eee->last_register_req + (eee->holepunch_interval/10) ) ) ) + { + /* fall through */ + traceEvent( TRACE_DEBUG, "update_supernode_reg: doing fast retry." ); + } + else if ( nowTime < (eee->last_register_req + eee->holepunch_interval)) + { + return; /* Too early */ + } + + if ( 0 == eee->sup_attempts ) + { + /* Give up on that supernode and try the next one. */ + ++(eee->sn_idx); + + if (eee->sn_idx >= eee->sn_num) + { + /* Got to end of list, go back to the start. Also works for list of one entry. */ + eee->sn_idx=0; + } + + traceEvent(TRACE_WARNING, "Supernode not responding - moving to %u of %u", + (unsigned int)eee->sn_idx, (unsigned int)eee->sn_num ); + +#ifdef __ANDROID_NDK__ + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_SUPERNODE_DISCONNECT ? 0 : 1; + g_status->running_status = EDGE_STAT_SUPERNODE_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } +#endif /* #ifdef __ANDROID_NDK__ */ + + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; + } + else + { + --(eee->sup_attempts); + } + + if(eee->re_resolve_supernode_ip || (eee->sn_num > 1) ) + { + supernode2addr(&(eee->supernode), eee->sn_ip_array[eee->sn_idx] ); + } + + traceEvent(TRACE_DEBUG, "Registering with supernode (%s) (attempts left %u)", + supernode_ip(eee), (unsigned int)eee->sup_attempts); + + send_register_super( eee, &(eee->supernode) ); + + eee->sn_wait=1; + + /* REVISIT: turn-on gratuitous ARP with config option. */ + /* send_grat_arps(sock_fd, is_udp_sock); */ + + eee->last_register_req = nowTime; +} + + +#define RETRY_INTERVAL 5 + + +/* @return 1 if destination is a peer, 0 if destination is supernode */ +static int find_peer_destination(n2n_edge_t * eee, + n2n_mac_t mac_address, + n2n_sock_t * destination) +{ + peer_info_t tmp; + peer_info_t* scan = NULL; + peer_info_t* tryscan = NULL; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + int retval=0; + int i; + time_t now = time(NULL); + + traceEvent(TRACE_DEBUG, "Searching destination peer for MAC %02X:%02X:%02X:%02X:%02X:%02X", + mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, + mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); + + memcpy(tmp.mac_addr, mac_address, sizeof(n2n_mac_t)); + scan = sglib_hashed_peer_info_t_find_member(eee->known_peers, &tmp); + if(scan) { + if(now-scan->last_seen > scan->timeout) { + /* delete the peer and establish new connection */ + sglib_hashed_peer_info_t_delete(eee->known_peers, scan); + establish_connection( eee, scan->mac_addr ); + dealloc_peer(scan); + } else if(scan->last_seen > 0) { + memcpy(destination, &scan->sock, sizeof(n2n_sock_t)); + retval = 1; + } + } + + if ( 0 == retval ) + { + tryscan = sglib_hashed_peer_info_t_find_member(eee->pending_peers, &tmp); + if(tryscan) { + if(tryscan->num_sockets == 0) { + /* not yet received peer_info from supernode */ + if(now - tryscan->last_sent_query > RETRY_INTERVAL) { + send_query_peer(eee, tryscan->mac_addr); + tryscan->last_sent_query = now; + } + } else if(now - tryscan->last_seen > RETRY_INTERVAL) { + traceEvent(TRACE_INFO, "retrying to register peer (%s) -> [%s]", + macaddr_str( mac_buf, mac_address), + sock_to_cstr( sockbuf, &tryscan->sock)); + for(i=0; inum_sockets; i++) + send_register(eee, &tryscan->sockets[i], tryscan->mac_addr); + tryscan->last_seen = now; + } + } + memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); + } + + traceEvent(TRACE_DEBUG, "find_peer_address (%s) -> [%s]", + macaddr_str( mac_buf, mac_address ), + sock_to_cstr( sockbuf, destination ) ); + + return retval; +} + + + + +/* *********************************************** */ + +static const struct option long_options[] = { + { "community", required_argument, NULL, 'c' }, + { "supernode-list", required_argument, NULL, 'l' }, + { "tun-device", required_argument, NULL, 'd' }, + { "euid", required_argument, NULL, 'u' }, + { "egid", required_argument, NULL, 'g' }, + { "local-ip", required_argument, NULL, 'L' }, + { "holepunch-interval", required_argument, NULL, 'i' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, +#ifdef WIN32 + { "remove", no_argument, NULL, 'R' }, +#endif + { NULL, 0, NULL, 0 } +}; + +/* ***************************************************** */ + + +/** Send an ecapsulated ethernet PACKET to a destination edge or broadcast MAC + * address. */ +static int send_PACKET( n2n_edge_t * eee, + n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktlen, + n2n_sock_t * destination) +{ + n2n_sock_str_t sockbuf; + + /* hexdump( pktbuf, pktlen ); */ + + + traceEvent( TRACE_INFO, "send_PACKET to %s", sock_to_cstr( sockbuf, destination ) ); + + sendto_sock( eee->udp_sock, pktbuf, pktlen, destination ); + return 0; +} + + +/* Choose the transop for Tx. This should be based on the newest valid + * cipherspec in the key schedule. + * + * Never fall back to NULL tranform unless no key sources were specified. It is + * better to render edge inoperative than to expose user data in the clear. In + * the case where all SAs are expired an arbitrary transform will be chosen for + * Tx. It will fail having no valid SAs but one must be selected. + */ +static size_t edge_choose_tx_transop( const n2n_edge_t * eee ) +{ + if ( eee->null_transop) + { + return N2N_TRANSOP_NULL_IDX; + } + + return eee->tx_transop_idx; +} + + +/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ +static void send_packet2net(n2n_edge_t * eee, + uint8_t *tap_pkt, size_t len) +{ + ipstr_t ip_buf; + n2n_mac_t destMac; + + n2n_common_t cmn; + n2n_PACKET_t pkt; + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx=0; + size_t tx_transop_idx=0; + + ether_hdr_t eh; + + int dest; + int offset; + n2n_sock_t destination; + + /* tap_pkt is not aligned so we have to copy to aligned memory */ + memcpy( &eh, tap_pkt, sizeof(ether_hdr_t) ); + + /* Discard IP packets that are not originated by this hosts */ + if(!(eee->allow_routing)) { + if(ntohs(eh.type) == 0x0800) { + /* This is an IP packet from the local source address - not forwarded. */ + uint32_t *src = (uint32_t*)&tap_pkt[ETH_FRAMEHDRSIZE + IP4_SRCOFFSET]; + + /* Note: all elements of the_ip are in network order */ + if( *src != eee->device.ip_addr) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(*src), ip_buf, sizeof(ip_buf))); + return; + } else { + /* This packet is originated by us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + /* Optionally compress then apply transforms, eg encryption. */ + + /* Once processed, send to destination in PACKET */ + + memcpy( destMac, tap_pkt, N2N_MAC_SIZE ); /* dest MAC is first in ethernet header */ + + memset( &cmn, 0, sizeof(cmn) ); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy( cmn.community, eee->community_name, N2N_COMMUNITY_SIZE ); + + dest = find_peer_destination(eee, destMac, &destination); + + memset( &pkt, 0, sizeof(pkt) ); + + tx_transop_idx = edge_choose_tx_transop( eee ); + + pkt.transform = eee->transop[tx_transop_idx].transform_id; + + idx=0; + encode_PACKET( pktbuf, &idx, &cmn, &pkt ); + /* make the ethernet-header part of the PACKET header */ + offset = copy_ETHFRAMEHDR( pktbuf+idx , tap_pkt); + idx += offset; + tap_pkt += offset; + len -= offset; + + traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u transform %u (idx=%u)", + (unsigned int)idx, (unsigned int)pkt.transform, (unsigned int)tx_transop_idx ); + + idx += eee->transop[tx_transop_idx].fwd( &(eee->transop[tx_transop_idx]), + pktbuf+idx, N2N_PKT_BUF_SIZE-idx, + tap_pkt, len ); + ++(eee->transop[tx_transop_idx].tx_cnt); /* stats */ + + if ( dest ) + { + ++(eee->tx_p2p); + eee->tx_bit_p2p += idx; + } + else + { + ++(eee->tx_sup); + eee->tx_bit_sup += idx; + } + send_PACKET( eee, destMac, pktbuf, idx, &destination); +} + + +/** Destination MAC 33:33:0:00:00:00 - 33:33:FF:FF:FF:FF is reserved for IPv6 + * neighbour discovery. + */ +static int is_ip6_discovery( const void * buf, size_t bufsize ) +{ + int retval = 0; + + if ( bufsize >= sizeof(ether_hdr_t) ) + { + /* copy to aligned memory */ + ether_hdr_t eh; + memcpy( &eh, buf, sizeof(ether_hdr_t) ); + + if ( (0x33 == eh.dhost[0]) && + (0x33 == eh.dhost[1]) ) + { + retval = 1; /* This is an IPv6 multicast packet [RFC2464]. */ + } + } + return retval; +} + +/** Destination 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF is multicast ethernet. + */ +static int is_ethMulticast( const void * buf, size_t bufsize ) +{ + int retval = 0; + + /* Match 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF */ + if ( bufsize >= sizeof(ether_hdr_t) ) + { + /* copy to aligned memory */ + ether_hdr_t eh; + memcpy( &eh, buf, sizeof(ether_hdr_t) ); + + if ( (0x01 == eh.dhost[0]) && + (0x00 == eh.dhost[1]) && + (0x5E == eh.dhost[2]) && + (0 == (0x80 & eh.dhost[3])) ) + { + retval = 1; /* This is an ethernet multicast packet [RFC1112]. */ + } + } + return retval; +} + + + +/** Read a single packet from the TAP interface, process it and write out the + * corresponding packet to the cooked socket. + */ +static void readFromTAPSocket( n2n_edge_t * eee ) +{ + /* tun -> remote */ + uint8_t eth_pkt[N2N_PKT_BUF_SIZE]; + macstr_t mac_buf; + ssize_t len; + +#ifdef __ANDROID_NDK__ + if (uip_arp_len != 0) { + len = uip_arp_len; + memcpy(eth_pkt, uip_arp_buf, MIN(uip_arp_len, N2N_PKT_BUF_SIZE)); + traceEvent(TRACE_DEBUG, "ARP reply packet to send"); + } + else + { +#endif /* #ifdef __ANDROID_NDK__ */ + len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE ); +#ifdef __ANDROID_NDK__ + } +#endif /* #ifdef __ANDROID_NDK__ */ + + if( (len <= 0) || (len > N2N_PKT_BUF_SIZE) ) + { + traceEvent(TRACE_WARNING, "read()=%d [%d/%s]", + (signed int)len, errno, strerror(errno)); + } + else + { + const uint8_t * mac = eth_pkt; + traceEvent(TRACE_INFO, "### Rx TAP packet (%4d) for %s", + (signed int)len, macaddr_str(mac_buf, mac) ); + + if ( eee->drop_multicast && + ( is_ip6_discovery( eth_pkt, len ) || + is_ethMulticast( eth_pkt, len) + ) + ) + { + traceEvent(TRACE_DEBUG, "Dropping multicast"); + } + else + { + send_packet2net(eee, eth_pkt, len); + } + } +} + + + +/** A PACKET has arrived containing an encapsulated ethernet datagram - usually + * encrypted. */ +static int handle_PACKET( n2n_edge_t * eee, + const n2n_common_t * cmn, + const n2n_PACKET_t * pkt, + const n2n_sock_t * orig_sender, + uint8_t * payload, + size_t psize ) +{ + ssize_t data_sent_len; + uint8_t from_supernode; + uint8_t * eth_payload=NULL; + int retval = -1; + time_t now; + n2n_ETHFRAMEHDR_t eth; + + now = time(NULL); + + traceEvent( TRACE_DEBUG, "handle_PACKET size %u transform %u", + (unsigned int)psize, (unsigned int)pkt->transform ); + /* hexdump( payload, psize ); */ + + from_supernode= cmn->flags & N2N_FLAGS_FROM_SUPERNODE; + + if ( from_supernode ) + { + ++(eee->rx_sup); + eee->last_sup=now; + eee->rx_bit_sup += psize; + } + else + { + ++(eee->rx_p2p); + eee->last_p2p=now; + eee->rx_bit_p2p += psize; + } + + decode_ETHFRAMEHDR(ð, payload); + /* Update the sender in peer table entry */ + check_peer( eee, from_supernode, eth.srcMac, orig_sender); + + /* Handle transform. */ + { + uint8_t decodebuffer[N2N_PKT_BUF_SIZE]; + uint8_t * decodebuf = decodebuffer; + size_t eth_size; + int rx_transop_idx=0; + int offset; + + /* copy eth header to decodebuf */ + offset = copy_ETHFRAMEHDR(decodebuffer, payload); + decodebuf += offset; + payload += offset; + psize -= offset; + eth_size = offset; + + rx_transop_idx = transop_enum_to_index(pkt->transform); + + if ( rx_transop_idx >=0 ) + { + eth_payload = decodebuf; + eth_size += eee->transop[rx_transop_idx].rev( &(eee->transop[rx_transop_idx]), + eth_payload, N2N_PKT_BUF_SIZE, + payload, psize ); + ++(eee->transop[rx_transop_idx].rx_cnt); /* stats */ + + /* Write ethernet packet to tap device. */ + traceEvent( TRACE_INFO, "sending to TAP %u", (unsigned int)eth_size ); + data_sent_len = tuntap_write(&(eee->device), decodebuffer, eth_size); + + if (data_sent_len == eth_size) + { + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "handle_PACKET dropped unknown transform enum %u", + (unsigned int)pkt->transform ); + } + } + + return retval; +} + + +/** Read a datagram from the management UDP socket and take appropriate + * action. */ +static void readFromMgmtSocket( n2n_edge_t * eee, int * keep_running ) +{ + uint8_t udp_buf[N2N_PKT_BUF_SIZE+1]; /* Complete UDP packet */ + ssize_t recvlen; + struct sockaddr_in sender_sock; + socklen_t i; + size_t msg_len; + time_t now; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + peer_info_t * lpi = NULL; + struct sglib_hashed_peer_info_t_iterator it; + int c; + + now = time(NULL); + i = sizeof(sender_sock); + recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if ( recvlen < 0 ) + { + traceEvent(TRACE_ERROR, "mgmt recvfrom failed with %s", strerror(errno) ); + + return; /* failed to receive data from UDP */ + } + + /* avoid parsing any uninitialized junk from the stack */ + udp_buf[recvlen] = 0; + + if ( recvlen >= 4 ) + { + if ( 0 == memcmp( udp_buf, "stop", 4 ) ) + { + traceEvent( TRACE_ERROR, "stop command received." ); + *keep_running = 0; + return; + } + + if ( 0 == memcmp( udp_buf, "help", 4 ) ) + { + msg_len=0; + //++traceLevel; + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "Help for edge management console:\n" + " stop Gracefully exit edge\n" + " help This help message\n" + " +verb Increase verbosity of logging\n" + " -verb Decrease verbosity of logging\n" + " peers List table of known peers\n" + " reload Re-read the keyschedule\n" + " mangle_peer mac ip [port] mangle peer\n" + " localip [value] Show or set the local IP value\n" + " Display statistics\n\n"); + + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + + return; + } + + } + + if ( recvlen >= 5 ) + { + if ( 0 == memcmp( udp_buf, "+verb", 5 ) ) + { + msg_len=0; + ++traceLevel; + + traceEvent( TRACE_ERROR, "+verb traceLevel=%u", (unsigned int)traceLevel ); + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> +OK traceLevel=%u\n", (unsigned int)traceLevel ); + + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + + return; + } + + if ( 0 == memcmp( udp_buf, "-verb", 5 ) ) + { + msg_len=0; + + if ( traceLevel > 0 ) + { + --traceLevel; + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> -OK traceLevel=%u\n", traceLevel ); + } + else + { + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> -NOK traceLevel=%u\n", traceLevel ); + } + + traceEvent( TRACE_ERROR, "-verb traceLevel=%u", (unsigned int)traceLevel ); + + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + return; + } + + if ( 0 == memcmp( udp_buf, "peers", 5 ) ) + { + msg_len = 0; + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> known peers (connected edges):\n"); + + traceEvent( TRACE_ERROR, "listing peers on mgmt socket", 0); + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + + c = 0; + for(lpi=sglib_hashed_peer_info_t_it_init(&it,eee->known_peers); lpi!=NULL; lpi=sglib_hashed_peer_info_t_it_next(&it)) { + c++; + msg_len = 0; + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> %i: %s -> %s last: %li(%ld sec ago)\n", c, macaddr_str( mac_buf, lpi->mac_addr ), + sock_to_cstr( sockbuf, &(lpi->sock) ), + lpi->last_seen, (now - lpi->last_seen)); + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + } + + msg_len = 0; + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> known peers (tried edges):\n"); + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + + c = 0; + for(lpi=sglib_hashed_peer_info_t_it_init(&it,eee->pending_peers); lpi!=NULL; lpi=sglib_hashed_peer_info_t_it_next(&it)) { + c++; + msg_len = 0; + if(lpi->num_sockets == 0) + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> %i: %s -> (no info) last: %li(%ld sec ago)\n", c, + macaddr_str( mac_buf, lpi->mac_addr ), + lpi->last_seen, (now - lpi->last_seen)); + else + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> %i: %s -> %s last: %li(%ld sec ago)\n", c, macaddr_str( mac_buf, lpi->mac_addr ), + sock_to_cstr( sockbuf, lpi->sockets ), + lpi->last_seen, (now - lpi->last_seen)); + if(lpi->num_sockets > 1) + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + " %s\n", + sock_to_cstr( sockbuf, lpi->sockets+1 )); + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + } + + return; + } + } + + if ( recvlen >= 6 ) + { + if ( 0 == memcmp( udp_buf, "reload", 6 ) ) + { + if ( strlen( eee->keyschedule ) > 0 ) + { + if ( edge_init_keyschedule(eee) == 0 ) + { + msg_len=0; + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> OK\n" ); + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + } + return; + } + } + } + + if ( recvlen >= 12 ) + { + if ( 0 == memcmp (udp_buf, "mangle_peer ", 12) ) + { + int j, n_matched; + n2n_mac_t target_mac; + unsigned int mac[6]; + int ip[4]; + int port; + struct peer_info * scan; + + udp_buf[recvlen] = 0; + n_matched = sscanf((const char *) udp_buf, + "mangle_peer %x:%x:%x:%x:%x:%x %d.%d.%d.%d %d", mac, mac+1, + mac+2, mac+3, mac+4, mac+5, ip, ip+1, ip+2, ip+3, &port); + for( j=0; j<6; j++ ) + target_mac[j] = (uint8_t) mac[j]; + scan = find_peer_by_mac( eee->pending_peers, target_mac ); + if (NULL != scan && n_matched >= 10) { + scan->sock.family = AF_INET; + printf("n_matched: %d, port: %d\n", n_matched, port); + if (n_matched >= 11 && port > 0) + scan->sock.port = (uint16_t) port; + for( j=0; j<4; j++) + scan->sock.addr.v4[j] = (uint8_t) ip[j]; + sendto( eee->udp_mgmt_sock, "success\n", 9, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + } else { + sendto( eee->udp_mgmt_sock, "failure\n", 9, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + } + return; + } + } + + char * cmd = strtok( (char *)udp_buf, " \r\n"); + if (cmd) { + if ( 0 == strcmp( cmd, "localip" ) ) + { + char *arg = strtok( NULL, " \r\n"); + if (arg) { + strncpy( eee->local_ip_str, arg, N2N_EDGE_LOCAL_IP_SIZE); + if ( set_localip(eee) != 0) { + sendto( eee->udp_mgmt_sock, "failure\n", 9, 0, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + return; + } + } + + /* show current value - possibly after changing it */ + msg_len=0; + if (!eee->local_sock_ena) { + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> localip off\n" ); + } else { + n2n_sock_str_t local_sockbuf; + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> localip %s (%s)\n", + eee->local_ip_str, + sock_to_cstr( local_sockbuf, &(eee->local_sock) ) ); + } + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); + return; + } + } + + traceEvent(TRACE_DEBUG, "mgmt status rq" ); + + msg_len=0; + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "Statistics for edge\n" ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "uptime %lu\n", + time(NULL) - eee->start_time ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "paths super:(tx),(rx) p2p: (tx),(rx)\n"); + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "packets %u,%u %u,%u\n", + (unsigned int)eee->tx_sup, + (unsigned int)eee->rx_sup, + (unsigned int)eee->tx_p2p, + (unsigned int)eee->rx_p2p ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "byte/s %u,%u %u,%u\n", + (unsigned int)eee->tx_bps_sup, + (unsigned int)eee->rx_bps_sup, + (unsigned int)eee->tx_bps_p2p, + (unsigned int)eee->rx_bps_p2p ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "trans:null |%6u|%6u|\n" + "trans:tf |%6u|%6u|\n" + "trans:aes |%6u|%6u|\n", + (unsigned int)eee->transop[N2N_TRANSOP_NULL_IDX].tx_cnt, + (unsigned int)eee->transop[N2N_TRANSOP_NULL_IDX].rx_cnt, + (unsigned int)eee->transop[N2N_TRANSOP_TF_IDX].tx_cnt, + (unsigned int)eee->transop[N2N_TRANSOP_TF_IDX].rx_cnt, + (unsigned int)eee->transop[N2N_TRANSOP_AESCBC_IDX].tx_cnt, + (unsigned int)eee->transop[N2N_TRANSOP_AESCBC_IDX].rx_cnt ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "peers pend:%u full:%u\n", + (unsigned int)hashed_peer_list_t_size( eee->pending_peers ), + (unsigned int)hashed_peer_list_t_size( eee->known_peers ) ); + + msg_len += snprintf( (char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "last super:%lu(%ld sec ago) p2p:%lu(%ld sec ago)\n", + eee->last_sup, (now - eee->last_sup), eee->last_p2p, (now - eee->last_p2p) ); + + traceEvent(TRACE_DEBUG, "mgmt status sending: %s", udp_buf ); + + + sendto( eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in) ); +} + + +/** Read a datagram from the main UDP socket to the internet. */ +static void readFromIPSocket( n2n_edge_t * eee ) +{ + n2n_common_t cmn; /* common fields in the packet header */ + + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ + macstr_t mac_buf1; + macstr_t mac_buf2; + + uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */ + ssize_t recvlen; + size_t rem; + size_t idx; + size_t msg_type; + struct sockaddr_in sender_sock; + n2n_sock_t sender; + n2n_sock_t * orig_sender=NULL; + time_t now=0; + size_t i; + int j; + + /* for PACKET packages */ + n2n_PACKET_t pkt; + + /* for PEER_INFO packages */ + n2n_PEER_INFO_t pi; + struct peer_info * scan; + + /* for REGISTER packages */ + n2n_REGISTER_t reg; + peer_info_t tmp; + + /* for REGISTER_ACK packages */ + n2n_REGISTER_ACK_t ra; + + /* For REGISTER_SUPER_ACK packages */ + n2n_REGISTER_SUPER_ACK_t rsa; + + + i = sizeof(sender_sock); + recvlen = recvfrom(eee->udp_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if ( recvlen < 0 ) + { + traceEvent(TRACE_ERROR, "recvfrom failed with %s", strerror(errno) ); + + return; /* failed to receive data from UDP */ + } + + /* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which + * IP transport version the packet arrived on. May need to UDP sockets. */ + sender.family = AF_INET; /* udp_sock was opened PF_INET v4 */ + sender.port = ntohs(sender_sock.sin_port); + memcpy( &(sender.addr.v4), &(sender_sock.sin_addr.s_addr), IPV4_SIZE ); + + /* The packet may not have an orig_sender socket spec. So default to last + * hop as sender. */ + orig_sender=&sender; + + traceEvent(TRACE_INFO, "### Rx N2N UDP (%d) from %s", + (signed int)recvlen, sock_to_cstr(sockbuf1, &sender) ); + + /* hexdump( udp_buf, recvlen ); */ + + rem = recvlen; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + if ( decode_common(&cmn, udp_buf, &rem, &idx) < 0 ) + { + traceEvent( TRACE_ERROR, "Failed to decode common section in N2N_UDP" ); + return; /* failed to decode packet */ + } + + now = time(NULL); + + msg_type = cmn.pc; /* packet code */ + + if( 0 == memcmp(cmn.community, eee->community_name, N2N_COMMUNITY_SIZE) ) + { + switch(msg_type) { + case MSG_TYPE_PACKET: + /* process PACKET */ + decode_PACKET( &pkt, &cmn, udp_buf, &rem, &idx ); + + traceEvent(TRACE_INFO, "Rx PACKET from %s (%s)", + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender) ); + + handle_PACKET( eee, &cmn, &pkt, orig_sender, udp_buf+idx, + recvlen-idx ); + break; + case MSG_TYPE_PEER_INFO: + decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx ); + + scan = find_peer_by_mac( eee->pending_peers, pi.mac ); + if (scan) { + scan->timeout = pi.timeout; + if (scan->num_sockets > 0) + free(scan->sockets); + if (pi.aflags & N2N_AFLAGS_LOCAL_SOCKET) + scan->num_sockets = 2; + else + scan->num_sockets = 1; + scan->sockets = malloc(scan->num_sockets*sizeof(n2n_sock_t)); + for(j=0; jnum_sockets; j++) + scan->sockets[j] = pi.sockets[j]; + traceEvent(TRACE_INFO, "Rx PEER_INFO on %s", + macaddr_str(mac_buf1, pi.mac) ); + for(j=0; jnum_sockets; j++) + send_register(eee, scan->sockets+j, scan->mac_addr); + } else { + traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", + macaddr_str(mac_buf1, pi.mac) ); + } + + break; + case MSG_TYPE_REGISTER: + /* Another edge is registering with us */ + decode_REGISTER( ®, &cmn, udp_buf, &rem, &idx ); + + traceEvent(TRACE_INFO, + "Rx REGISTER src=%s dst=%s from peer %s (%s)", + macaddr_str( mac_buf1, reg.srcMac ), + macaddr_str( mac_buf2, reg.dstMac ), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender) ); + + if ( 0 == memcmp(reg.dstMac, (eee->device.mac_addr), 6) ) + { + memcpy(tmp.mac_addr, reg.srcMac, sizeof(n2n_mac_t)); + if (sglib_hashed_peer_info_t_find_member( + eee->pending_peers, &tmp) != NULL) + send_register(eee, orig_sender, NULL); + } + + send_register_ack(eee, orig_sender, ®); + break; + case MSG_TYPE_REGISTER_ACK: + /* Peer edge is acknowledging our register request */ + + decode_REGISTER_ACK( &ra, &cmn, udp_buf, &rem, &idx ); + + if ( ra.sock.family ) + { + orig_sender = &(ra.sock); + } + + traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)", + macaddr_str( mac_buf1, ra.srcMac ), + macaddr_str( mac_buf2, ra.dstMac ), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender) ); + + /* Move from pending_peers to known_peers; ignore if not in pending. */ + set_peer_operational( eee, ra.srcMac, &sender ); + break; + case MSG_TYPE_REGISTER_SUPER_ACK: + if ( eee->sn_wait ) + { + decode_REGISTER_SUPER_ACK( &rsa, &cmn, udp_buf, &rem, &idx ); + + if ( rsa.sock.family ) + { + orig_sender = &(rsa.sock); + } + + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u", + macaddr_str( mac_buf1, rsa.edgeMac ), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender), + (unsigned int)eee->sup_attempts ); + + if ( 0 == memcmp( rsa.cookie, eee->last_cookie, N2N_COOKIE_SIZE ) ) + { + if ( rsa.num_sn > 0 ) + { + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s", + sock_to_cstr(sockbuf1, &(rsa.sn_bak) ) ); + } + + eee->last_p2p = now; + eee->last_sup = now; + eee->sn_wait=0; + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ + +#ifdef __ANDROID_NDK__ + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1; + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } +#endif /* #ifdef __ANDROID_NDK__ */ + + /* REVISIT: store sn_back */ + /* don't adjust lifetime according to supernode - this value should be specified + * by the client (because dependent on NAT/firewall) (lukas) + eee->holepunch_interval = rsa.lifetime; + eee->holepunch_interval = MAX( eee->holepunch_interval, REGISTER_SUPER_INTERVAL_MIN ); + eee->holepunch_interval = MIN( eee->holepunch_interval, REGISTER_SUPER_INTERVAL_MAX ); + */ + } + else + { + traceEvent( TRACE_WARNING, "Rx REGISTER_SUPER_ACK with wrong or old cookie." ); + } + } + else + { + traceEvent( TRACE_WARNING, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER." ); + } + break; + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); + break; + } /* end switch(msg_type) */ + } /* if (community match) */ + else + { + traceEvent(TRACE_WARNING, "Received packet with invalid community"); + } + +} + +/* ***************************************************** */ + + +#ifdef WIN32 +static DWORD tunReadThread(LPVOID lpArg ) +{ + n2n_edge_t *eee = (n2n_edge_t*)lpArg; + + while(1) + { + readFromTAPSocket(eee); + } + + return((DWORD)NULL); +} + + +/** Start a second thread in Windows because TUNTAP interfaces do not expose + * file descriptors. */ +static void startTunReadThread(n2n_edge_t *eee) +{ + HANDLE hThread; + DWORD dwThreadId; + + hThread = CreateThread(NULL, /* security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ + (void*)eee, /* argument to thread function */ + 0, /* thread creation flags */ + &dwThreadId); /* thread id out */ +} +#endif + +/* ***************************************************** */ + +/** Resolve the supernode IP address. + * + * REVISIT: This is a really bad idea. The edge will block completely while the + * hostname resolution is performed. This could take 15 seconds. + */ +static void supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn) +{ + n2n_sn_name_t addr; + const char *supernode_host; + + memcpy( addr, addrIn, N2N_EDGE_SN_HOST_SIZE ); + + supernode_host = strtok(addr, ":"); + + if(supernode_host) + { + in_addr_t sn_addr; + char *supernode_port = strtok(NULL, ":"); + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + int nameerr; + + if ( supernode_port ) + sn->port = atoi(supernode_port); + else + traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", + addr, supernode_host, supernode_port); + + nameerr = getaddrinfo( supernode_host, NULL, &aihints, &ainfo ); + + if( 0 == nameerr ) + { + struct sockaddr_in * saddr; + + /* ainfo s the head of a linked list if non-NULL. */ + if ( ainfo && (PF_INET == ainfo->ai_family) ) + { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + + memcpy( sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE ); + sn->family=AF_INET; + } + else + { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); + } + + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + ainfo = NULL; + } else { + traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s, assuming numeric", supernode_host); + sn_addr = inet_addr(supernode_host); /* uint32_t */ + memcpy( sn->addr.v4, &(sn_addr), IPV4_SIZE ); + sn->family=AF_INET; + } + + } else + traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); +} + +/** Decode local address string (given on command line) + */ +static int localip2addr(n2n_sock_t * l_ip, + const n2n_local_ip_t local_ip_str, int local_port) +{ + /* TODO: IPv6? */ + unsigned int ip[4]; + int i, n_matches; + + n_matches = sscanf( local_ip_str, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], + &ip[3]); + + if( n_matches != 4) { + return 0; + } + + for( i=0; i < 4; i++ ) { + if( ip[i] > 255 ) { + return 0; + } + } + l_ip->family = AF_INET; + l_ip->port = local_port; + for( i = 0; i < 4; i++ ) + l_ip->addr.v4[i] = ip[i]; + return 1; +} + +static int set_localip(n2n_edge_t * eee) { + int local_port; + n2n_sock_str_t local_sockbuf; + struct sockaddr_in sa; + + /* Assume failure, until one of the methods succeeds */ + eee->local_sock_ena = 0; + + if (eee->local_ip_str[0] == 0) { + /* Sanity check - cannot use an empty string to set localip */ + traceEvent( TRACE_ERROR, "localip string is empty" ); + return(-1); + } + + socklen_t sa_len = sizeof(sa); + if ( getsockname(eee->udp_sock, (struct sockaddr *) &sa, &sa_len) == -1 ) { + traceEvent( TRACE_ERROR, "getsockname() failed" ); + return(-1); + } + + local_port = ntohs(sa.sin_port); + memset(&(eee->local_sock), 0, sizeof(eee->local_sock)); + + if ( localip2addr( &(eee->local_sock), + eee->local_ip_str, local_port ) ) { + eee->local_sock_ena = 1; + } else if ( 0 == strcmp( eee->local_ip_str, "auto" ) ) { + /* Automatically use a "sane" value for the localip. + * This is currently using the local ip address that is used to + * talk to the supernode, but that could change if a better method + * if found + */ + + SOCKET fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + traceEvent(TRACE_WARNING, "socket() failed"); + return(-1); + } + + struct sockaddr_in sa_sn; + + fill_sockaddr( (struct sockaddr *) &sa_sn, + sizeof(sa_sn), + &eee->supernode ); + + if ( connect(fd, (struct sockaddr *) &sa_sn, sizeof(sa_sn) ) <0 ) { + close(fd); + traceEvent(TRACE_WARNING, "connect() failed"); + return(-1); + } + + if ( getsockname(fd, (struct sockaddr *) &sa, &sa_len) <0 ) { + close(fd); + traceEvent(TRACE_WARNING, "getsockname() failed"); + return(-1); + } + + if ( AF_INET != sa.sin_family ) { + /* TODO IPV6 */ + close(fd); + traceEvent(TRACE_WARNING, "wrong socket family"); + return(-1); + } + + eee->local_sock.family = sa.sin_family; + eee->local_sock.port = local_port; + memcpy( eee->local_sock.addr.v4, &(sa.sin_addr.s_addr), IPV4_SIZE ); + eee->local_sock_ena = 1; + close(fd); + } + + if (eee->local_sock_ena) { + traceEvent(TRACE_NORMAL, "Local Socket is %s", + sock_to_cstr( local_sockbuf, &(eee->local_sock) ) ); + return(0); + } + + traceEvent(TRACE_WARNING, "Wrong local_ip parameter (-L ip), disabled"); + return(-1); +} + +/* ***************************************************** */ + + +/** Find the address and IP mode for the tuntap device. + * + * s is one of these forms: + * + * := | A.B.C.D + * + * | static: | dhcp: + * + * If the mode is present (colon required) then fill ip_mode with that value + * otherwise do not change ip_mode. Fill ip_mode with everything after the + * colon if it is present; or s if colon is not present. + * + * ip_add and ip_mode are NULL terminated if modified. + * + * return 0 on success and -1 on error + */ +static int scan_address( char * ip_addr, size_t addr_size, + char * ip_mode, size_t mode_size, + const char * s ) +{ + int retval = -1; + char * p; + + if ( ( NULL == s ) || ( NULL == ip_addr) ) + { + return -1; + } + + memset(ip_addr, 0, addr_size); + + p = strpbrk(s, ":"); + + if ( p ) + { + /* colon is present */ + if ( ip_mode ) + { + size_t end=0; + + memset(ip_mode, 0, mode_size); + end = MIN( p-s, (ssize_t)(mode_size-1) ); /* ensure NULL term */ + strncpy( ip_mode, s, end ); + strncpy( ip_addr, p+1, addr_size-1 ); /* ensure NULL term */ + retval = 0; + } + } + else + { + /* colon is not present */ + strncpy( ip_addr, s, addr_size ); + } + + return retval; +} + +static int run_loop(n2n_edge_t * eee ); +int real_main(int argc, char* argv[]); +static n2n_edge_t eee; /* single instance for this program */ + +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ +#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ +#define N2N_IF_MODE_SIZE 16 /* static | dhcp */ + +/** Entry point to program from kernel. */ +int real_main(int argc, char* argv[]) +{ + int opt; + int local_port = 0 /* any port */; + int mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */ + char tuntap_dev_name[N2N_IFNAMSIZ] = "edge0"; + char ip_mode[N2N_IF_MODE_SIZE]="static"; + char ip_addr[N2N_NETMASK_STR_SIZE] = ""; + char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; + int mtu = DEFAULT_MTU; + int got_s = 0; + +#ifndef WIN32 + uid_t userid=0; /* root is the only guaranteed ID */ + gid_t groupid=0; /* root is the only guaranteed ID */ +#endif + + char device_mac[N2N_MACNAMSIZ]=""; + char * encrypt_key=NULL; + + int i, effectiveargc=0; + char ** effectiveargv=NULL; + char * linebuffer = NULL; + + if (-1 == edge_init(&eee) ) + { + traceEvent( TRACE_ERROR, "Failed in edge_init" ); + exit(1); + } + + if( getenv( "N2N_KEY" )) + { + encrypt_key = strdup( getenv( "N2N_KEY" )); + } + +#ifdef WIN32 + tuntap_dev_name[0] = '\0'; +#endif + memset(&(eee.supernode), 0, sizeof(eee.supernode)); + eee.supernode.family = AF_INET; + + linebuffer = (char *)malloc(MAX_CMDLINE_BUFFER_LENGTH); + if (!linebuffer) + { + traceEvent( TRACE_ERROR, "Unable to allocate memory"); + exit(1); + } + snprintf(linebuffer, MAX_CMDLINE_BUFFER_LENGTH, "%s",argv[0]); + +#ifdef WIN32 + for(i=0; i < (int)strlen(linebuffer); i++) + if(linebuffer[i] == '\\') linebuffer[i] = '/'; +#endif + + for(i = 1; i < argc; ++i) + { + if(argv[i][0] == '@') + { + if (readConfFile(&argv[i][1], linebuffer)<0) exit(1); /* <<<<----- check */ + } + else if ((strlen(linebuffer)+strlen(argv[i])+2) < MAX_CMDLINE_BUFFER_LENGTH) + { + strncat(linebuffer, " ", 1); + strncat(linebuffer, argv[i], strlen(argv[i])); + } + else + { + traceEvent( TRACE_ERROR, "too many argument"); + exit(1); + } + } + /* strip trailing spaces */ + while(strlen(linebuffer) && linebuffer[strlen(linebuffer)-1]==' ') + linebuffer[strlen(linebuffer)-1]= '\0'; + + /* build the new argv from the linebuffer */ + effectiveargv = buildargv(&effectiveargc, linebuffer); + +#ifdef WIN32 + /* unfortunately, any cmdline quoting used originally is gone, so we can + * not use the getopt to process the install + */ + if (!_strnicmp(effectiveargv[1], "--install", 9)) { + char *p = strchr(linebuffer,' ') + 1; /* skip the argv[0] */ + char *scm_args = strchr(p,' ') + 1; /* skip the "--install" */ + + printf("Installing service with args '%s'\n", scm_args); + /* request service installation */ + char *path = SCM_Install(&sd,scm_args); + if (!path) { + printf("Service installation failed\n"); + return 2; + } + printf("Service '%s' installed, binary path '%s'\n", sd.name,path); + printf("You should now start the service using the service manager.\n"); + return 1; + } +#endif + + if (linebuffer) + { + free(linebuffer); + linebuffer = NULL; + } + + /* {int k;for(k=0;k 0 ) + { + fprintf(stderr, "Error: -K and -k options are mutually exclusive.\n"); + exit(1); + } else { + encrypt_key = strdup(optarg); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key); + } + break; + } + case 'r': /* enable packet routing across n2n endpoints */ + { + eee.allow_routing = 1; + break; + } + + case 'l': /* supernode-list */ + { + if ( eee.sn_num < N2N_EDGE_NUM_SUPERNODES ) + { + strncpy( (eee.sn_ip_array[eee.sn_num]), optarg, N2N_EDGE_SN_HOST_SIZE); + traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)eee.sn_num, (eee.sn_ip_array[eee.sn_num]) ); + ++eee.sn_num; + } + else + { + fprintf(stderr, "Too many supernodes!\n" ); + exit(1); + } + break; + } + + case 'i': /* holepunch-interval */ + { + eee.holepunch_interval = atoi(optarg); + eee.holepunch_interval = MAX( eee.holepunch_interval, REGISTER_SUPER_INTERVAL_MIN ); + eee.holepunch_interval = MIN( eee.holepunch_interval, REGISTER_SUPER_INTERVAL_MAX ); + break; + } + case 'L': /* local ip */ + { + eee.local_sock_ena = 1; + strncpy( eee.local_ip_str, optarg, N2N_EDGE_LOCAL_IP_SIZE); + if ( N2N_EDGE_LOCAL_IP_SIZE > 0 ) + eee.local_ip_str[N2N_EDGE_LOCAL_IP_SIZE - 1] = '\0'; + traceEvent(TRACE_DEBUG, "Storing local_ip_str = %s\n", (eee.local_ip_str) ); + break; + } + +#if defined(N2N_CAN_NAME_IFACE) + case 'd': /* TUNTAP name */ + { + strncpy(tuntap_dev_name, optarg, N2N_IFNAMSIZ); + break; + } +#endif + + case 'b': + { + eee.re_resolve_supernode_ip = 1; + break; + } + + case 'p': + { + local_port = atoi(optarg); + break; + } + + case 't': + { + mgmt_port = atoi(optarg); + break; + } + + case 's': /* Subnet Mask */ + { + if (0 != got_s) + { + traceEvent(TRACE_WARNING, "Multiple subnet masks supplied."); + } + strncpy(netmask, optarg, N2N_NETMASK_STR_SIZE); + got_s = 1; + break; + } + + case 'h': /* help */ + { + help(); + break; + } + + case 'v': /* verbose */ + { + ++traceLevel; /* do 2 -v flags to increase verbosity to DEBUG level*/ + break; + } + +#ifdef WIN32 + case 'R': /* Remove */ + { + // request service removal + if (SCM_Remove(&sd)==0) { + printf("Deleted service '%s'\n",sd.name); + } else { + printf("Service removal failed\n"); + } + return 1; + } +#endif + + } /* end switch */ + } + + +#ifdef N2N_HAVE_DAEMON + if ( eee.daemon ) + { + useSyslog=1; /* traceEvent output now goes to syslog. */ + if ( -1 == daemon( 0, 0 ) ) + { + traceEvent( TRACE_ERROR, "Failed to become daemon." ); + exit(-5); + } + } +#endif /* #ifdef N2N_HAVE_DAEMON */ + + print_n2n_version(1 /* trace */); + + + for (i=0; i< N2N_EDGE_NUM_SUPERNODES; ++i ) + { + traceEvent( TRACE_NORMAL, "supernode %u => %s\n", i, (eee.sn_ip_array[i]) ); + } + + supernode2addr( &(eee.supernode), eee.sn_ip_array[eee.sn_idx] ); + + + for ( i=0; i 0) + traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)local_port); + + if ( encrypt_key ) { + if(edge_init_twofish( &eee, (uint8_t *)(encrypt_key), strlen(encrypt_key) ) < 0) { + fprintf(stderr, "Error: twofish setup failed.\n" ); + return(-1); + } + } else if ( strlen(eee.keyschedule) > 0 ) { + if (edge_init_keyschedule( &eee ) != 0 ) { + fprintf(stderr, "Error: keyschedule setup failed.\n" ); + return(-1); + } + + } + /* else run in NULL mode */ + + + eee.udp_sock = open_socket(local_port, 1 /*bind ANY*/ ); + if(eee.udp_sock < 0) + { + traceEvent( TRACE_ERROR, "Failed to bind main UDP port %u", (signed int)local_port ); + return(-1); + } + + + if(eee.local_sock_ena) { + if ( set_localip(&eee) != 0) { + traceEvent( TRACE_ERROR, "set localip failed" ); + return(-1); + } + } + + eee.udp_mgmt_sock = open_socket(mgmt_port, 0 /* bind LOOPBACK*/ ); + + if(eee.udp_mgmt_sock < 0) + { + traceEvent( TRACE_ERROR, "Failed to bind management UDP port %u", (unsigned int)N2N_EDGE_MGMT_PORT ); + return(-1); + } + + + traceEvent(TRACE_NORMAL, "edge started"); + + update_supernode_reg(&eee, time(NULL) ); + + return run_loop(&eee); +} + +int keep_running=1; +static int run_loop(n2n_edge_t * eee ) +{ + size_t numPurged; + time_t lastIfaceCheck=0; + time_t lastTransop=0; + time_t lastStatCalc=0; + time_t lastStatCalcDiff; + time_t lastLocalIPReResolve=0; + + +#ifdef WIN32 + startTunReadThread(eee); +#endif + + /* Main loop + * + * select() is used to wait for input on either the TAP fd or the UDP/TCP + * socket. When input is present the data is read and processed by either + * readFromIPSocket() or readFromTAPSocket() + */ + + while(keep_running) + { + int rc, max_sock = 0; + fd_set socket_mask; + struct timeval wait_time; + time_t nowTime; + + FD_ZERO(&socket_mask); + FD_SET(eee->udp_sock, &socket_mask); + FD_SET(eee->udp_mgmt_sock, &socket_mask); + max_sock = max( eee->udp_sock, eee->udp_mgmt_sock ); +#ifndef WIN32 + FD_SET(eee->device.fd, &socket_mask); + max_sock = max( max_sock, eee->device.fd ); +#endif + + wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS; wait_time.tv_usec = 0; + + rc = select(max_sock+1, &socket_mask, NULL, NULL, &wait_time); + nowTime=time(NULL); + + /* Make sure ciphers are updated before the packet is treated. */ + if ( ( nowTime - lastTransop ) > TRANSOP_TICK_INTERVAL ) + { + lastTransop = nowTime; + + n2n_tick_transop( eee, nowTime ); + } + + if(rc > 0) + { + /* Any or all of the FDs could have input; check them all. */ + + if(FD_ISSET(eee->udp_sock, &socket_mask)) + { + /* Read a cooked socket from the internet socket. Writes on the TAP + * socket. */ + readFromIPSocket(eee); + } + +#ifdef __ANDROID_NDK__ + if (uip_arp_len != 0) { + readFromTAPSocket(eee); + uip_arp_len = 0; + } +#endif /* #ifdef __ANDROID_NDK__ */ + + if(FD_ISSET(eee->udp_mgmt_sock, &socket_mask)) + { + /* Read a cooked socket from the internet socket. Writes on the TAP + * socket. */ + readFromMgmtSocket(eee, &keep_running); + } + +#ifndef WIN32 + if(FD_ISSET(eee->device.fd, &socket_mask)) + { + /* Read an ethernet frame from the TAP socket. Write on the IP + * socket. */ + readFromTAPSocket(eee); + } +#endif + } + + /* Finished processing select data. */ + + + update_supernode_reg(eee, nowTime); + + numPurged = 0; + if ((nowTime - eee->last_purge) >= PURGE_REGISTRATION_FREQUENCY) { + numPurged += hashed_purge_expired_registrations(eee->known_peers); + numPurged += hashed_purge_expired_registrations(eee->pending_peers); + eee->last_purge = nowTime; + } + if ( numPurged > 0 ) + { + traceEvent( TRACE_NORMAL, "Peer removed: pending=%u, operational=%u", + (unsigned int)hashed_peer_list_t_size( eee->pending_peers ), + (unsigned int)hashed_peer_list_t_size( eee->known_peers ) ); + } + + if ( eee->dyn_ip_mode && + (( nowTime - lastIfaceCheck ) > IFACE_UPDATE_INTERVAL ) ) + { + traceEvent(TRACE_NORMAL, "Re-checking dynamic IP address."); + tuntap_get_address( &(eee->device) ); + lastIfaceCheck = nowTime; + } + + if (eee->local_ip_str[0] != 0 && nowTime - lastLocalIPReResolve > LOCALIP_UPDATE_INTERVAL && strncmp(eee->local_ip_str, "auto", sizeof("auto")) == 0) { + traceEvent(TRACE_NORMAL, "Re-resove local socket."); + set_localip(eee); + lastLocalIPReResolve = nowTime; + } + + lastStatCalcDiff = nowTime - lastStatCalc; + if(lastStatCalcDiff > STAT_CALC_INTERVAL) { + // traceEvent(TRACE_NORMAL, "recalc bps."); + eee->tx_bps_p2p = eee->tx_bit_p2p / (size_t)lastStatCalcDiff; + eee->tx_bit_p2p = 0; + eee->tx_bps_sup = eee->tx_bit_sup / (size_t)lastStatCalcDiff; + eee->tx_bit_sup = 0; + eee->rx_bps_p2p = eee->rx_bit_p2p / (size_t)lastStatCalcDiff; + eee->rx_bit_p2p = 0; + eee->rx_bps_sup = eee->rx_bit_sup / (size_t)lastStatCalcDiff; + eee->rx_bit_sup = 0; + lastStatCalc = nowTime; + +#ifdef __ANDROID_NDK__ + uip_arp_timer(); +#endif /* #ifdef __ANDROID_NDK__ */ + } + + } /* while */ + + send_deregister( eee, &(eee->supernode)); + tuntap_close(&(eee->device)); + edge_deinit( eee ); + +#ifdef __ANDROID_NDK__ + traceEvent(TRACE_NORMAL, "Edge stoped."); + if (!slog) { + closeslog(slog); + slog = NULL; + } +#endif /* #ifdef __ANDROID_NDK__ */ + + return(0); +} + +#ifndef __ANDROID_NDK__ +int n2n_main(int argc, char **argv) { + return real_main(argc,argv); +} + +int n2n_stop(void *param1) { + keep_running=0; + return 0; +} + +int main(int argc, char **argv) +{ + if (SCM_Start(&sd,argc,argv)!=SVC_OK) { + return 1; + } + + return 0; +} +#else /* #ifdef __ANDROID_NDK__ */ +int start_edge_v2s(n2n_edge_status_t* status) +{ + int local_port = 0 /* any port */; + char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0"; + char ip_mode[N2N_IF_MODE_SIZE]="static"; + char ip_addr[N2N_NETMASK_STR_SIZE] = ""; + char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; + char device_mac[N2N_MACNAMSIZ]=""; + char * encrypt_key=NULL; + int i; + + if (!status) { + traceEvent( TRACE_ERROR, "Empty cmd struct" ); + return 1; + } + g_status = status; + n2n_edge_cmd_t* cmd = &status->cmd; + + keep_running = 0; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTING; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + traceLevel = cmd->trace_vlevel; + traceLevel = traceLevel < 0 ? 0 : traceLevel; /* TRACE_ERROR */ + traceLevel = traceLevel > 4 ? 4 : traceLevel; /* TRACE_DEBUG */ + if (!slog) { + closeslog(slog); + slog = NULL; + } + slog = initslog(android_log_level(traceLevel), cmd->logpath); + + if (-1 == edge_init(&eee) ) + { + traceEvent( TRACE_ERROR, "Failed in edge_init" ); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + memset(&(eee.supernode), 0, sizeof(eee.supernode)); + eee.supernode.family = AF_INET; + + if (cmd->vpn_fd < 0) { + traceEvent(TRACE_ERROR, "VPN socket is invalid."); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + eee.device.fd = cmd->vpn_fd; + if (cmd->enc_key_file) + { + strncpy(eee.keyschedule, cmd->enc_key_file, N2N_PATHNAME_MAXLEN-1); + eee.keyschedule[N2N_PATHNAME_MAXLEN-1]=0; /* strncpy does not add NULL if the source has no NULL. */ + traceEvent(TRACE_DEBUG, "keyfile = '%s'\n", eee.keyschedule); + } + else if (cmd->enc_key) + { + encrypt_key = strdup(cmd->enc_key); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key); + } + + if (cmd->ip_addr[0] != '\0') + { + scan_address(ip_addr, N2N_NETMASK_STR_SIZE, + ip_mode, N2N_IF_MODE_SIZE, + cmd->ip_addr); + } + else + { + traceEvent(TRACE_ERROR, "Ip address is not set."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if (cmd->community[0] != '\0') + { + strncpy((char *)eee.community_name, cmd->community, N2N_COMMUNITY_SIZE); + } + else + { + traceEvent(TRACE_ERROR, "Community is not set."); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + eee.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; + if (cmd->mac_addr[0] != '\0') + { + strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); + } + else + { + strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); + traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); + } + eee.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i) + { + if (cmd->supernodes[i][0] != '\0') + { + strncpy(eee.sn_ip_array[eee.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE); + traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)eee.sn_num, (eee.sn_ip_array[eee.sn_num])); + ++eee.sn_num; + } + } + eee.holepunch_interval = cmd->holepunch_interval; + eee.holepunch_interval = MAX(eee.holepunch_interval, REGISTER_SUPER_INTERVAL_MIN); + eee.holepunch_interval = MIN(eee.holepunch_interval, REGISTER_SUPER_INTERVAL_MAX); + if (cmd->local_ip[0] != '\0') + { + eee.local_sock_ena = 1; + strncpy(eee.local_ip_str, cmd->local_ip, N2N_EDGE_LOCAL_IP_SIZE); + if (N2N_EDGE_LOCAL_IP_SIZE > 0) + { + eee.local_ip_str[N2N_EDGE_LOCAL_IP_SIZE - 1] = '\0'; + } + traceEvent(TRACE_DEBUG, "Storing local_ip_str = %s\n", (eee.local_ip_str)); + } + eee.re_resolve_supernode_ip = cmd->re_resolve_supernode_ip == 0 ? 0 : 1; + if (cmd->ip_netmask[0] != '\0') + { + strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); + } + + + print_n2n_version(1 /* trace */); + for (i=0; i< N2N_EDGE_NUM_SUPERNODES; ++i ) + { + traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee.sn_ip_array[i])); + } + supernode2addr(&(eee.supernode), eee.sn_ip_array[eee.sn_idx]); + if (encrypt_key == NULL && strlen(eee.keyschedule) == 0) + { + traceEvent(TRACE_WARNING, "Encryption is disabled in edge."); + eee.null_transop = 1; + } + if (0 == strcmp("dhcp", ip_mode)) + { + traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled."); + eee.dyn_ip_mode = 1; + } + else + { + traceEvent(TRACE_NORMAL, "ip_mode='%s'", ip_mode); + } + if(tuntap_open(&(eee.device), tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) + { + traceEvent(TRACE_ERROR, "Failed in tuntap_open"); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if(local_port > 0) + { + traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)local_port); + } + if (encrypt_key) + { + if(edge_init_twofish(&eee, (uint8_t *)(encrypt_key), strlen(encrypt_key)) < 0) + { + traceEvent(TRACE_ERROR, "twofish setup failed.\n"); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + free(encrypt_key); + encrypt_key = NULL; + } + else if (strlen(eee.keyschedule) > 0) + { + if (edge_init_keyschedule(&eee) != 0) + { + traceEvent(TRACE_ERROR, "keyschedule setup failed.\n"); + free(encrypt_key); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + } + /* else run in NULL mode */ + eee.udp_sock = open_socket(local_port, 1 /*bind ANY*/ ); + if(eee.udp_sock < 0) + { + traceEvent(TRACE_ERROR, "Failed to bind main UDP port %u", (signed int)local_port); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + if(eee.local_sock_ena) + { + if (set_localip(&eee) != 0) + { + traceEvent(TRACE_ERROR, "set localip failed"); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + } + eee.udp_mgmt_sock = open_socket(N2N_EDGE_MGMT_PORT, 0 /* bind LOOPBACK*/ ); + if(eee.udp_mgmt_sock < 0) + { + traceEvent( TRACE_ERROR, "Failed to bind management UDP port %u", (unsigned int)N2N_EDGE_MGMT_PORT ); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + + /* set host addr, netmask, mac addr for UIP and init arp*/ + { + int match, i; + int ip[4]; + uip_ipaddr_t ipaddr; + struct uip_eth_addr eaddr; + + match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_sethostaddr(ipaddr); + match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3); + if (match != 4) { + traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask); + if (!slog) { + closeslog(slog); + slog = NULL; + } + return 1; + } + uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); + uip_setnetmask(ipaddr); + for (i = 0; i < 6; ++i) { + eaddr.addr[i] = eee.device.mac_addr[i]; + } + uip_setethaddr(eaddr); + + uip_arp_init(); + } + + keep_running = 1; + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + traceEvent(TRACE_NORMAL, "edge started"); + + update_supernode_reg(&eee, time(NULL)); + + return run_loop(&eee); +} + +int stop_edge_v2s(void) +{ + keep_running = 0; + + struct sockaddr_in peer_addr; + peer_addr.sin_family = PF_INET; + peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT); + sendto(eee.udp_mgmt_sock, "stop", 4, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in)); + + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + return 0; +} +#endif /* #ifdef __ANDROID_NDK__ */ diff --git a/bundles/n2n_meyerd/n2n_v2/gen_keyfile.py b/bundles/n2n_meyerd/n2n_v2/gen_keyfile.py new file mode 100644 index 00000000..b6dc3e67 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/gen_keyfile.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +# (c) 2009 Richard Andrews + +# Program to generate a n2n_edge key schedule file for twofish keys +# Each key line consists of the following element +# +# +# where , are UNIX time_t values of key valid period +# is the transform ID (=2 for twofish) +# is twofish-specific data as follows +# _ + +import os +import sys +import time +import random + +NUM_KEYS=30 +KEY_LIFE=300 +KEY_LEN=16 + +now=time.time() +start_sa=random.randint( 0, 0xffffffff ) + +random.seed(now) # note now is a floating point time value + +def rand_key(): + key=str() + for i in range(0,KEY_LEN): + key += "%02x"%( random.randint( 0, 255) ) + + return key + +for i in range(0,NUM_KEYS): + from_time = now + (KEY_LIFE * (i-1) ) + until_time = now + (KEY_LIFE * (i+1) ) + key = rand_key() + sa_idx = start_sa + i + transform_id = random.randint( 2, 3 ) + + sys.stdout.write("%d %d %d %d_%s\n"%(from_time, until_time, transform_id,sa_idx, key) ) + + diff --git a/bundles/n2n_meyerd/n2n_v2/lzoconf.h b/bundles/n2n_meyerd/n2n_v2/lzoconf.h new file mode 100644 index 00000000..cc437f1e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/lzoconf.h @@ -0,0 +1,417 @@ +/* lzoconf.h -- configuration for the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED + +#define LZO_VERSION 0x2030 +#define LZO_VERSION_STRING "2.03" +#define LZO_VERSION_DATE "Apr 30 2008" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +#if !defined(LZO_UINT32_C) +# if (UINT_MAX < LZO_0xffffffffL) +# define LZO_UINT32_C(c) c ## UL +# else +# define LZO_UINT32_C(c) ((c) + 0U) +# endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint should match size_t */ +#if !defined(LZO_UINT_MAX) +# if defined(LZO_ABI_LLP64) /* WIN64 */ +# if defined(LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# else + typedef unsigned long long lzo_uint; + typedef long long lzo_int; +# endif +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* Integral types with 32 bits or more. */ +#if !defined(LZO_UINT32_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint32; + typedef int lzo_int32; +# define LZO_UINT32_MAX UINT_MAX +# define LZO_INT32_MAX INT_MAX +# define LZO_INT32_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint32; + typedef long lzo_int32; +# define LZO_UINT32_MAX ULONG_MAX +# define LZO_INT32_MAX LONG_MAX +# define LZO_INT32_MIN LONG_MIN +# else +# error "lzo_uint32" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32. */ +#if (LZO_UINT_MAX >= LZO_UINT32_MAX) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32 +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +# if (LZO_UINT_MAX <= UINT_MAX) +# define __LZO_MMODEL +# elif defined(LZO_HAVE_MM_HUGE_PTR) +# define __LZO_MMODEL_HUGE 1 +# define __LZO_MMODEL __huge +# else +# define __LZO_MMODEL +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_uint32p lzo_uint32 __LZO_MMODEL * +#define lzo_int32p lzo_int32 __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * +/* deprecated - use `lzo_bytep' instead of `lzo_byte *' */ +#define lzo_byte unsigned char __LZO_MMODEL + +typedef int lzo_bool; + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) +lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) +lzo_adler32(lzo_uint32 _adler, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(lzo_uint32) +lzo_crc32(lzo_uint32 _c, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(const lzo_uint32p) +lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of `size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); +#define LZO_PTR_ALIGN_UP(_ptr,_size) \ + ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility with LZO v1.xx +************************************************************************/ + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL +#define __LZO_DMODEL +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_meyerd/n2n_v2/lzodefs.h b/bundles/n2n_meyerd/n2n_v2/lzodefs.h new file mode 100644 index 00000000..18056372 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/lzodefs.h @@ -0,0 +1,1807 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif /* already included */ + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_meyerd/n2n_v2/minilzo.c b/bundles/n2n_meyerd/n2n_v2/minilzo.c new file mode 100644 index 00000000..6a62b31b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/minilzo.c @@ -0,0 +1,4112 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO +#define LZO_BUILD + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2030) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +# define ACC_LIBC_FREESTANDING 1 +# define ACC_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# define ACC_CFG_NO_UNALIGNED 1 +#endif +#if defined(LZO_ARCH_GENERIC) +# define ACC_ARCH_GENERIC 1 +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# define ACC_ABI_NEUTRAL_ENDIAN 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define ACC_CONFIG_NO_HEADER 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#endif + +#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_BORLANDC && LZO_ARCH_I086) +# pragma option -h +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +# pragma warning(disable: 4514 4710 4711) +#endif + +#if (LZO_CC_SUNPROC) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +#endif + +#if defined(__LZO_MMODEL_HUGE) && (!LZO_HAVE_MM_HUGE_PTR) +# error "this should not happen - check defines for __huge" +#endif + +#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define ACC_WANT_ACC_INCD_H 1 +# define ACC_WANT_ACC_INCE_H 1 +# define ACC_WANT_ACC_INCI_H 1 +#elif 1 +# include +#else +# define ACC_WANT_ACC_INCD_H 1 +#endif + +#if (LZO_ARCH_I086) +# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT +# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) +# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) +# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) +# define __LZO_UINTPTR_T_IS_POINTER 1 + typedef char* lzo_uintptr_t; +# define lzo_uintptr_t lzo_uintptr_t +# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t size_t +# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long +# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned int +# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long long +# else +# define lzo_uintptr_t size_t +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if defined(LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !defined(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !defined(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !defined(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !defined(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if defined(LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if !defined(__lzo_inline) +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +# define __lzo_noinline +#endif + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#if 1 && !defined(LZO_CFG_NO_UNALIGNED) +#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if (LZO_SIZEOF_SHORT == 2) +# define LZO_UNALIGNED_OK_2 +# endif +# if (LZO_SIZEOF_INT == 4) +# define LZO_UNALIGNED_OK_4 +# endif +#endif +#endif + +#if defined(LZO_UNALIGNED_OK_2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2) +#endif +#if defined(LZO_UNALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#elif defined(LZO_ALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +__LZO_EXTERN_C int __lzo_init_done; +__LZO_EXTERN_C const char __lzo_copyright[]; +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# else +# define lzo_uintptr_t acc_uintptr_t +# ifdef __ACC_INTPTR_T_IS_POINTER +# define __LZO_UINTPTR_T_IS_POINTER 1 +# endif +# endif +#endif + +#if (LZO_ARCH_I086) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#elif (LZO_MM_PVP) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) +#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#define LZO_DETERMINISTIC + +#define LZO_DICT_USE_PTR +#if 0 && (LZO_ARCH_I086) +# undef LZO_DICT_USE_PTR +#endif + +#if defined(LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) + p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#elif (LZO_MM_PVP) + p = (lzo_uintptr_t) (ptr); + p = (p << 3) | (p >> 61); +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if defined(__LZO_UINTPTR_T_IS_POINTER) + size_t n = (size_t) ptr; + n = (((n + size - 1) / size) * size) - n; +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Built: " __DATE__ " " __TIME__ " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ +#if (LZO_OS_DOS16 && LZO_CC_TURBOC) + return (lzo_voidp) __lzo_copyright; +#else + return (const lzo_bytep) __lzo_copyright; +#endif +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCMP) + const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCPY) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMMOVE) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMSET) + lzo_hbyte_p p = (lzo_hbyte_p) s; + if __lzo_likely(len > 0) do + *p++ = (unsigned char) c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, c, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif + +#if !defined(__LZO_IN_MINILZO) + +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) + ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) + +#if !defined(__LZO_UINTPTR_T_IS_POINTER) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) + ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + +#endif +#undef ACCCHK_ASSERT + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + union { unsigned char c[2*sizeof(lzo_xint)]; lzo_xint l[2]; } u; + lzo_uintptr_t p; + +#if !defined(LZO_CFG_NO_CONFIG_CHECK) +#if defined(LZO_ABI_BIG_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[sizeof(lzo_xint) - 1] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_ABI_LITTLE_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[0] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_UNALIGNED_OK_2) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_ushortp) (p+1)) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_4) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_uint32p) (p+1)) == 0); +#endif +#endif + + LZO_UNUSED(u); LZO_UNUSED(p); + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +int __lzo_init_done = 0; + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT +#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef ACCCHK_ASSERT + + __lzo_init_done = 1; + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#define do_compress _lzo1x_1_do_compress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#define LZO_NEED_DICT_H +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 8 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 8 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if defined(LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_uint) ((p)-(in))) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if defined(LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) <= 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if defined(LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define DO_COMPRESS lzo1x_1_compress + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + register const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - M2_MAX_LEN - 5; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += 4; + for (;;) + { + register const lzo_bytep m_pos; + lzo_uint m_off; + lzo_uint m_len; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } + else + { + if __lzo_likely(m_pos[2] == ip[2]) + { +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) + { + assert(op - 2 > out); op[-2] |= LZO_BYTE(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (m_pos[3] == ip[3]) +#endif + goto match; + } + else + { +#if 0 +#if 0 + if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else + if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif + { + register lzo_uint t; + + t = lit; + assert(op - 2 > out); op[-2] |= LZO_BYTE(t); + do *op++ = *ii++; while (--t > 0); + assert(ii == ip); + m_off -= 1; + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); + ip += 2; + goto match_done; + } +#endif + } + } + +literal: + UPDATE_I(dict,0,dindex,ip,in); + ++ip; + if __lzo_unlikely(ip >= ip_end) + break; + continue; + +match: + UPDATE_I(dict,0,dindex,ip,in); + if (pd(ip,ii) > 0) + { + register lzo_uint t = pd(ip,ii); + + if (t <= 3) + { + assert(op - 2 > out); + op[-2] |= LZO_BYTE(t); + } + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + assert(ii == ip); + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ || + m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y + || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ + || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif + ) + { + --ip; + m_len = pd(ip, ii); + assert(m_len >= 3); assert(m_len <= M2_MAX_LEN); + + if (m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } + else +#if defined(LZO1X) + { + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + goto m3_m4_offset; + } +#elif defined(LZO1Y) + goto m4_match; +#endif + } + else + { + { + const lzo_bytep end = in_end; + const lzo_bytep m = m_pos + M2_MAX_LEN + 1; + while (ip < end && *m == *ip) + m++, ip++; + m_len = pd(ip, ii); + } + assert(m_len > M2_MAX_LEN); + + if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= 33) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } + else + { +#if defined(LZO1Y) +m4_match: +#endif + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11)); +m3_m4_len: + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + } + +m3_m4_offset: + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + +#if 0 +match_done: +#endif + ii = ip; + if __lzo_unlikely(ip >= ip_end) + break; + } + + *out_len = pd(op, out); + return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_bytep op = out; + lzo_uint t; + + if __lzo_unlikely(in_len <= M2_MAX_LEN + 5) + t = in_len; + else + { + t = do_compress(in,in_len,op,out_len,wrkmem); + op += *out_len; + } + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ + diff --git a/bundles/n2n_meyerd/n2n_v2/minilzo.h b/bundles/n2n_meyerd/n2n_v2/minilzo.h new file mode 100644 index 00000000..0aff50e4 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/minilzo.h @@ -0,0 +1,106 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H + +#define MINILZO_VERSION 0x2030 + +#ifdef __LZOCONF_H +# error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/bundles/n2n_meyerd/n2n_v2/munin/n2n-supernode b/bundles/n2n_meyerd/n2n_v2/munin/n2n-supernode new file mode 100644 index 00000000..0064b38e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/munin/n2n-supernode @@ -0,0 +1,110 @@ +#!/usr/bin/env perl +use warnings; +use strict; + +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + +use IO::Socket::INET; +use Munin::Plugin; + +my $fields = { + edges => { + label => 'Current Connected clients', + }, + errors => { + label => 'Error rate', + type => 'DERIVE', + min => 0, + }, + reg_sup => { + label => 'Connect rate', + type => 'DERIVE', + min => 0, + }, + reg_nak => { + label => 'Connect error rate', + type => 'DERIVE', + min => 0, + }, + fwd => { + label => 'Packets forwarded rate', + type => 'DERIVE', + min => 0, + }, + broadcast => { + label => 'Broadcast packet rate', + type => 'DERIVE', + min => 0, + }, +}; + +sub do_config { + print("graph_title n2n supernode status\n"); + print("graph_category network\n"); + print("graph_order edges errors reg_sup reg_nak fwd broadcast\n"); + for my $fieldname (keys(%{$fields})) { + my $field = $fields->{$fieldname}; + for my $key (keys(%{$field})) { + print($fieldname.'.'.$key," ",$field->{$key},"\n"); + } + } + exit 0; +} + +sub do_autoconf { + # quick check to see if this plugin should be enabled + if (`pgrep supernode`) { + print("yes\n"); + exit 0; + } else { + print("no - supernode is not running\n"); + exit 0; + } +} + +sub do_fetch { + my $sock = IO::Socket::INET->new( + PeerAddr => '127.0.0.1', + PeerPort => 5645, + Proto => 'udp', + ); + $sock->send("\n"); + my $buf; + $sock->recv($buf,4096); + undef $sock; + + my $db; + for my $line (split(/\n/,$buf)) { + if ($line =~ m/^(last [a-z]+) +(\d+) sec ago$/) { + $db->{$1} = $2; + next; + } + if ($line =~ m/^([a-z_]+) +(\d+)$/) { + $db->{$1} = $2; + next; + } + } + + for my $field (keys(%{$fields})) { + print($field.".value ",$db->{$field},"\n"); + } + exit 0; +} + +sub main() { + if (!defined($ARGV[0])) { + do_fetch(); + } + if ($ARGV[0] eq 'config') { + do_config(); + } + if ($ARGV[0] eq 'autoconf') { + do_autoconf(); + } + die("bad arg"); +} +main(); + diff --git a/bundles/n2n_meyerd/n2n_v2/n2n.c b/bundles/n2n_meyerd/n2n_v2/n2n.c new file mode 100644 index 00000000..477bb6a9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n.c @@ -0,0 +1,536 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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, see + * + * Code contributions courtesy of: + * Massimo Torquati + * Matt Gilg + * + */ + +#include "n2n.h" + +#include "minilzo.h" + +#include + +/* sglib hash table implementation */ + +SGLIB_DEFINE_LIST_FUNCTIONS(peer_info_t, PEER_INFO_COMPARATOR, next) +SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(peer_info_t, PEER_HASH_TAB_SIZE, peer_info_t_hash_function) + +unsigned int peer_info_t_hash_function(peer_info_t *e) { +#if N2N_MAC_SIZE != 6 + #error not implemented yet! +#else + short i = 0; + uint32_t tmp = 0; + /* Q: why is the hashing implemented like this? + * A: because the MAC addresses basically consist of two parts + * the first three bytes are a organisation unique identifier + * the second three bytes are a interface unique identifier + * therefore if all the (randomly) generated MAC addresses of the + * tun/tap interfaces all have the same organisation unique identifier + * the hashing performance is best if only the interface unique identifier + * is taken into account + */ + for(; i < N2N_MAC_SIZE / 2; i++) { + tmp |= (e->mac_addr[i] ^ e->mac_addr[(N2N_MAC_SIZE/2)+i]) + << (N2N_MAC_SIZE/2-1-i); + } + return tmp; +#endif +}; + + +const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */ +const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */ + +/* ************************************** */ + +SOCKET open_socket(int local_port, int bind_any) { + SOCKET sock_fd; + struct sockaddr_in local_address; + int sockopt = 1; + + if((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", + strerror(errno), sock_fd); + return(-1); + } + +#ifndef WIN32 + /* fcntl(sock_fd, F_SETFL, O_NONBLOCK); */ +#endif + + setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); + + memset(&local_address, 0, sizeof(local_address)); + local_address.sin_family = AF_INET; + local_address.sin_port = htons(local_port); + local_address.sin_addr.s_addr = htonl(bind_any?INADDR_ANY:INADDR_LOOPBACK); + if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) { + traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); + return(-1); + } + + return(sock_fd); +} + + + + + +int traceLevel = 2 /* NORMAL */; +int useSyslog = 0, syslog_opened = 0; + +#ifdef __ANDROID_NDK__ +slog_t* slog = NULL; +int android_log_level(int lvl) +{ + switch (lvl) { + case 0: // ERROR + return ANDROID_LOG_ERROR; + case 1: // WARNING + return ANDROID_LOG_WARN; + case 2: // NORMAL + return ANDROID_LOG_INFO; + case 3: // INFO + return ANDROID_LOG_DEBUG; + case 4: // DEBUG + return ANDROID_LOG_VERBOSE; + default: // NORMAL + return ANDROID_LOG_INFO; + } +} +#endif /* #ifdef __ANDROID_NDK__ */ + +#define N2N_TRACE_DATESIZE 32 +void traceEvent(int eventTraceLevel, char* file, int line, const char * format, ...) { + va_list va_ap; + + if(eventTraceLevel <= traceLevel) { + char buf[2048]; + char out_buf[640]; + char theDate[N2N_TRACE_DATESIZE]; + char *extra_msg = ""; + time_t theTime = time(NULL); +#ifdef WIN32 + int i; +#endif + + /* We have two paths - one if we're logging, one if we aren't + * Note that the no-log case is those systems which don't support it (WIN32), + * those without the headers !defined(USE_SYSLOG) + * those where it's parametrically off... + */ + + memset(buf, 0, sizeof(buf)); + strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); + + va_start (va_ap, format); + vsnprintf(buf, sizeof(buf)-1, format, va_ap); + va_end(va_ap); + + if(eventTraceLevel == 0 /* TRACE_ERROR */) + extra_msg = "ERROR: "; + else if(eventTraceLevel == 1 /* TRACE_WARNING */) + extra_msg = "WARNING: "; + + while(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + +#ifndef WIN32 + if(useSyslog) { + if(!syslog_opened) { + openlog("n2n", LOG_PID, LOG_DAEMON); + syslog_opened = 1; + } + + snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); + syslog(LOG_INFO, "%s", out_buf); + } else { +#ifdef __ANDROID_NDK__ + char * p = strrchr(file, '/'); + file = (p ? p + 1 : file); +#endif /* #ifdef __ANDROID_NDK__ */ + snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, file, line, extra_msg, buf); +#ifdef __ANDROID_NDK__ + slog = writeslog(slog, android_log_level(eventTraceLevel), "n2n_v2s", out_buf); +#else /* #ifdef __ANDROID_NDK__ */ + printf("%s\n", out_buf); + fflush(stdout); +#endif /* #ifdef __ANDROID_NDK__ */ + } +#else + /* this is the WIN32 code */ + OutputDebugStringA(buf); + for(i=strlen(file)-1; i>0; i--) if(file[i] == '\\') { i++; break; }; + snprintf(out_buf, sizeof(out_buf), "%s [%11s:%4d] %s%s", theDate, &file[i], line, extra_msg, buf); + printf("%s\n", out_buf); + fflush(stdout); +#endif + } + +} + +/* *********************************************** */ + +/* addr should be in network order. Things are so much simpler that way. */ +char* intoa(uint32_t /* host order */ addr, char* buf, uint16_t buf_len) { + char *cp, *retStr; + uint8_t byteval; + int n; + + cp = &buf[buf_len]; + *--cp = '\0'; + + n = 4; + do { + byteval = addr & 0xff; + *--cp = byteval % 10 + '0'; + byteval /= 10; + if (byteval > 0) { + *--cp = byteval % 10 + '0'; + byteval /= 10; + if (byteval > 0) + *--cp = byteval + '0'; + } + *--cp = '.'; + addr >>= 8; + } while (--n > 0); + + /* Convert the string to lowercase */ + retStr = (char*)(cp+1); + + return(retStr); +} + +/* *********************************************** */ + +char * macaddr_str( macstr_t buf, + const n2n_mac_t mac ) +{ + snprintf(buf, N2N_MACSTR_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0] & 0xFF, mac[1] & 0xFF, mac[2] & 0xFF, + mac[3] & 0xFF, mac[4] & 0xFF, mac[5] & 0xFF); + return(buf); +} + +/* *********************************************** */ + +uint8_t is_multi_broadcast(const uint8_t * dest_mac) { + + int is_broadcast = ( memcmp(broadcast_addr, dest_mac, 6) == 0 ); + int is_multicast = ( memcmp(multicast_addr, dest_mac, 3) == 0 ); + int is_ipv6_multicast = ( memcmp(ipv6_multicast_addr, dest_mac, 2) == 0 ); + + return is_broadcast || is_multicast || is_ipv6_multicast; + +} + +/* http://www.faqs.org/rfcs/rfc908.html */ + + +/* *********************************************** */ + +char* msg_type2str(uint16_t msg_type) { + switch(msg_type) { + case MSG_TYPE_REGISTER: return("MSG_TYPE_REGISTER"); + case MSG_TYPE_DEREGISTER: return("MSG_TYPE_DEREGISTER"); + case MSG_TYPE_PACKET: return("MSG_TYPE_PACKET"); + case MSG_TYPE_REGISTER_ACK: return("MSG_TYPE_REGISTER_ACK"); + case MSG_TYPE_REGISTER_SUPER: return("MSG_TYPE_REGISTER_SUPER"); + case MSG_TYPE_REGISTER_SUPER_ACK: return("MSG_TYPE_REGISTER_SUPER_ACK"); + case MSG_TYPE_REGISTER_SUPER_NAK: return("MSG_TYPE_REGISTER_SUPER_NAK"); + case MSG_TYPE_FEDERATION: return("MSG_TYPE_FEDERATION"); + default: return("???"); + } + + return("???"); +} + +/* *********************************************** */ + +void hexdump(const uint8_t * buf, size_t len) +{ + size_t i; + + if ( 0 == len ) { return; } + + for(i=0; i 0) && ((i % 16) == 0)) { printf("\n"); } + printf("%02X ", buf[i] & 0xFF); + } + + printf("\n"); +} + +/* *********************************************** */ + +void print_n2n_version(int trace) { + const char* bufline = "Welcome to n2n v.%s for %s\n" + "Built on %s\n" + "Copyright 2007-09 - http://www.ntop.org\n" + "Modify version %s\n" + "Modify by %s\n" + "Modify Copyright 2018 - %d - https://github.com/switch-iot/hin2n\n\n"; + time_t t = time(NULL); + if (trace == 1) { + traceEvent(TRACE_NORMAL, bufline, n2n_sw_version, n2n_sw_osName, n2n_sw_buildDate, n2n_mod_version, n2n_mod_author, localtime(&t)->tm_year + 1900); + } else { + printf(bufline, bufline, n2n_sw_version, n2n_sw_osName, n2n_sw_buildDate, n2n_mod_version, n2n_mod_author, localtime(&t)->tm_year + 1900); + } +} + +const char* random_device_mac(void) +{ + const char key[] = "0123456789abcdef"; + static char mac[18]; + int i; + + srand(gettid()); + for (i = 0; i < sizeof(mac) - 1; ++i) + { + if ((i + 1) % 3 == 0) { + mac[i] = ':'; + continue; + } + mac[i] = key[random() % sizeof(key)]; + } + mac[sizeof(mac) - 1] = '\0'; + return mac; +} + + +/** Find the peer entry in list with mac_addr equal to mac. + * + * Does not modify the list. + * + * @return NULL if not found; otherwise pointer to peer entry. + */ +peer_info_t * find_peer_by_mac( peer_info_t ** list, const n2n_mac_t mac ) +{ + peer_info_t tmp; + memcpy(tmp.mac_addr, mac, sizeof(n2n_mac_t)); + + return sglib_hashed_peer_info_t_find_member(list, &tmp); +} + + +/** Return the number of elements in the list. + * + */ +size_t peer_list_size( const struct peer_info * list ) +{ + size_t retval=0; + + while ( list ) + { + ++retval; + list = list->next; + } + + return retval; +} + +size_t hashed_peer_list_t_size(peer_info_t** htab) { + peer_info_t *ll; + struct sglib_hashed_peer_info_t_iterator it; + size_t retval = 0; + + for(ll=sglib_hashed_peer_info_t_it_init(&it,htab); ll!=NULL; ll=sglib_hashed_peer_info_t_it_next(&it)) { + ++retval; + } + + return retval; +} + +/** Add new to the head of list. If list is NULL; create it. + * + * The item new is added to the head of the list. New is modified during + * insertion. list takes ownership of new. + */ +void peer_list_add( struct peer_info * * list, + struct peer_info * new ) +{ + new->next = *list; + new->last_seen = time(NULL); + *list = new; +} + +size_t purge_with_function(struct peer_info ** peer_list, size_t(*purger)(struct peer_info ** peer_list, time_t purge_before)) { + time_t now = time(NULL); + size_t num_reg = 0; + + traceEvent(TRACE_INFO, "Purging old registrations"); + + num_reg = purger( peer_list, now-REGISTRATION_TIMEOUT ); + + traceEvent(TRACE_INFO, "Remove %ld registrations", num_reg); + + return num_reg; +} + +void dealloc_peer( peer_info_t* peer ) +{ + free(peer->sockets); + free(peer); +} + + +/** Purge old items from the peer_list and return the number of items that were removed. */ +size_t purge_peer_list( struct peer_info ** peer_list, + time_t purge_before ) +{ + struct peer_info *scan; + struct peer_info *prev; + size_t retval=0; + + scan = *peer_list; + prev = NULL; + while(scan != NULL) { + if(scan->last_seen < purge_before) { + struct peer_info *next = scan->next; + + if(prev == NULL) { + *peer_list = next; + } else { + prev->next = next; + } + ++retval; + dealloc_peer(scan); + scan = next; + } else { + prev = scan; + scan = scan->next; + } + } + return retval; +} + +size_t purge_hashed_peer_list_t(peer_info_t ** peer_list, time_t purge_before) { + peer_info_t *ll; + struct sglib_hashed_peer_info_t_iterator it; + size_t retval = 0; + + for(ll=sglib_hashed_peer_info_t_it_init(&it,peer_list); ll!=NULL; + ll=sglib_hashed_peer_info_t_it_next(&it)) { + if(ll->last_seen < purge_before) { + ++retval; + sglib_hashed_peer_info_t_delete(peer_list, ll); + dealloc_peer(ll); + } + } + + return retval; +} + +size_t purge_expired_registrations( struct peer_info ** peer_list ) { + return purge_with_function(peer_list, purge_peer_list); +} + +size_t hashed_purge_expired_registrations(peer_info_t ** peer_list) { + return purge_with_function(peer_list, purge_hashed_peer_list_t); +} + +size_t clear_hashed_peer_info_t_list(peer_info_t ** peer_list) { + peer_info_t *ll; + struct sglib_hashed_peer_info_t_iterator it; + size_t retval = 0; + + for(ll=sglib_hashed_peer_info_t_it_init(&it,peer_list); ll!=NULL; ll=sglib_hashed_peer_info_t_it_next(&it)) { + ++retval; + sglib_hashed_peer_info_t_delete(peer_list, ll); + dealloc_peer(ll); + } + + return retval; +} + +static uint8_t hex2byte( const char * s ) +{ + char tmp[3]; + tmp[0]=s[0]; + tmp[1]=s[1]; + tmp[2]=0; /* NULL term */ + + return((uint8_t)strtol( tmp, NULL, 16 )); +} + +extern int str2mac( uint8_t * outmac /* 6 bytes */, const char * s ) +{ + size_t i; + + /* break it down as one case for the first "HH", the 5 x through loop for + * each ":HH" where HH is a two hex nibbles in ASCII. */ + + *outmac=hex2byte(s); + ++outmac; + s+=2; /* don't skip colon yet - helps generalise loop. */ + + for (i=1; i<6; ++i ) + { + s+=1; + *outmac=hex2byte(s); + ++outmac; + s+=2; + } + + return 0; /* ok */ +} + +extern char * sock_to_cstr( n2n_sock_str_t out, + const n2n_sock_t * sock ) +{ + if ( NULL == out ) { return NULL; } + memset(out, 0, N2N_SOCKBUF_SIZE); + + if ( AF_INET6 == sock->family ) + { + /* INET6 not written yet */ + snprintf( out, N2N_SOCKBUF_SIZE, "XXXX:%hu", sock->port ); + return out; + } + else + { + const uint8_t * a = sock->addr.v4; + snprintf( out, N2N_SOCKBUF_SIZE, "%d.%d.%d.%d:%d", (a[0] & 0xff), + (a[1] & 0xff), (a[2] & 0xff), (a[3] & 0xff), sock->port ); + return out; + } +} + +/* @return zero if the two sockets are equivalent. */ +int sock_equal( const n2n_sock_t * a, + const n2n_sock_t * b ) +{ + if ( a->port != b->port ) { return 1; } + if ( a->family != b->family ) { return 1; } + switch (a->family) /* they are the same */ + { + case AF_INET: + if ( 0 != memcmp( a->addr.v4, b->addr.v4, IPV4_SIZE ) ) { return 1;}; + break; + default: + if ( 0 != memcmp( a->addr.v6, b->addr.v6, IPV6_SIZE ) ) { return 1;}; + break; + } + + return 0; +} + diff --git a/bundles/n2n_meyerd/n2n_v2/n2n.h b/bundles/n2n_meyerd/n2n_v2/n2n.h new file mode 100644 index 00000000..87e3bf0e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n.h @@ -0,0 +1,315 @@ +/* + * (C) 2007-09 - Luca Deri + * Richard Andrews + * + * 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 3 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, see + * + * Code contributions courtesy of: + * Babak Farrokhi [FreeBSD port] + * Lukasz Taczuk + * + */ + +#ifndef _N2N_H_ +#define _N2N_H_ + +/* + tunctl -t tun0 + tunctl -t tun1 + ifconfig tun0 1.2.3.4 up + ifconfig tun1 1.2.3.5 up + ./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello + ./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello + + + tunctl -u UID -t tunX +*/ + +#if defined(__APPLE__) && defined(__MACH__) +#define _DARWIN_ +#endif + + +/* Some capability defaults which can be reset for particular platforms. */ +#define N2N_HAVE_DAEMON 1 +#define N2N_HAVE_SETUID 1 +/* #define N2N_CAN_NAME_IFACE */ + +/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */ +#ifdef WIN32 +#include "win32/n2n_win32.h" +#undef N2N_HAVE_DAEMON +#undef N2N_HAVE_SETUID +#endif + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#ifndef _MSC_VER +#include +#endif /* #ifndef _MSC_VER */ + +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#define N2N_CAN_NAME_IFACE 1 +#endif /* #ifdef __linux__ */ + +#ifdef __FreeBSD__ +#include +#endif /* #ifdef __FreeBSD__ */ + +#include +#include + +#define ETH_ADDR_LEN 6 +struct ether_hdr +{ + uint8_t dhost[ETH_ADDR_LEN]; + uint8_t shost[ETH_ADDR_LEN]; + uint16_t type; /* higher layer protocol encapsulated */ +} __attribute__ ((__packed__)); + +typedef struct ether_hdr ether_hdr_t; + +#ifdef __sun__ +#include /* MIN() and MAX() declared here */ +#undef N2N_HAVE_DAEMON +#endif /* #ifdef __sun__ */ + +#ifdef __ANDROID_NDK__ +#undef N2N_HAVE_DAEMON +#undef N2N_HAVE_SETUID +#undef N2N_CAN_NAME_IFACE +#endif /* #ifdef __ANDROID_NDK__ */ + +#include +#include +#include +#include +#include +#include +#include + +#define closesocket(a) close(a) +#endif /* #ifndef WIN32 */ + +#include + +#include + +#ifdef WIN32 +#include "win32/wintap.h" +#endif /* #ifdef WIN32 */ + +/* include sglib for hash tables */ +#include "sglib.h" + +#include "n2n_wire.h" + +/* N2N_IFNAMSIZ is needed on win32 even if dev_name is not used after declaration */ +#define N2N_IFNAMSIZ 16 /* 15 chars * NULL */ +#ifndef WIN32 +typedef struct tuntap_dev { + int fd; + uint8_t mac_addr[6]; + uint32_t ip_addr, device_mask; + uint16_t mtu; + char dev_name[N2N_IFNAMSIZ]; +} tuntap_dev; + +#define SOCKET int +#endif /* #ifndef WIN32 */ + +#define QUICKLZ 1 + +/* N2N packet header indicators. */ +#define MSG_TYPE_REGISTER 1 +#define MSG_TYPE_DEREGISTER 2 +#define MSG_TYPE_PACKET 3 +#define MSG_TYPE_REGISTER_ACK 4 +#define MSG_TYPE_REGISTER_SUPER 5 +#define MSG_TYPE_REGISTER_SUPER_ACK 6 +#define MSG_TYPE_REGISTER_SUPER_NAK 7 +#define MSG_TYPE_FEDERATION 8 +#define MSG_TYPE_PEER_INFO 9 +#define MSG_TYPE_QUERY_PEER 10 + +/* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet + * frames. Doing this will break compatibility with the standard n2n packet + * format so do it only for experimentation. All edges must be built with the + * same value if they are to understand each other. */ +#define N2N_COMPRESSION_ENABLED 1 + +#define DEFAULT_MTU 1400 + +/* Frequency registration should be attempted to purge and timeout value after + * which to purge*/ +#if defined(DEBUG) +# define PURGE_REGISTRATION_FREQUENCY 60 +# define REGISTRATION_TIMEOUT 120 +#else /* #if defined(DEBUG) */ +# define PURGE_REGISTRATION_FREQUENCY 60 +# define REGISTRATION_TIMEOUT 120 +#endif /* #if defined(DEBUG) */ + +/** Common type used to hold stringified IP addresses. */ +typedef char ipstr_t[32]; + +/** Common type used to hold stringified MAC addresses. */ +#define N2N_MACSTR_SIZE 32 +typedef char macstr_t[N2N_MACSTR_SIZE]; + +struct peer_info { + struct peer_info * next; + n2n_community_t community_name; + n2n_mac_t mac_addr; + n2n_sock_t sock; + int num_sockets; + n2n_sock_t * sockets; + time_t last_seen; + time_t last_sent_query; + size_t timeout; +}; +typedef struct peer_info peer_info_t; + +/* sglib hash table defines */ +#define PEER_HASH_TAB_SIZE 53 // prime number + +/* #define PEER_INFO_COMPARATOR(e1, e2) (\ + for(int i = 0; i < N2N_MAC_SIZE; i++) {\ + int8_t tmp = (e1)->mac_addr[i] - (e2)->mac_addr[i]; \ + if(tmp != 0) \ + return tmp; \ + } \ + return 0; \ +}) +*/ + +#define PEER_INFO_COMPARATOR(e1, e2) (strncmp((const char*)(e1)->mac_addr, (const char*)(e2)->mac_addr, sizeof(n2n_mac_t))) + +unsigned int peer_info_t_hash_function(peer_info_t *e); + +SGLIB_DEFINE_LIST_PROTOTYPES(peer_info_t, PEER_INFO_COMPARATOR, next) +SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(peer_info_t, PEER_HASH_TAB_SIZE, peer_info_t_hash_function) + +struct n2n_edge; /* defined in edge.c */ +typedef struct n2n_edge n2n_edge_t; + + +/* ************************************** */ + +#ifdef __ANDROID_NDK__ +#include +extern int android_log_level(int lvl); +extern slog_t* slog; +#ifndef N2N_LOG_FILEPATH +#define N2N_LOG_FILEPATH "/storage/sdcard0/wang.switchy.hin2n/n2n_v2s.log" +#endif /* #ifndef N2N_LOG_FILEPATH */ +#endif /* #ifdef __ANDROID_NDK__ */ +#define TRACE_ERROR 0, __FILE__, __LINE__ +#define TRACE_WARNING 1, __FILE__, __LINE__ +#define TRACE_NORMAL 2, __FILE__, __LINE__ +#define TRACE_INFO 3, __FILE__, __LINE__ +#define TRACE_DEBUG 4, __FILE__, __LINE__ + +/* ************************************** */ + +#define SUPERNODE_IP "127.0.0.1" +#define SUPERNODE_PORT 1234 + +/* ************************************** */ + +#ifndef max +#define max(a, b) ((a < b) ? b : a) +#endif + +#ifndef min +#define min(a, b) ((a > b) ? b : a) +#endif + +/* ************************************** */ + +/* Variables */ +/* extern TWOFISH *tf; */ +extern int traceLevel; +extern int useSyslog; +extern const uint8_t broadcast_addr[6]; +extern const uint8_t multicast_addr[6]; + +/* Functions */ +extern void traceEvent(int eventTraceLevel, char* file, int line, const char * format, ...); +extern int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, + char *device_mask, const char * device_mac, int mtu); +extern int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); +extern int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); +extern void tuntap_close(struct tuntap_dev *tuntap); +extern void tuntap_get_address(struct tuntap_dev *tuntap); + +extern SOCKET open_socket(int local_port, int bind_any); + +extern char* intoa(uint32_t addr, char* buf, uint16_t buf_len); +extern char* macaddr_str(macstr_t buf, const n2n_mac_t mac); +extern int str2mac( uint8_t * outmac /* 6 bytes */, const char * s ); +extern char * sock_to_cstr( n2n_sock_str_t out, + const n2n_sock_t * sock ); + +extern int sock_equal( const n2n_sock_t * a, + const n2n_sock_t * b ); + +extern uint8_t is_multi_broadcast(const uint8_t * dest_mac); +extern char* msg_type2str(uint16_t msg_type); +extern void hexdump(const uint8_t * buf, size_t len); + +void print_n2n_version(int trace); +const char* random_device_mac(void); + + +/* Operations on peer_info lists. */ +struct peer_info * find_peer_by_mac( peer_info_t ** list, + const n2n_mac_t mac ); +void peer_list_add( struct peer_info * * list, + struct peer_info * new ); +size_t peer_list_size( const struct peer_info * list ); +void dealloc_peer( peer_info_t* peer ); +size_t hashed_peer_list_t_size(peer_info_t** htab); +size_t purge_with_function(struct peer_info ** peer_list, size_t(*purger)(struct peer_info ** peer_list, time_t purge_before)); +size_t purge_peer_list( struct peer_info ** peer_list, + time_t purge_before ); +size_t purge_hashed_peer_list_t(peer_info_t ** peer_list, time_t purge_before); +size_t clear_peer_list( struct peer_info ** peer_list ); +size_t clear_hashed_peer_info_t_list(peer_info_t ** peer_list); +size_t purge_expired_registrations( struct peer_info ** peer_list ); +size_t hashed_purge_expired_registrations(struct peer_info ** peer_list); + +/* version.c */ +extern char *n2n_sw_version, *n2n_sw_osName, *n2n_sw_buildDate, *n2n_mod_version, *n2n_mod_author; + +#endif /* _N2N_H_ */ diff --git a/bundles/n2n_meyerd/n2n_v2/n2n.spec b/bundles/n2n_meyerd/n2n_v2/n2n.spec new file mode 100644 index 00000000..f5ee7d8a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n.spec @@ -0,0 +1,52 @@ +Summary: N2N peer-to-peer virtual private network system. +Name: n2n +Version: 2.1.0 +Release: 1 +License: GPLv3 +Vendor: ntop.org +Group: None +URL: http://www.ntop.org/n2n +Source0: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +%description +N2N is a peer-to-peer virtual private network system. N2N uses the universal +TUNTAP interface to create TAP network interfaces to an encrypted virtual +LAN. Members of a community share encryption keys which allow exchange of +data. The supernode is used for peer discovery and initial packet relay before +direct peer-to-peer exchange is established. Once direct packet exchange is +established, the supernode is not required. + +N2N-2 introduces additional security features and multiple supernodes. + +%prep + +%setup -q + +echo -e "\n *** Building ${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE} ***\n" + +%build +make + +%install +make PREFIX=${RPM_BUILD_ROOT}/usr install + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,-) + /usr/sbin/supernode + /usr/sbin/edge +%doc /usr/share/man/man1/supernode.1.gz +%doc /usr/share/man/man8/edge.8.gz +%doc /usr/share/man/man7/n2n_v2.7.gz + + +%changelog +* Fri Oct 30 2009 Richard Andrews - +- First beta for n2n-2 +* Sat May 3 2008 Richard Andrews - +- Initial build. + diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.c b/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.c new file mode 100644 index 00000000..56de3a19 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.c @@ -0,0 +1,203 @@ +/* (c) 2009 Richard Andrews */ +/* Contributions from: + * - Jozef Kralik + */ + +#include "n2n.h" +#include "n2n_keyfile.h" +#include +#include +#include +#include + + +#ifdef WIN32 +char *strsep( char **ppsz_string, const char *psz_delimiters ) +{ + char *p; + char *psz_string = *ppsz_string; + if( !psz_string ) + return NULL; + + p = strpbrk( psz_string, psz_delimiters ); + if( !p ) + { + *ppsz_string = NULL; + return psz_string; + } + *p++ = '\0'; + + *ppsz_string = p; + return psz_string; +} +#endif + + +/* Parse hex nibbles in ascii until a non-nibble character is found. Nibble + * characters are 0-9, a-f and A-F. + * + * Return number of bytes parsed into keyBuf or a negative error code. + */ +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyLen, + const char * textKey, + size_t textLen) +{ + ssize_t retval=0; + uint8_t * pout=keyBuf; + size_t octet=0; + const char * textEnd; + const char * pbeg; + + textEnd = textKey+textLen; + pbeg=textKey; + + while ( ( pbeg + 1 < textEnd ) && ( retval < (ssize_t)keyLen ) ) + { + if ( 1 != sscanf( pbeg, "%02x", (unsigned int*)&octet ) ) + { + retval=-1; + break; + } + + *pout = (octet & 0xff); + ++pout; + ++retval; + pbeg += 2; + } + + return retval; +} + + +static int parseKeyLine( n2n_cipherspec_t * spec, + const char * linein ) +{ + /* parameters are separated by whitespace */ + char line[N2N_KEYFILE_LINESIZE]; + char * lp=line; + const char * token; + strncpy( line, linein, N2N_KEYFILE_LINESIZE ); + + memset( spec, 0, sizeof( n2n_cipherspec_t ) ); + + /* decode valid_from time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_from = atol(token); + + /* decode valid_until time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_until = atol(token); + + /* decode the transform number */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->t = atoi(token); + + /* The reset if opaque key data */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + strncpy( (char *)spec->opaque, token, N2N_MAX_KEYSIZE ); + spec->opaque_size=strlen( (char *)spec->opaque); + + return 0; + +error: + return -1; +} + + +#define SEP "/" + + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ) +{ + if ( k->valid_until < k->valid_from ) { goto bad; } + if ( k->valid_from > now ) { goto bad; } + if ( k->valid_until < now ) { goto bad; } + + return 0; + +bad: + return -1; +} + +/* Read key control file and return the number of specs stored or a negative + * error code. + * + * As the specs are read in the from and until time values are compared to + * present time. Only those keys which are valid are stored. + */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ) /* path to control file */ +{ + /* Each line contains one cipherspec. */ + + int retval=0; + FILE * fp=NULL; + size_t idx=0; + time_t now = time(NULL); + + traceEvent( TRACE_DEBUG, "Reading '%s'\n", ctrlfile_path ); + + fp = fopen( ctrlfile_path, "r" ); + if ( fp ) + { + /* Read the file a line a time with fgets. */ + char line[N2N_KEYFILE_LINESIZE]; + size_t lineNum=0; + + while ( idx < numspecs ) + { + n2n_cipherspec_t * k = &(specs[idx]); + fgets( line, N2N_KEYFILE_LINESIZE, fp ); + ++lineNum; + + if ( strlen(line) > 1 ) + { + if ( 0 == parseKeyLine( k, line ) ) + { + if ( k->valid_until > now ) + { + traceEvent( TRACE_INFO, " --> [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + ++retval; + ++idx; + } + else + { + traceEvent( TRACE_INFO, " --X [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + } + } + else + { + traceEvent( TRACE_WARNING, "Failed to decode line %u\n", lineNum ); + } + } + + if ( feof(fp) ) + { + break; + } + + line[0]=0; /* this line has been consumed */ + } + + fclose( fp); + fp=NULL; + } + else + { + traceEvent( TRACE_ERROR, "Failed to open '%s'\n", ctrlfile_path ); + retval = -1; + } + + return retval; +} diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.h b/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.h new file mode 100644 index 00000000..6068df1e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_keyfile.h @@ -0,0 +1,101 @@ +/* (c) 2009 Richard Andrews */ + +/** Key files + * + * Edge implements a very simple interface for getting instructions about + * rolling keys. + * + * Key definitions are written as individual files in /.key. The + * format of each key is a single line of hex nibbles as follows: + * + * 0102030405060708090a0b0c0d0e0f + * + * Any external key exchange mechanism can receive the key data write it into + * the keyfiles. + * + * To control which keys are active at what times the key control file is + * used. This is a single file which is periodically reread. It contains key + * definitions in chronological order with one line per key definition as + * follows: + * + * + * + * edge reads the key control file periodically to get updates in policy. edge + * holds a number of keys in memory. Data can be decoded if it was encoded by + * any of the keys still in memory. By having at least 2 keys in memory it + * allows for clock skew and transmission delay when encoder and decoder roll + * keys at slightly different times. The amount of overlap in the valid time + * ranges provides the tolerance to timing skews in the system. + * + * The keys have the same level of secrecy as any other user file. Existing + * UNIX permission systems can be used to provide access controls. + * + */ + +/** How Edge Uses The Key Schedule + * + * Edge provides state space for a number of transform algorithms. Each + * transform uses its state space to store the SA information for its keys as + * found in the key file. When a packet is received the transform ID is in + * plain text. The packets is then sent to that transform for decoding. Each + * transform can store its SA numbers differently (or not at all). The + * transform code then finds the SA number, then finds the cipher (with key) in + * the state space and uses this to decode the packet. + * + * To support this, as edge reads each key line, it passes it to the + * appropriate transform to parse the line and store the SA information in its + * state space. + * + * When encoding a packet, edge has several transforms and potentially valid + * SAs to choose from. To keep track of which one to use for encoding edge does + * its own book-keeping as each key line is passed to the transform code: it + * stores a lookup of valid_from -> transform. When encoding a packet it then + * just calls the transform with the best valid_from in the table. The + * transform's own state space has all the SAs for its keys and the best of + * those is chosen. + */ + +#if !defined( N2N_KEYFILE_H_ ) +#define N2N_KEYFILE_H_ + + +#include "n2n_wire.h" +#include + +#define N2N_MAX_KEYSIZE 256 /* bytes */ +#define N2N_MAX_NUM_CIPHERSPECS 8 +#define N2N_KEYPATH_SIZE 256 +#define N2N_KEYFILE_LINESIZE 256 + +/** This structure stores an encryption cipher spec. */ +struct n2n_cipherspec +{ + n2n_transform_t t; /* N2N_TRANSFORM_ID_xxx for this spec. */ + time_t valid_from; /* Start using the key at this time. */ + time_t valid_until; /* Key is valid if time < valid_until. */ + uint16_t opaque_size; /* Size in bytes of key. */ + uint8_t opaque[N2N_MAX_KEYSIZE];/* Key matter. */ +}; + +typedef struct n2n_cipherspec n2n_cipherspec_t; + + +static const char * const DELIMITERS=" \t\n\r"; + + +/** @return number of cipherspec items filled. */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ); /* path to control file */ + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ); + +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyMax, + const char * textKey, + size_t textLen ); + +/*----------------------------------------------------------------------------*/ + +#endif /* #if !defined( N2N_KEYFILE_H_ ) */ diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_test.c b/bundles/n2n_meyerd/n2n_v2/n2n_test.c new file mode 100644 index 00000000..97ec91b0 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_test.c @@ -0,0 +1,24 @@ +#include "n2n.h" +#include "n2n_keyfile.h" +#include +#include +#include + +int main(int arc, const char * argv[] ) +{ + int e; + n2n_cipherspec_t specs[N2N_MAX_NUM_CIPHERSPECS]; + + e = n2n_read_keyfile( specs, N2N_MAX_NUM_CIPHERSPECS, "keyctrl.conf" ); + + if ( e < 0 ) + { + perror( "Failed to read keyfile" ); + } + else + { + fprintf( stderr, "Stored %d keys.\n", e ); + } + + return 0; +} diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_transforms.h b/bundles/n2n_meyerd/n2n_v2/n2n_transforms.h new file mode 100644 index 00000000..effbc50b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_transforms.h @@ -0,0 +1,78 @@ +/* (c) 2009 Richard Andrews */ + +#if !defined(N2N_TRANSFORMS_H_) +#define N2N_TRANSFORMS_H_ + +#include "n2n_keyfile.h" +#include "n2n_wire.h" + + +#define N2N_TRANSFORM_ID_INVAL 0 /* marks uninitialised data */ +#define N2N_TRANSFORM_ID_NULL 1 +#define N2N_TRANSFORM_ID_TWOFISH 2 +#define N2N_TRANSFORM_ID_AESCBC 3 +#define N2N_TRANSFORM_ID_LZO 4 +#define N2N_TRANSFORM_ID_TWOFISH_LZO 5 +#define N2N_TRANSFORM_ID_AESCBC_LZO 6 +#define N2N_TRANSFORM_ID_USER_START 64 +#define N2N_TRANSFORM_ID_MAX 65535 + + +struct n2n_trans_op; +typedef struct n2n_trans_op n2n_trans_op_t; + +struct n2n_tostat +{ + uint8_t can_tx; /* Does this transop have a valid SA for encoding. */ + n2n_cipherspec_t tx_spec; /* If can_tx, the spec used to encode. */ +}; + +typedef struct n2n_tostat n2n_tostat_t; + + +typedef int (*n2n_transdeinit_f)( n2n_trans_op_t * arg ); +typedef int (*n2n_transaddspec_f)( n2n_trans_op_t * arg, + const n2n_cipherspec_t * cspec ); +typedef n2n_tostat_t (*n2n_transtick_f)( n2n_trans_op_t * arg, + time_t now ); + +typedef int (*n2n_transform_f)( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ); + +/** Holds the info associated with a data transform plugin. + * + * When a packet arrives the transform ID is extracted. This defines the code + * to use to decode the packet content. The transform code then decodes the + * packet and consults its internal key lookup. + */ +struct n2n_trans_op +{ + void * priv; /* opaque data. Key schedule goes here. */ + + n2n_transform_t transform_id; /* link header enum to a transform */ + size_t tx_cnt; + size_t rx_cnt; + + n2n_transdeinit_f deinit; /* destructor function */ + n2n_transaddspec_f addspec; /* parse opaque data from a key schedule file. */ + n2n_transtick_f tick; /* periodic maintenance */ + n2n_transform_f fwd; /* encode a payload */ + n2n_transform_f rev; /* decode a payload */ +}; + +/* Setup a single twofish SA for single-key operation. */ +int transop_twofish_setup( n2n_trans_op_t * ttt, + n2n_sa_t sa_num, + uint8_t * encrypt_pwd, + uint32_t encrypt_pwd_len ); + +/* Initialise an empty transop ready to receive cipherspec elements. */ +int transop_twofish_init( n2n_trans_op_t * ttt ); +int transop_aes_init( n2n_trans_op_t * ttt ); +void transop_null_init( n2n_trans_op_t * ttt ); + +#endif /* #if !defined(N2N_TRANSFORMS_H_) */ + diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_v2.7 b/bundles/n2n_meyerd/n2n_v2/n2n_v2.7 new file mode 100644 index 00000000..092f2d3a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_v2.7 @@ -0,0 +1,156 @@ +.TH "n2n_v2" 7 "Sep 21, 2009" "revision 3909" "Background" +.SH NAME +N2n Version 2 \- version 2 of the n2n decentralised peer-to-peer network overlay +VPN. +.SH DESCRIPTION +N2n is a peer-to-peer network overlay or VPN system that provides layer 2 over +layer 3 encapsulation with data transform capabilities such as encryption and +compression. This guide discusses the differences of version 2 or n2n from +version 1. +.SH PROTOCOLS +N2n-2 uses a different set of messages to communicate with edges and +supernodes. The n2n-2 messages are not compatible with n2n-1. There is no +backward compatibility for n2n-1. +.SH ENCRYPTION +N2n-2 offers a new way of handling encryption compared to n2n-1. N2n-1 provided +facility for a single community password with no expiration. In n2n-2 this +method is preserved but a new mechanism has been added using a key schedule +file. +.TP +Key Schedule +A key schedule file lists a number of keys with the period for which each is +valid along with the encryption type identifier and the actual key value. This +allows the user to define up to 32 keys in advance with a pre-set time at which +they keys will change. The key schedule file can be reloaded while the edge is +running to allow new keys to be loaded and unused keys expunged. +.TP +Timing Requirements When a key rolls over to the next in the schedule, the new +key is used for all transmitted packets; however any packets received using an +older key can still be decoded as the keys from the key schedule are still +known. As a result edges do not need to have accurate time synchronisation. The +accuracy of required synchronisation depends to a large degree on the key +schedule. Rapid key roll-overs requires more accurate time synchronisation. +.P +N2n-2 provides the following encryption ciphers; more can be added as required: +.TP +.B (1) NULL +Data is encapsulated unchanged. Useful for testing and high-performance, low +sensitivity applications. +.TP +.B (2) TF +Twofish AES candidate. +.P +The following additional ciphers are specified but not yet implemented: +.TP +.B (3) AES-CBC +AES in CBC mode with 256-bit key. +.TP +.B (4) LZO +LZO compression of data (no encryption). +.TP +.B (5) TF-LZO +TF cipher with LZO compression of data prior to encryption. +.TP +.B (6) AES-CBC-LZO +AES-CBC ciper with LZO compression of data prior to encryption. + +.SH EXTENSIBILITY +N2n-2 decouples the data transform system from the core of the edge +operation. This allows for easier addition of new data transform +operations. N2n-2 reserves 64 standard transform identifiers (such as TwoFish +encryption) but allocates transform identifiers 64 - 65536 for user-defined +transforms. This allows anyone to add to n2n new private transforms without +breaking compatibility with the standard offering. + +.SH MULTIPLE SUPERNODES +N2n-2 introduces the capability of multiple supernodes to be used by an +edge. N2n-2 offers supernode in several flavours: +.TP +Stand-alone supernode + +This is the same concept as from n2n-1. Supernode is a small efficient C program +which operates in isolation. +.TP +Federated supernodes + +This is a cluster of supernodes which share information. Edges registered to any +of the cooperating supernodes can relay packets through the supernode federation +and switch supernodes if required. Supernodes can send PACKET or REGISTER +messages to other supernodes to try and find the destination edge. + +.P +The n2n-2 edge implementation allows multiple supernodes to be specified on the +command line. Edges monitor the current supernode for responses to +REGISTER_SUPER messages. If 3 responses are missed then the edge starts looking +for a new supernode. It cycles through the list of supernodes specified until it +finds a working one. + +.SH EFFICIENCY +The n2n-2 message formats have been made more efficient. The amount of data +overhead has been reduced by ensuring the messages contain only the data fields +required. Some optional fields do not consume data if they are not present. + +.SH DAEMON OPERATION +The supernode and edge use daemon mode of operation by default. This sense is +inverted from n2n-1 where they ran in the foreground by default. They can be +made to run in the foreground so tools such a DJB's daemontools can work with +them. See the +.B -f +option + +.SH MANAGEMENT CONSOLE +Edge and supernode in n2n-2 provide a UDP-based management console. Both listen +on the localhost address 127.0.0.1. Commands can be sent to the programs by +sending to the UDP socket. Responses are returned to the socket from which +commands were issued. This only works from the computer on which the programs +are running. Statistics can be retrieved and commands issued. The netcat utility +is all that is required; but more sophisticated tools could be built on the +interface. + +.SH SUPERNODE AUTHENTICATION +.B (To be implemented) +Space has been reserved in the supernode registration messages for an +authentication mechanism. + +.SH MESSAGE SUMMARY +The following message types work within n2n-2. +.TP +REGISTER_SUPER +Sent from an edge to its local supernode to register its MAC with the community. +.TP +REGISTER_SUPER_ACK +Sent from a supernode to an edge to confirm registration. This also carries the +definition of the edge socket as seen at the supernode so NAT can be detected +and described. +.TP +REGISTER_SUPER_NAK +Supernode refusing to register an edge. +.TP +PACKET +Encapsulated ethernet packets sent between edges. Supernodes forward or +broadcast these and edges send them direct in peer-to-peer mode. +.TP +REGISTER +A peer-to-peer mode registration request from one edge to another. Supernodes +forward these to facilitate NAT crossing introductions. +.TP +REGISTER_ACK +Complete peer-to-peer mode setup between two edges. These messages need to +travel direct between edges. +.TP +FEDERATION +Federated supernodes exchanging community information. + +.SH OTHER DIFFERENCES +.TP +HTTP Tunneling +This experimental feature (-t option in n2n_v1) of n2n_v1 has been removed +entirely from n2n_v2. +.SH AUTHORS +.TP +Richard Andrews andrews (at) ntop.org - main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - code inherited from n2n-1 +.SH SEE ALSO +ifconfig(8) edge(8) supernode(1) diff --git a/bundles/n2n_meyerd/n2n_v2/n2n_wire.h b/bundles/n2n_meyerd/n2n_v2/n2n_wire.h new file mode 100644 index 00000000..4e9c023c --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/n2n_wire.h @@ -0,0 +1,380 @@ +/* (c) 2009 Richard Andrews + * + * Contributions by: + * Luca Deri + * Lukasz Taczuk + */ + +#if !defined( N2N_WIRE_H_ ) +#define N2N_WIRE_H_ + +#include + +#if defined(WIN32) +#include "win32/n2n_win32.h" + +#if defined(__MINGW32__) +#include +#endif /* #ifdef __MINGW32__ */ + +#else /* #if defined(WIN32) */ +#include +#include +#include /* AF_INET and AF_INET6 */ +#endif /* #if defined(WIN32) */ + +#define N2N_PKT_VERSION 2 +#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */ +#define N2N_COMMUNITY_SIZE 16 +#define N2N_MAC_SIZE 6 +#define N2N_COOKIE_SIZE 4 +#define N2N_PKT_BUF_SIZE 2048 +#define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ + +typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; +typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; +typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE]; + +typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ + +enum n2n_pc +{ + n2n_ping=0, /* Not used */ + n2n_register=1, /* Register edge to edge */ + n2n_deregister=2, /* Deregister this edge */ + n2n_packet=3, /* PACKET data content */ + n2n_register_ack=4, /* ACK of a registration from edge to edge */ + n2n_register_super=5, /* Register edge to supernode */ + n2n_register_super_ack=6, /* ACK from supernode to edge */ + n2n_register_super_nak=7, /* NAK from supernode to edge - registration refused */ + n2n_federation=8, /* Not used by edge */ + n2n_peer_info=9, /* Send info on a peer from sn to edge */ + n2n_query_peer=10 /* ask supernode for info on a peer */ +}; + +typedef enum n2n_pc n2n_pc_t; + +/* for the additional_flags present in some non-PACKET types */ +#define N2N_AFLAGS_LOCAL_SOCKET 0x0001 + +/* for the common header section */ +#define N2N_FLAGS_FROM_SUPERNODE 0x0020 + +/* The bits in flag that are the packet type */ +#define N2N_FLAGS_TYPE_MASK 0x001f /* 0 - 31 */ +#define N2N_FLAGS_BITS_MASK 0xffe0 + +#define IPV4_SIZE 4 +#define IPV6_SIZE 16 + +#define ETH_FRAMEHDRSIZE 14 +#define IP4_SRCOFFSET 12 + +#define N2N_AUTH_TOKEN_SIZE 32 /* bytes */ + + +#define N2N_EUNKNOWN -1 +#define N2N_ENOTIMPL -2 +#define N2N_EINVAL -3 +#define N2N_ENOSPACE -4 + + +typedef uint16_t n2n_flags_t; +typedef uint16_t n2n_transform_t; /* Encryption, compression type. */ +typedef uint32_t n2n_sa_t; /* security association number */ + +struct n2n_sock +{ + uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ + uint16_t port; /* host order */ + union + { + uint8_t v6[IPV6_SIZE]; /* byte sequence */ + uint8_t v4[IPV4_SIZE]; /* byte sequence */ + } addr; +}; + +typedef struct n2n_sock n2n_sock_t; + +struct n2n_auth +{ + uint16_t scheme; /* What kind of auth */ + uint16_t toksize; /* Size of auth token */ + uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */ +}; + +typedef struct n2n_auth n2n_auth_t; + + +struct n2n_common +{ + /* int version; */ + uint8_t ttl; + n2n_pc_t pc; + n2n_flags_t flags; + n2n_community_t community; +}; + +typedef struct n2n_common n2n_common_t; + +struct n2n_REGISTER +{ + n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */ + n2n_mac_t srcMac; /* MAC of registering party */ + n2n_mac_t dstMac; /* MAC of target edge */ + n2n_sock_t sock; /* when relaying by supernode */ +}; + +typedef struct n2n_REGISTER n2n_REGISTER_t; + +struct n2n_REGISTER_ACK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER */ + n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */ + n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */ + n2n_sock_t sock; /* Supernode's view of edge socket (IP Addr, port) */ +}; + +typedef struct n2n_REGISTER_ACK n2n_REGISTER_ACK_t; + +struct n2n_PACKET +{ + n2n_transform_t transform; +}; + +typedef struct n2n_PACKET n2n_PACKET_t; + +struct n2n_ETHFRAMEHDR +{ + n2n_mac_t srcMac; + n2n_mac_t dstMac; + /* uint16_t ethertype; */ /* is there a reason to use this? */ +}; + +typedef struct n2n_ETHFRAMEHDR n2n_ETHFRAMEHDR_t; + + +/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */ +struct n2n_REGISTER_SUPER +{ + uint16_t aflags; /* additional flags */ + n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */ + uint16_t timeout; + n2n_mac_t edgeMac; /* MAC to register with edge sending socket */ + n2n_auth_t auth; /* Authentication scheme and tokens */ + n2n_sock_t local_sock; +}; + +typedef struct n2n_REGISTER_SUPER n2n_REGISTER_SUPER_t; + + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +struct n2n_REGISTER_SUPER_ACK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ + n2n_mac_t edgeMac; /* MAC registered to edge sending socket */ + uint16_t lifetime; /* How long the registration will live */ + n2n_sock_t sock; /* Sending sockets associated with edgeMac */ + + /* The packet format provides additional supernode definitions here. + * uint8_t count, then for each count there is one + * n2n_sock_t. + */ + uint8_t num_sn; /* Number of supernodes that were send + * even if we cannot store them all. If + * non-zero then sn_bak is valid. */ + n2n_sock_t sn_bak; /* Socket of the first backup supernode */ + +}; + +typedef struct n2n_REGISTER_SUPER_ACK n2n_REGISTER_SUPER_ACK_t; + + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +struct n2n_REGISTER_SUPER_NAK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ +}; + +typedef struct n2n_REGISTER_SUPER_NAK n2n_REGISTER_SUPER_NAK_t; + +struct n2n_PEER_INFO +{ + uint16_t aflags; + uint16_t timeout; + n2n_mac_t mac; + n2n_sock_t sockets[2]; +}; + +typedef struct n2n_PEER_INFO n2n_PEER_INFO_t; + +struct n2n_QUERY_PEER +{ + n2n_mac_t srcMac; + n2n_mac_t targetMac; +}; + +typedef struct n2n_QUERY_PEER n2n_QUERY_PEER_t; + +struct n2n_buf +{ + uint8_t * data; + size_t size; +}; + +typedef struct n2n_buf n2n_buf_t; + +int encode_uint8( uint8_t * base, + size_t * idx, + const uint8_t v ); + +int decode_uint8( uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_uint16( uint8_t * base, + size_t * idx, + const uint16_t v ); + +int decode_uint16( uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_uint32( uint8_t * base, + size_t * idx, + const uint32_t v ); + +int decode_uint32( uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_buf( uint8_t * base, + size_t * idx, + const void * p, + size_t s); + +int decode_buf( uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_mac( uint8_t * base, + size_t * idx, + const n2n_mac_t m ); + +int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passing a n2n_mac_t */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_common( uint8_t * base, + size_t * idx, + const n2n_common_t * common ); + +int decode_common( n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_sock( uint8_t * base, + size_t * idx, + const n2n_sock_t * sock ); + +int decode_sock( n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_t * reg ); + +int decode_REGISTER( n2n_REGISTER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_SUPER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_t * reg ); + +int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_ACK_t * reg ); + +int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_SUPER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * cmn, + const n2n_REGISTER_SUPER_ACK_t * reg ); + +int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int fill_sockaddr( struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock ); + +int encode_PACKET( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt ); + +int decode_PACKET( n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_PEER_INFO( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PEER_INFO_t * pi ); + +int decode_PEER_INFO( n2n_PEER_INFO_t * pi, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_QUERY_PEER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * qp ); + +int decode_QUERY_PEER( n2n_QUERY_PEER_t * qp, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +void decode_ETHFRAMEHDR( n2n_ETHFRAMEHDR_t * eth, + const uint8_t * base ); + +int copy_ETHFRAMEHDR( uint8_t * base, + uint8_t * pkt); + + +#endif /* #if !defined( N2N_WIRE_H_ ) */ diff --git a/bundles/n2n_meyerd/n2n_v2/scm.h b/bundles/n2n_meyerd/n2n_v2/scm.h new file mode 100644 index 00000000..38cf0491 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/scm.h @@ -0,0 +1,24 @@ +/* + * + * + * + */ + +struct SCM_def { + char *name; + char *desc; + int mode; /* set to SVC_CONSOLE by the *-scm.c code */ + int argc; char **argv; /* original cmdline args */ + int (*init)(int, char **); /* called before main */ + int (*main)(int, char **); /* called to run the service */ + int (*stop)(void *); /* called by scm to tell the service to stop */ +}; + +int SCM_Start(struct SCM_def *, int argc, char **argv); +char *SCM_Install(struct SCM_def *,char *); +int SCM_Remove(struct SCM_def *); + +#define SVC_OK 0 +#define SVC_FAIL -1 +#define SVC_CONSOLE 1 + diff --git a/bundles/n2n_meyerd/n2n_v2/scripts/mk_SRPM.sh b/bundles/n2n_meyerd/n2n_v2/scripts/mk_SRPM.sh new file mode 100644 index 00000000..2b1b3743 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/scripts/mk_SRPM.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +set -x + +BASE=`pwd` + +TARFILE=`${BASE}/scripts/mk_tar.sh` + +test -f ${TARFILE} + +echo "Building SRPM" +# -ts means build source RPM from tarfile +rpmbuild -ts ${TARFILE} + +echo "Done" diff --git a/bundles/n2n_meyerd/n2n_v2/scripts/mk_deb.sh b/bundles/n2n_meyerd/n2n_v2/scripts/mk_deb.sh new file mode 100644 index 00000000..42d86916 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/scripts/mk_deb.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +set -x + +BASE=`pwd` + +TARFILE=`${BASE}/scripts/mk_tar.sh` +TEMPDIR="build_deb" + +test -f ${TARFILE} + +echo "Building .deb" + +if [ -d ${TEMPDIR} ]; then + echo "Removing ${TEMPDIR} directory" + rm -rf ${TEMPDIR} >&2 +fi + +mkdir ${TEMPDIR} + +pushd ${TEMPDIR} + +tar xzf ${TARFILE} #At original location + +cd n2n* + +dpkg-buildpackage -rfakeroot + +popd + +echo "Done" diff --git a/bundles/n2n_meyerd/n2n_v2/scripts/mk_tar.sh b/bundles/n2n_meyerd/n2n_v2/scripts/mk_tar.sh new file mode 100644 index 00000000..0e84331c --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/scripts/mk_tar.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +# This script makes a SRPM - a source RPM file which can be built into the +# appropriate distro specific RPM for any platform. +# +# To build the binary package: +# rpm -i n2n-.src.rpm +# rpmbuild -bb n2n.spec +# +# Look for the "Wrote:" line to see where the final RPM is. +# +# To run this script cd to the n2n directory and run it as follows +# scripts/mk_SRPMS.sh +# + +set -e + +function exit_fail() +{ + echo "$1" + exit 1 +} + +PACKAGE="n2n" +PKG_VERSION="2.1.0" +PKG_AND_VERSION="${PACKAGE}-${PKG_VERSION}" + +TEMPDIR="tmp" + +SOURCE_MANIFEST=" +README +edge.c +lzoconf.h +lzodefs.h +Makefile +minilzo.c +minilzo.h +n2n.c +n2n.h +n2n_keyfile.c +n2n_keyfile.h +n2n.spec +n2n_transforms.h +n2n_wire.h +sn.c +transform_aes.c +transform_null.c +transform_tf.c +tuntap_linux.c +tuntap_freebsd.c +tuntap_netbsd.c +tuntap_osx.c +twofish.c +twofish.h +version.c +wire.c +edge.8 +supernode.1 +n2n_v2.7 +debian/changelog +debian/compat +debian/control +debian/copyright +debian/n2n-edge.docs +debian/n2n-edge.install +debian/n2n-supernode.install +debian/n2n-edge.manpages +debian/n2n-supernode.manpages +debian/README.Debian +debian/rules +" + +BASE=`pwd` + +for F in ${SOURCE_MANIFEST}; do + test -e $F || exit_fail "Cannot find $F. Maybe you're in the wrong directory. Please execute from n2n directory."; >&2 +done + +echo "Found critical files. Proceeding." >&2 + +if [ -d ${TEMPDIR} ]; then + echo "Removing ${TEMPDIR} directory" + rm -rf ${TEMPDIR} >&2 +fi + +mkdir ${TEMPDIR} >&2 + +pushd ${TEMPDIR} >&2 + +echo "Creating staging directory ${PWD}/${PKG_AND_VERSION}" >&2 + +if [ -d ${PKG_AND_VERSION} ] ; then + echo "Removing ${PKG_AND_VERSION} directory" + rm -rf ${PKG_AND_VERSION} >&2 +fi + +mkdir ${PKG_AND_VERSION} + +pushd ${BASE} >&2 + +echo "Copying in files" >&2 +for F in ${SOURCE_MANIFEST}; do + cp --parents -a $F ${TEMPDIR}/${PKG_AND_VERSION}/ +done + +popd >&2 + +TARFILE="${PKG_AND_VERSION}.tar.gz" +echo "Creating ${TARFILE}" >&2 +tar czf ${BASE}/${TARFILE} ${PKG_AND_VERSION} + +popd >&2 + +rm -rf ${TEMPDIR} >&2 + +echo ${BASE}/${TARFILE} diff --git a/bundles/n2n_meyerd/n2n_v2/sglib.h b/bundles/n2n_meyerd/n2n_v2/sglib.h new file mode 100644 index 00000000..76304380 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/sglib.h @@ -0,0 +1,1951 @@ +/* + + This is SGLIB version 1.0.3 + + (C) by Marian Vittek, Bratislava, http://www.xref-tech.com/sglib, 2003-5 + + License Conditions: You can use a verbatim copy (including this + copyright notice) of sglib freely in any project, commercial or not. + You can also use derivative forms freely under terms of Open Source + Software license or under terms of GNU Public License. If you need + to use a derivative form in a commercial project, or you need sglib + under any other license conditions, contact the author. + + + +*/ + + +#ifndef _SGLIB__h_ +#define _SGLIB__h_ + +/* the assert is used exclusively to write unexpected error messages */ +#include + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 0 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* + + Basic algorithms for sorting arrays. Multiple depending arrays can + be rearranged using user defined 'elem_exchangers' + +*/ + +/* HEAP - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_HEAP_SORT(type, a, max, comparator, elem_exchanger) {\ + int _k_;\ + for(_k_=(max)/2; _k_>=0; _k_--) {\ + SGLIB___ARRAY_HEAP_DOWN(type, a, _k_, max, comparator, elem_exchanger);\ + }\ + for(_k_=(max)-1; _k_>=0; _k_--) {\ + elem_exchanger(type, a, 0, _k_);\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, _k_, comparator, elem_exchanger);\ + }\ +} + +#define SGLIB___ARRAY_HEAP_DOWN(type, a, ind, max, comparator, elem_exchanger) {\ + type _t_;\ + int _m_, _l_, _r_, _i_;\ + _i_ = (ind);\ + _m_ = _i_;\ + do {\ + _i_ = _m_; \ + _l_ = 2*_i_+1;\ + _r_ = _l_+1;\ + if (_l_ < (max)){\ + if (comparator(((a)[_m_]), ((a)[_l_])) < 0) _m_ = _l_;\ + if (_r_ < (max)) {\ + if (comparator(((a)[_m_]), ((a)[_r_])) < 0) _m_ = _r_;\ + }\ + }\ + if (_m_ != _i_) {\ + elem_exchanger(type, a, _i_, _m_);\ + }\ + } while (_m_ != _i_);\ +} + + +/* QUICK - SORT (level 0) */ + +#define SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator) {\ + SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + +#define SGLIB_ARRAY_QUICK_SORT(type, a, max, comparator, elem_exchanger) {\ + int _i_, _j_, _p_, _stacki_, _start_, _end_;\ + /* can sort up to 2^64 elements */\ + int _startStack_[64]; \ + int _endStack_[64];\ + type _tmp_;\ + _startStack_[0] = 0;\ + _endStack_[0] = (max);\ + _stacki_ = 1;\ + while (_stacki_ > 0) {\ + _stacki_ --;\ + _start_ = _startStack_[_stacki_];\ + _end_ = _endStack_[_stacki_];\ + while (_end_ - _start_ > 2) {\ + _p_ = _start_;\ + _i_ = _start_ + 1;\ + _j_ = _end_ - 1;\ + while (_i_<_j_) {\ + for(; _i_<=_j_ && comparator(((a)[_i_]),((a)[_p_]))<=0; _i_++) ;\ + if (_i_ > _j_) {\ + /* all remaining elements lesseq than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else {\ + for(; _i_<=_j_ && comparator(((a)[_j_]),((a)[_p_]))>=0; _j_--) ;\ + if (_i_ > _j_) {\ + /* all remaining elements greater than pivot */\ + elem_exchanger(type, a, _j_, _p_);\ + _i_ = _j_;\ + } else if (_i_ < _j_) {\ + elem_exchanger(type, a, _i_, _j_);\ + if (_i_+2 < _j_) {_i_++; _j_--;}\ + else if (_i_+1 < _j_) _i_++;\ + }\ + }\ + }\ + /* O.K. i==j and pivot is on a[i] == a[j] */\ + /* handle recursive calls without recursion */\ + if (_i_-_start_ > 1 && _end_-_j_ > 1) {\ + /* two recursive calls, use array-stack */\ + if (_i_-_start_ < _end_-_j_-1) {\ + _startStack_[_stacki_] = _j_+1;\ + _endStack_[_stacki_] = _end_;\ + _stacki_ ++;\ + _end_ = _i_;\ + } else {\ + _startStack_[_stacki_] = _start_;\ + _endStack_[_stacki_] = _i_;\ + _stacki_ ++;\ + _start_ = _j_+1;\ + }\ + } else {\ + if (_i_-_start_ > 1) {\ + _end_ = _i_;\ + } else {\ + _start_ = _j_+1;\ + }\ + }\ + }\ + if (_end_ - _start_ == 2) {\ + if (comparator(((a)[_start_]),((a)[_end_-1])) > 0) {\ + elem_exchanger(type, a, _start_, _end_-1);\ + }\ + }\ + }\ +} + +/* BINARY SEARCH (level 0) */ + +#define SGLIB_ARRAY_BINARY_SEARCH(type, a, start_index, end_index, key, comparator, found, result_index) {\ + int _kk_, _cc_, _ii_, _jj_, _ff_;\ + _ii_ = (start_index); \ + _jj_ = (end_index);\ + _ff_ = 0;\ + while (_ii_ <= _jj_ && _ff_==0) {\ + _kk_ = (_jj_+_ii_)/2;\ + _cc_ = comparator(((a)[_kk_]), (key));\ + if (_cc_ == 0) {\ + (result_index) = _kk_; \ + _ff_ = 1;\ + } else if (_cc_ < 0) {\ + _ii_ = _kk_+1;\ + } else {\ + _jj_ = _kk_-1;\ + }\ + }\ + if (_ff_ == 0) {\ + /* not found, but set its resulting place in the array */\ + (result_index) = _jj_+1;\ + }\ + (found) = _ff_;\ +} + +/* -------------------------------- queue (in an array) ------------------ */ +/* queue is a quadruple (a,i,j,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first used element in the array */ +/* j is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_QUEUE_INIT(type, a, i, j) { i = j = 0; } +#define SGLIB_QUEUE_IS_EMPTY(type, a, i, j) ((i)==(j)) +#define SGLIB_QUEUE_IS_FULL(type, a, i, j, dim) ((i)==((j)+1)%(dim)) +#define SGLIB_QUEUE_FIRST_ELEMENT(type, a, i, j) (a[i]) +#define SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_FULL(type, a, i, j, dim)) assert(0 && "the queue is full");\ + (j) = ((j)+1) % (dim);\ +} +#define SGLIB_QUEUE_ADD(type, a, elem, i, j, dim) {\ + a[j] = (elem);\ + SGLIB_QUEUE_ADD_NEXT(type, a, i, j, dim);\ +} +#define SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim) {\ + if (SGLIB_QUEUE_IS_EMPTY(type, a, i, j)) assert(0 && "the queue is empty");\ + (i) = ((i)+1) % (dim);\ +} +#define SGLIB_QUEUE_DELETE(type, a, i, j, dim) {\ + SGLIB_QUEUE_DELETE_FIRST(type, a, i, j, dim);\ +} + +/* ----------------- priority queue (heap) (in an array) -------------------- */ +/* heap is a triple (a,i,dim) such that: */ +/* a is the array storing values */ +/* i is the index of the first free element in the array */ +/* dim is the size of the array a */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + +#define SGLIB_HEAP_INIT(type, a, i) { i = 0; } +#define SGLIB_HEAP_IS_EMPTY(type, a, i) ((i)==0) +#define SGLIB_HEAP_IS_FULL(type, a, i, dim) ((i)==(dim)) +#define SGLIB_HEAP_FIRST_ELEMENT(type, a, i) (a[0]) +#define SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, elem_exchanger) {\ + int _i_;\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + _i_ = (i)++;\ + while (_i_ > 0 && comparator(a[_i_/2], a[_i_]) < 0) {\ + elem_exchanger(type, a, (_i_/2), _i_);\ + _i_ = _i_/2;\ + }\ +} +#define SGLIB_HEAP_ADD(type, a, elem, i, dim, comparator) {\ + if (SGLIB_HEAP_IS_FULL(type, a, i, dim)) assert(0 && "the heap is full");\ + a[i] = (elem);\ + SGLIB_HEAP_ADD_NEXT(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} +#define SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, elem_exchanger) {\ + if (SGLIB_HEAP_IS_EMPTY(type, a, i)) assert(0 && "the heap is empty");\ + (i)--;\ + a[0] = a[i];\ + SGLIB___ARRAY_HEAP_DOWN(type, a, 0, i, comparator, elem_exchanger);\ +} +#define SGLIB_HEAP_DELETE(type, a, i, dim, comparator) {\ + SGLIB_HEAP_DELETE_FIRST(type, a, i, dim, comparator, SGLIB_ARRAY_ELEMENTS_EXCHANGER);\ +} + + +/* ----------------- hashed table of pointers (in an array) -------------------- */ + +/* + + This hashed table is storing pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + In case of collision while adding an object the index shifted + by SGLIB_HASH_TAB_SHIFT_CONSTANT (constant can be redefined) + + You can NOT delete an element from such hash table. The only + justification (I can see) for this data structure is an exchange + file format, having an index table at the beginning and then + refering objects via indexes. + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! + +*/ + +#define SGLIB_HASH_TAB_INIT(type, table, dim) {\ + int _i_;\ + for(_i_ = 0; _i_ < (dim); _i_++) (table)[_i_] = NULL;\ +} + +#define SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, member){\ + unsigned _pos_;\ + type *_elem_;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, _pos_, _elem_);\ + (member) = (table)[_pos_];\ + if (_elem_ == NULL) {\ + if ((table)[_pos_] != NULL) assert(0 && "the hash table is full");\ + (table)[_pos_] = (elem);\ + }\ +} + +#define SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, resultIndex, resultMember) {\ + unsigned _i_;\ + int _count_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && comparator(_e_, (elem))!=0 && _count_<(dim)) {\ + _count_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + (resultIndex) = _i_;\ + if (_count_ < (dim)) (resultMember) = _e_;\ + else (resultMember) = NULL;\ +} + +#define SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, resultIndex) {\ + unsigned _i_;\ + int _c_;\ + type *_e_;\ + _count = 0;\ + _i_ = hash_function(elem);\ + _i_ %= (dim);\ + while ((_e_=(table)[_i_])!=NULL && _e_!=(elem) && _c_<(dim)) {\ + _c_ ++;\ + _i_ = (_i_ + SGLIB_HASH_TAB_SHIFT_CONSTANT) % (dim);\ + }\ + if (_e_==(elem)) (resultIndex) = _i_;\ + else (resultIndex) = -1;\ +} + +#define SGLIB_HASH_TAB_MAP_ON_ELEMENTS(type, table, dim, iteratedIndex, iteratedVariable, command) {\ + unsigned iteratedIndex;\ + type *iteratedVariable;\ + for(iteratedIndex=0; iteratedIndex < (dim); iteratedIndex++) {\ + iteratedVariable = (table)[iteratedIndex];\ + if (iteratedVariable != NULL) {command;}\ + }\ +} + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ------------------------------------ lists (level 0) --------------------- */ + +#define SGLIB_LIST_ADD(type, list, elem, next) {\ + (elem)->next = (list);\ + (list) = (elem);\ +} + +#define SGLIB_LIST_CONCAT(type, first, second, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else {\ + type *_p_;\ + for(_p_ = (first); _p_->next!=NULL; _p_=_p_->next) ;\ + _p_->next = (second);\ + }\ +} + +#define SGLIB_LIST_DELETE(type, list, elem, next) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && *_p_!=(elem); _p_= &(*_p_)->next) ;\ + assert(*_p_!=NULL && "element is not member of the container, use DELETE_IF_MEMBER instead"!=NULL);\ + *_p_ = (*_p_)->next;\ +} + +#define SGLIB_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ + if (_p_ == NULL) {\ + SGLIB_LIST_ADD(type, list, elem, next);\ + }\ +} + +#define SGLIB_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_p_;\ + for(_p_ = &(list); *_p_!=NULL && comparator((*_p_), (elem)) != 0; _p_= &(*_p_)->next) ;\ + (member) = *_p_;\ + if (*_p_ != NULL) {\ + *_p_ = (*_p_)->next;\ + }\ +} + +#define SGLIB_LIST_IS_MEMBER(type, list, elem, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && _p_ != (elem); _p_= _p_->next) ;\ + (result) = (_p_!=NULL);\ +} + +#define SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) != 0; _p_= _p_->next) ;\ + (member) = _p_;\ +} + +#define SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + type *_ne_;\ + type *iteratedVariable;\ + (iteratedVariable) = (list); \ + while ((iteratedVariable)!=NULL) {\ + _ne_ = (iteratedVariable)->next;\ + {command;};\ + (iteratedVariable) = _ne_;\ + }\ +} + +#define SGLIB_LIST_LEN(type, list, next, result) {\ + (result) = 0;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, _ce_, next, (result)++);\ +} + +#define SGLIB_LIST_REVERSE(type, list, next) {\ + type *_list_,*_tmp_,*_res_;\ + _list_ = (list);\ + _res_ = NULL;\ + while (_list_!=NULL) {\ + _tmp_ = _list_->next; _list_->next = _res_;\ + _res_ = _list_; _list_ = _tmp_;\ + }\ + (list) = _res_;\ +} + +#define SGLIB_LIST_SORT(type, list, comparator, next) {\ + /* a non-recursive merge sort on lists */\ + type *_r_;\ + type *_a_, *_b_, *_todo_, *_t_, **_restail_;\ + int _i_, _n_, _contFlag_;\ + _r_ = (list);\ + _contFlag_ = 1;\ + for(_n_ = 1; _contFlag_; _n_ = _n_+_n_) {\ + _todo_ = _r_; _r_ = NULL; _restail_ = &_r_; _contFlag_ =0;\ + while (_todo_!=NULL) {\ + _a_ = _todo_;\ + for(_i_ = 1, _t_ = _a_; _i_ < _n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + *_restail_ = _a_;\ + break;\ + }\ + _b_ = _t_->next; _t_->next=NULL;\ + for(_i_ =1, _t_ = _b_; _i_<_n_ && _t_!=NULL; _i_++, _t_ = _t_->next) ;\ + if (_t_ ==NULL) {\ + _todo_ =NULL;\ + } else {\ + _todo_ = _t_->next; _t_->next=NULL;\ + }\ + /* merge */\ + while (_a_!=NULL && _b_!=NULL) {\ + if (comparator(_a_, _b_) < 0) {\ + *_restail_ = _a_; _restail_ = &(_a_->next); _a_ = _a_->next;\ + } else {\ + *_restail_ = _b_; _restail_ = &(_b_->next); _b_ = _b_->next;\ + }\ + }\ + if (_a_!=NULL) *_restail_ = _a_;\ + else *_restail_ = _b_;\ + while (*_restail_!=NULL) _restail_ = &((*_restail_)->next);\ + _contFlag_ =1;\ + }\ + }\ + (list) = _r_;\ +} + +/* --------------------------------- sorted list (level 0) --------------------- */ +/* + All operations suppose that the list is sorted and they preserve + this property. +*/ + + +#define SGLIB_SORTED_LIST_ADD(type, list, elem, comparator, next) {\ + type **_e_;\ + int _cmpres_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmpres_, _e_);\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ +} + +#define SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ != 0) {\ + (elem)->next = *_e_;\ + *_e_ = (elem);\ + (member) = NULL;\ + } else {\ + (member) = *_e_;\ + }\ +} + +#define SGLIB_SORTED_LIST_DELETE(type, list, elem, next) {\ + SGLIB_LIST_DELETE(type, list, elem, next);\ +} + +#define SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, next, member) {\ + type **_e_;\ + int _cmp_res_;\ + SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, _cmp_res_, _e_);\ + if (_cmp_res_ == 0) {\ + (member) = *_e_;\ + *_e_ = (*_e_)->next;\ + } else {\ + (member) = NULL;\ + }\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, member) {\ + type *_p_;\ + int _cmpres_ = 1;\ + for(_p_ = (list); _p_!=NULL && (_cmpres_=comparator(_p_, (elem))) < 0; _p_=_p_->next) ;\ + if (_cmpres_ != 0) (member) = NULL;\ + else (member) = _p_;\ +} + +#define SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result) {\ + type *_p_;\ + for(_p_ = (list); _p_!=NULL && comparator(_p_, (elem)) < 0; _p_=_p_->next) ;\ + while (_p_ != NULL && _p_ != (elem) && comparator(_p_, (elem)) == 0) _p_=_p_->next;\ + (result) = (_p_ == (elem));\ +} + +#define SGLIB_SORTED_LIST_FIND_MEMBER_OR_PLACE(type, list, elem, comparator, next, comparator_result, member_ptr) {\ + (comparator_result) = -1;\ + for((member_ptr) = &(list); \ + *(member_ptr)!=NULL && ((comparator_result)=comparator((*member_ptr), (elem))) < 0; \ + (member_ptr) = &(*(member_ptr))->next) ;\ +} + +#define SGLIB_SORTED_LIST_LEN(type, list, next, result) {\ + SGLIB_LIST_LEN(type, list, next, result);\ +} + +#define SGLIB_SORTED_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command) {\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, next, command);\ +} + + +/* ------------------------------- double linked list (level 0) ------------------------- */ +/* + Lists with back pointer to previous element. Those lists implements deletion + of an element in a constant time. +*/ + +#define SGLIB___DL_LIST_CREATE_SINGLETON(type, list, elem, previous, next) {\ + (list) = (elem);\ + (list)->next = (list)->previous = NULL;\ +} + +#define SGLIB_DL_LIST_ADD_AFTER(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place)->next;\ + (elem)->previous = (place);\ + (place)->next = (elem);\ + if ((elem)->next != NULL) (elem)->next->previous = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE(type, place, elem, previous, next) {\ + if ((place) == NULL) {\ + SGLIB___DL_LIST_CREATE_SINGLETON(type, place, elem, previous, next);\ + } else {\ + (elem)->next = (place);\ + (elem)->previous = (place)->previous;\ + (place)->previous = (elem);\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem);\ + }\ +} + +#define SGLIB_DL_LIST_ADD(type, list, elem, previous, next) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, list, elem, previous, next)\ +} + +#define SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, the_add_operation) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ == NULL) {\ + the_add_operation(type, list, elem, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_BEFORE);\ +} + +#define SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD_AFTER);\ +} + +#define SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member) {\ + SGLIB___DL_LIST_GENERIC_ADD_IF_NOT_MEMBER(type, list, elem, comparator, previous, next, member, SGLIB_DL_LIST_ADD);\ +} + +#define SGLIB_DL_LIST_CONCAT(type, first, second, previous, next) {\ + if ((first)==NULL) {\ + (first) = (second);\ + } else if ((second)!=NULL) {\ + type *_dlp_;\ + for(_dlp_ = (first); _dlp_->next!=NULL; _dlp_=_dlp_->next) ;\ + SGLIB_DL_LIST_ADD_AFTER(type, _dlp_, second, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_DELETE(type, list, elem, previous, next) {\ + type *_l_;\ + _l_ = (list);\ + if (_l_ == (elem)) {\ + if ((elem)->previous != NULL) _l_ = (elem)->previous;\ + else _l_ = (elem)->next;\ + }\ + if ((elem)->next != NULL) (elem)->next->previous = (elem)->previous;\ + if ((elem)->previous != NULL) (elem)->previous->next = (elem)->next;\ + (list) = _l_;\ +} + +#define SGLIB_DL_LIST_DELETE_IF_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + for(_dlp_ = (list); _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->previous) ;\ + if (_dlp_ == NULL && (list) != NULL) {\ + for(_dlp_ = (list)->next; _dlp_!=NULL && comparator(_dlp_, (elem)) != 0; _dlp_= _dlp_->next) ;\ + }\ + (member) = _dlp_;\ + if (_dlp_ != NULL) {\ + SGLIB_DL_LIST_DELETE(type, list, _dlp_, previous, next);\ + }\ +} + +#define SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result) {\ + type *_dlp_;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, previous, result);\ + if (result == 0 && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_IS_MEMBER(type, _dlp_, elem, next, result);\ + }\ +} + +#define SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, member) {\ + type *_dlp_;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, previous, member);\ + if ((member) == NULL && (list) != NULL) {\ + _dlp_ = (list)->next;\ + SGLIB_LIST_FIND_MEMBER(type, _dlp_, elem, comparator, next, member);\ + }\ +} + +#define SGLIB_DL_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, next, command) {\ + type *_dl_;\ + type *iteratedVariable;\ + if ((list)!=NULL) {\ + _dl_ = (list)->next;\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, list, iteratedVariable, previous, command);\ + SGLIB_LIST_MAP_ON_ELEMENTS(type, _dl_, iteratedVariable, next, command);\ + }\ +} + +#define SGLIB_DL_LIST_SORT(type, list, comparator, previous, next) {\ + type *_dll_, *_dlp_, *_dlt_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + SGLIB_LIST_SORT(type, _dll_, comparator, next);\ + SGLIB___DL_LIST_CREATE_FROM_LIST(type, _dll_, previous, next);\ + (list) = _dll_;\ + }\ +} + +#define SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->previous!=NULL; _dll_=_dll_->previous) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result) {\ + type *_dll_;\ + _dll_ = (list);\ + if (_dll_ != NULL) {\ + for(; _dll_->next!=NULL; _dll_=_dll_->next) ;\ + }\ + (result) = _dll_;\ +} + +#define SGLIB_DL_LIST_LEN(type, list, previous, next, result) {\ + type *_dl_;\ + int _r1_, _r2_;\ + if ((list)==NULL) {\ + (result) = 0;\ + } else {\ + SGLIB_LIST_LEN(type, list, previous, _r1_);\ + _dl_ = (list)->next;\ + SGLIB_LIST_LEN(type, _dl_, next, _r2_);\ + (result) = _r1_ + _r2_;\ + }\ +} + +#define SGLIB_DL_LIST_REVERSE(type, list, previous, next) {\ + type *_list_,*_nlist_,*_dlp_,*_dln_;\ + _list_ = (list);\ + if (_list_!=NULL) {\ + _nlist_ = _list_->next;\ + while (_list_!=NULL) {\ + _dln_ = _list_->next; \ + _dlp_ = _list_->previous; \ + _list_->next = _dlp_;\ + _list_->previous = _dln_;\ + _list_ = _dlp_;\ + }\ + while (_nlist_!=NULL) {\ + _dln_ = _nlist_->next; \ + _dlp_ = _nlist_->previous; \ + _nlist_->next = _dlp_;\ + _nlist_->previous = _dln_;\ + _nlist_ = _dln_;\ + }\ + }\ +} + +#define SGLIB___DL_LIST_CREATE_FROM_LIST(type, list, previous, next) {\ + type *_dlp_, *_dlt_;\ + _dlp_ = NULL;\ + for(_dlt_ = (list); _dlt_!=NULL; _dlt_ = _dlt_->next) {\ + _dlt_->previous = _dlp_;\ + _dlp_ = _dlt_;\ + }\ +} + + +/* ------------------------------- binary tree traversal (level 0) -------------------- */ + + +#define SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, iteratedVariable, order, left, right, command) {\ + /* this is non-recursive implementation of tree traversal */\ + /* it maintains the path to the current node in the array '_path_' */\ + /* the _path_[0] contains the root of the tree; */\ + /* the _path_[_pathi_] contains the _current_element_ */\ + /* the macro does not use the _current_element_ after execution of command */\ + /* command can destroy it, it can free the element for example */\ + type *_path_[SGLIB_MAX_TREE_DEEP];\ + type *_right_[SGLIB_MAX_TREE_DEEP];\ + char _pass_[SGLIB_MAX_TREE_DEEP];\ + type *_cn_;\ + int _pathi_;\ + type *iteratedVariable;\ + _cn_ = (tree);\ + _pathi_ = 0;\ + while (_cn_!=NULL) {\ + /* push down to leftmost innermost element */\ + while(_cn_!=NULL) {\ + _path_[_pathi_] = _cn_;\ + _right_[_pathi_] = _cn_->right;\ + _pass_[_pathi_] = 0;\ + _cn_ = _cn_->left;\ + if (order == 0) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pathi_ ++;\ + if (_pathi_ >= SGLIB_MAX_TREE_DEEP) assert(0 && "the binary_tree is too deep");\ + }\ + do {\ + _pathi_ --;\ + if ((order==1 && _pass_[_pathi_] == 0)\ + || (order == 2 && (_pass_[_pathi_] == 1 || _right_[_pathi_]==NULL))) {\ + iteratedVariable = _path_[_pathi_];\ + {command;}\ + }\ + _pass_[_pathi_] ++;\ + } while (_pathi_>0 && _right_[_pathi_]==NULL) ;\ + _cn_ = _right_[_pathi_];\ + _right_[_pathi_] = NULL;\ + _pathi_ ++;\ + }\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 1, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_PREORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 0, left, right, command);\ +} + +#define SGLIB_BIN_TREE_MAP_ON_ELEMENTS_POSTORDER(type, tree, _current_element_, left, right, command) {\ + SGLIB___BIN_TREE_MAP_ON_ELEMENTS(type, tree, _current_element_, 2, left, right, command);\ +} + +#define SGLIB___BIN_TREE_FIND_MEMBER(type, tree, elem, left, right, comparator, res) {\ + type *_s_;\ + int _c_;\ + _s_ = (tree);\ + while (_s_!=NULL) {\ + _c_ = comparator((elem), _s_);\ + if (_c_ < 0) _s_ = _s_->left;\ + else if (_c_ > 0) _s_ = _s_->right;\ + else break;\ + }\ + (res) = _s_;\ +} + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - LEVEL - 1 INTERFACE - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------------ STATIC ARRAYS ------------------------------- */ +/* ---------------------------------------------------------------------------- */ + +/* ----------------------------- array sorting (level 1) ---------------------- */ + +#define SGLIB_DEFINE_ARRAY_SORTING_PROTOTYPES(type, comparator) \ + extern void sglib_##type##_array_quick_sort(type *a, int max);\ + extern void sglib_##type##_array_heap_sort(type *a, int max);\ + + +#define SGLIB_DEFINE_ARRAY_SORTING_FUNCTIONS(type, comparator) \ + void sglib_##type##_array_quick_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_QUICK_SORT(type, a, max, comparator);\ + }\ + void sglib_##type##_array_heap_sort(type *a, int max) {\ + SGLIB_ARRAY_SINGLE_HEAP_SORT(type, a, max, comparator);\ + }\ + + +/* ----------------------------- array queue (level 1) ------------------- */ +/* sglib's queue is stored in a fixed sized array */ +/* queue_type MUST be a structure containing fields: */ +/* afield is the array storing elem_type */ +/* ifield is the index of the first element in the queue */ +/* jfield is the index of the first free element after the queue */ +/* dim is the size of the array afield */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_QUEUE_PROTOTYPES(queue_type, elem_type, afield, ifield, jfield, dim) \ + extern void sglib_##queue_type##_init(queue_type *q); \ + extern int sglib_##queue_type##_is_empty(queue_type *q); \ + extern int sglib_##queue_type##_is_full(queue_type *q); \ + extern elem_type sglib_##queue_type##_first_element(queue_type *q); \ + extern elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q); \ + extern void sglib_##queue_type##_add_next(queue_type *q); \ + extern void sglib_##queue_type##_add(queue_type *q, elem_type elem); \ + extern void sglib_##queue_type##_delete_first(queue_type *q); \ + extern void sglib_##queue_type##_delete(queue_type *q); + + +#define SGLIB_DEFINE_QUEUE_FUNCTIONS(queue_type, elem_type, afield, ifield, jfield, dim) \ + void sglib_##queue_type##_init(queue_type *q) {\ + SGLIB_QUEUE_INIT(elem_type, q->afield, q->ifield, q->jfield);\ + }\ + int sglib_##queue_type##_is_empty(queue_type *q) {\ + return(SGLIB_QUEUE_IS_EMPTY(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + int sglib_##queue_type##_is_full(queue_type *q) {\ + return(SGLIB_QUEUE_IS_FULL(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type sglib_##queue_type##_first_element(queue_type *q) {\ + return(SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + elem_type *sglib_##queue_type##_first_element_ptr(queue_type *q) {\ + return(& SGLIB_QUEUE_FIRST_ELEMENT(elem_type, q->afield, q->ifield, q->jfield));\ + }\ + void sglib_##queue_type##_add_next(queue_type *q) {\ + SGLIB_QUEUE_ADD_NEXT(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_add(queue_type *q, elem_type elem) {\ + SGLIB_QUEUE_ADD(elem_type, q->afield, elem, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete_first(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + }\ + void sglib_##queue_type##_delete(queue_type *q) {\ + SGLIB_QUEUE_DELETE_FIRST(elem_type, q->afield, q->ifield, q->jfield, dim);\ + } + + +/* ------------------------ array heap (level 1) ------------------------- */ +/* sglib's heap is a priority queue implemented in a fixed sized array */ +/* heap_type MUST be a structure containing fields: */ +/* afield is the array of size dim storing elem_type */ +/* ifield is the index of the first free element after the queue */ +/* !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! */ + + +#define SGLIB_DEFINE_HEAP_PROTOTYPES(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + extern void sglib_##heap_type##_init(heap_type *q); \ + extern int sglib_##heap_type##_is_empty(heap_type *q); \ + extern int sglib_##heap_type##_is_full(heap_type *q); \ + extern elem_type sglib_##heap_type##_first_element(heap_type *q); \ + extern elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q); \ + extern void sglib_##heap_type##_add_next(heap_type *q); \ + extern void sglib_##heap_type##_add(heap_type *q, elem_type elem); \ + extern void sglib_##heap_type##_delete_first(heap_type *q); \ + extern void sglib_##heap_type##_delete(heap_type *q) + +#define SGLIB_DEFINE_HEAP_FUNCTIONS(heap_type, elem_type, afield, ifield, dim, comparator, elem_exchanger) \ + void sglib_##heap_type##_init(heap_type *q) {\ + SGLIB_HEAP_INIT(elem_type, q->afield, q->ifield);\ + }\ + int sglib_##heap_type##_is_empty(heap_type *q) {\ + return(SGLIB_HEAP_IS_EMPTY(elem_type, q->afield, q->ifield));\ + }\ + int sglib_##heap_type##_is_full(heap_type *q) {\ + return(SGLIB_HEAP_IS_FULL(elem_type, q->afield, q->ifield));\ + }\ + elem_type sglib_##heap_type##_first_element(heap_type *q) {\ + return(SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + elem_type *sglib_##heap_type##_first_element_ptr(heap_type *q) {\ + return(& SGLIB_HEAP_FIRST_ELEMENT(elem_type, q->afield, q->ifield));\ + }\ + void sglib_##heap_type##_add_next(heap_type *q) {\ + SGLIB_HEAP_ADD_NEXT(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_add(heap_type *q, elem_type elem) {\ + SGLIB_HEAP_ADD(elem_type, q->afield, elem, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete_first(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + }\ + void sglib_##heap_type##_delete(heap_type *q) {\ + SGLIB_HEAP_DELETE_FIRST(elem_type, q->afield, q->ifield, dim, comparator, elem_exchanger);\ + } + + +/* ------------------------ hashed table (level 1) ------------------------- */ +/* + + sglib's hash table is an array storing directly pointers to objects (not containers). + In this table there is a one-to-one mapping between 'objects' stored + in the table and indexes where they are placed. Each index is + pointing to exactly one 'object' and each 'object' stored in the + table occurs on exactly one index. Once an object is stored in the + table, it can be represented via its index. + + type - is the type of elements + dim - is the size of the hash array + hash_function - is a hashing function mapping type* to unsigned + comparator - is a comparator on elements + + !!!!!!! This data structure is NOT documented, do not use it !!!!!!!!!! +*/ + +#define SGLIB_DEFINE_HASHED_TABLE_PROTOTYPES(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_TABLE_FUNCTIONS(type, dim, hash_function, comparator) \ + struct sglib_hashed_##type##_iterator {\ + int currentIndex;\ + type **table;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + SGLIB_HASH_TAB_INIT(type, table, dim);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + SGLIB_HASH_TAB_ADD_IF_NOT_MEMBER(type, table, dim, elem, hash_function, comparator, *member);\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + int ind;\ + SGLIB_HASH_TAB_IS_MEMBER(type, table, dim, elem, hash_function, ind);\ + return(ind != -1);\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + type *mmb;\ + int ind;\ + SGLIB_HASH_TAB_FIND_MEMBER(type, table, dim, elem, hash_function, comparator, ind, mmb);\ + return(mmb);\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + int i;\ + it->table = table;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + for(i=0; i<(dim) && table[i]==NULL; i++) ;\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL);\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(table[it->currentIndex]);\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + i=it->currentIndex;\ + if (i<(dim)) {\ + for(i++; i<(dim) && table[i]==NULL; i++) ;\ + }\ + it->currentIndex = i;\ + if (i<(dim)) return(table[i]);\ + return(NULL);\ + } + + +/* ------------------- hashed container (only for level 1) -------------------- */ +/* + hashed container is a table of given fixed size containing another + (dynamic) base container in each cell. Once an object should be + inserted into the hashed container, a hash function is used to + determine the cell where the object belongs and the object is + inserted into the base container stored in this cell. Usually the + base container is simply a list or a sorted list, but it can be a + red-black tree as well. + + parameters: + type - the type of the container stored in each cell. + dim - the size of the hashed array + hash_function - the hashing function hashing 'type *' to unsigned. + +*/ + +#define SGLIB_DEFINE_HASHED_CONTAINER_PROTOTYPES(type, dim, hash_function) \ + struct sglib_hashed_##type##_iterator {\ + struct sglib_##type##_iterator containerIt;\ + type **table;\ + int currentIndex;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_hashed_##type##_init(type *table[dim]);\ + extern void sglib_hashed_##type##_add(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member);\ + extern void sglib_hashed_##type##_delete(type *table[dim], type *elem);\ + extern int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb);\ + extern int sglib_hashed_##type##_is_member(type *table[dim], type *elem);\ + extern type * sglib_hashed_##type##_find_member(type *table[dim], type *elem);\ + extern type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]); \ + extern type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it); \ + extern type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it); + +#define SGLIB_DEFINE_HASHED_CONTAINER_FUNCTIONS(type, dim, hash_function) \ + /*extern unsigned hash_function(type *elem);*/\ + void sglib_hashed_##type##_init(type *table[dim]) {\ + unsigned i;\ + for(i=0; i<(dim); i++) table[i] = NULL;\ + }\ + void sglib_hashed_##type##_add(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_add(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_add_if_not_member(type *table[dim], type *elem, type **member) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_add_if_not_member(&(table)[i], elem, member));\ + }\ + void sglib_hashed_##type##_delete(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + sglib_##type##_delete(&(table)[i], elem);\ + }\ + int sglib_hashed_##type##_delete_if_member(type *table[dim], type *elem, type **memb) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_delete_if_member(&(table)[i], elem, memb));\ + }\ + int sglib_hashed_##type##_is_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_is_member((table)[i], elem));\ + }\ + type * sglib_hashed_##type##_find_member(type *table[dim], type *elem) {\ + unsigned i;\ + i = ((unsigned)hash_function(elem)) % (dim);\ + return(sglib_##type##_find_member((table)[i], elem));\ + }\ + type *sglib_hashed_##type##_it_init_on_equal(struct sglib_hashed_##type##_iterator *it, type *table[dim], int (*subcomparator)(type *, type *), type *equalto) {\ + type *e;\ + it->table = table;\ + it->currentIndex = 0;\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, table[it->currentIndex], it->subcomparator, it->equalto);\ + if (e==NULL) e = sglib_hashed_##type##_it_next(it);\ + return(e);\ + }\ + type *sglib_hashed_##type##_it_init(struct sglib_hashed_##type##_iterator *it, type *table[dim]) {\ + return(sglib_hashed_##type##_it_init_on_equal(it, table, NULL, NULL));\ + }\ + type *sglib_hashed_##type##_it_current(struct sglib_hashed_##type##_iterator *it) {\ + return(sglib_##type##_it_current(&it->containerIt));\ + }\ + type *sglib_hashed_##type##_it_next(struct sglib_hashed_##type##_iterator *it) {\ + type *e;\ + e = sglib_##type##_it_next(&it->containerIt);\ + while (e==NULL && (++(it->currentIndex))<(dim)) {\ + e = sglib_##type##_it_init_on_equal(&it->containerIt, it->table[it->currentIndex], it->subcomparator, it->equalto);\ + }\ + return(e);\ + } + + + +/* ---------------------------------------------------------------------------- */ +/* ------------------------- DYNAMIC DATA STRUCTURES -------------------------- */ +/* ---------------------------------------------------------------------------- */ + + + +/* ------------------------------------ list (level 1) -------------------------------- */ + +#define SGLIB_DEFINE_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_LIST_IS_MEMBER(type, list, elem, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_LIST_ADD(type, *list, elem, next);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_LIST_CONCAT(type, *first, second, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_LIST_REVERSE(type, *list, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + +/* ----------------------------- sorted list (level 1) ----------------------------------- */ + + +#define SGLIB_DEFINE_SORTED_LIST_PROTOTYPES(type, comparator, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_SORTED_LIST_FUNCTIONS(type, comparator, next) \ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_SORTED_LIST_IS_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_SORTED_LIST_FIND_MEMBER(type, list, elem, comparator, next, result);\ + return(result);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_SORTED_LIST_ADD(type, *list, elem, comparator, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_SORTED_LIST_DELETE(type, *list, elem, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_SORTED_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_SORTED_LIST_LEN(type, list, next, res);\ + return(res);\ + }\ + void sglib_##type##_sort(type **list) { \ + SGLIB_LIST_SORT(type, *list, comparator, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->nextelem = list;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + int c;\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && (c=scp(ce, eq)) < 0) ce = ce->next;\ + if (ce != NULL && c > 0) ce = NULL;\ + }\ + it->currentelem = ce;\ + if (ce != NULL) it->nextelem = ce->next;\ + return(ce);\ + } + + +/* ----------------------------- double linked list (level 1) ------------------------------ */ + + +#define SGLIB_DEFINE_DL_LIST_PROTOTYPES(type, comparator, previous, next) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + type *prevelem;\ + type *nextelem;\ + int (*subcomparator)(type *, type *);\ + type *equalto;\ + };\ + extern void sglib_##type##_add(type **list, type *elem);\ + extern void sglib_##type##_add_before(type **list, type *elem);\ + extern void sglib_##type##_add_after(type **list, type *elem);\ + extern int sglib_##type##_add_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member);\ + extern void sglib_##type##_concat(type **first, type *second);\ + extern void sglib_##type##_delete(type **list, type *elem);\ + extern int sglib_##type##_delete_if_member(type **list, type *elem, type **member);\ + extern int sglib_##type##_is_member(type *list, type *elem);\ + extern type *sglib_##type##_find_member(type *list, type *elem);\ + extern type *sglib_##type##_get_first(type *list);\ + extern type *sglib_##type##_get_last(type *list);\ + extern void sglib_##type##_sort(type **list);\ + extern int sglib_##type##_len(type *list);\ + extern void sglib_##type##_reverse(type **list);\ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); + + +#define SGLIB_DEFINE_DL_LIST_FUNCTIONS(type, comparator, previous, next) \ + void sglib_##type##_add(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_after(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_AFTER(type, *list, elem, previous, next);\ + }\ + void sglib_##type##_add_before(type **list, type *elem) {\ + SGLIB_DL_LIST_ADD_BEFORE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_add_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_after_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_AFTER_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + int sglib_##type##_add_before_if_not_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_ADD_BEFORE_IF_NOT_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member==NULL);\ + }\ + void sglib_##type##_concat(type **first, type *second) {\ + SGLIB_DL_LIST_CONCAT(type, *first, second, previous, next);\ + }\ + void sglib_##type##_delete(type **list, type *elem) {\ + SGLIB_DL_LIST_DELETE(type, *list, elem, previous, next);\ + }\ + int sglib_##type##_delete_if_member(type **list, type *elem, type **member) {\ + SGLIB_DL_LIST_DELETE_IF_MEMBER(type, *list, elem, comparator, previous, next, *member);\ + return(*member!=NULL);\ + }\ + int sglib_##type##_is_member(type *list, type *elem) {\ + int result;\ + SGLIB_DL_LIST_IS_MEMBER(type, list, elem, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_find_member(type *list, type *elem) {\ + type *result;\ + SGLIB_DL_LIST_FIND_MEMBER(type, list, elem, comparator, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_first(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_FIRST(type, list, previous, next, result);\ + return(result);\ + }\ + type *sglib_##type##_get_last(type *list) {\ + type *result;\ + SGLIB_DL_LIST_GET_LAST(type, list, previous, next, result);\ + return(result);\ + }\ + void sglib_##type##_sort(type **list) {\ + SGLIB_DL_LIST_SORT(type, *list, comparator, previous, next);\ + }\ + int sglib_##type##_len(type *list) {\ + int res;\ + SGLIB_DL_LIST_LEN(type, list, previous, next, res);\ + return(res);\ + }\ + void sglib_##type##_reverse(type **list) {\ + SGLIB_DL_LIST_REVERSE(type, *list, previous, next);\ + }\ + \ + type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *list, int (*subcomparator)(type *, type *), type *equalto) {\ + it->subcomparator = subcomparator;\ + it->equalto = equalto;\ + it->prevelem = list;\ + it->nextelem = list;\ + if (list != NULL) it->nextelem = list->next;\ + return(sglib_##type##_it_next(it));\ + }\ + type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *list) {\ + return(sglib_##type##_it_init_on_equal(it, list, NULL, NULL));\ + }\ + type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ + }\ + type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + type *ce, *eq;\ + int (*scp)(type *, type *);\ + ce = it->prevelem;\ + it->prevelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(eq, ce)!=0) ce = ce->previous;\ + }\ + if (ce != NULL) {\ + it->prevelem = ce->previous;\ + } else {\ + ce = it->nextelem;\ + it->nextelem = NULL;\ + if (it->subcomparator != NULL) {\ + eq = it->equalto; \ + scp = it->subcomparator;\ + while (ce!=NULL && scp(ce, eq)!=0) ce = ce->next;\ + }\ + if (ce != NULL) it->nextelem = ce->next;\ + }\ + it->currentelem = ce;\ + return(ce);\ + } + + +/* --------------------------------- red-black trees (level 1) -------------------------------- */ + +/* + +This implementation requires pointers to left and right sons (no +parent pointer is needed) and one bit of additional information +storing the color of the node. The implementation follows discrepancy +fixing rules from: +http://www.cis.ohio-state.edu/~gurari/course/cis680/cis680Ch11.html + +*/ + +#define SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK) {\ + type *t, *tl, *a, *b, *c, *ar, *bl, *br, *cl, *cr;\ + t = *tree;\ + tl = t->leftt;\ + if (t->rightt!=NULL && SGLIB___GET_VALUE(t->rightt->bits)==RED) {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if ((tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) \ + || (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED)) {\ + SGLIB___SET_VALUE(t->leftt->bits,BLACK);\ + SGLIB___SET_VALUE(t->rightt->bits,BLACK);\ + SGLIB___SET_VALUE(t->bits,RED);\ + }\ + }\ + } else {\ + if (SGLIB___GET_VALUE(tl->bits)==RED) {\ + if (tl->leftt!=NULL && SGLIB___GET_VALUE(tl->leftt->bits)==RED) {\ + a = t; b = tl; c = tl->leftt;\ + br = b->rightt;\ + a->leftt = br;\ + b->leftt = c; b->rightt = a;\ + SGLIB___SET_VALUE(a->bits,RED);\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + *tree = b;\ + } else if (tl->rightt!=NULL && SGLIB___GET_VALUE(tl->rightt->bits)==RED) {\ + a = t; b = tl; ar=a->rightt;\ + bl=b->leftt; c=b->rightt;\ + cl=c->leftt; cr=c->rightt;\ + b->rightt = cl;\ + a->leftt = cr;\ + c->leftt = b;\ + c->rightt = a;\ + SGLIB___SET_VALUE(c->bits,BLACK);\ + SGLIB___SET_VALUE(a->bits,RED);\ + *tree = c;\ + }\ + }\ + }\ +} + +#define SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, leftt, rightt, bits, RED, BLACK, res) {\ + type *t, *a, *b, *c, *d, *ar, *bl, *br, *cl, *cr, *dl, *dr;\ + t = a = *tree;\ + assert(t!=NULL);\ + ar = a->rightt;\ + b = t->leftt;\ + if (b==NULL) {\ + assert(SGLIB___GET_VALUE(t->bits)==RED);\ + SGLIB___SET_VALUE(t->bits,BLACK);\ + res = 0;\ + } else {\ + bl = b->leftt;\ + br = b->rightt;\ + if (SGLIB___GET_VALUE(b->bits)==RED) {\ + if (br==NULL) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + res = 0;\ + } else {\ + c = br;\ + assert(c!=NULL && SGLIB___GET_VALUE(c->bits)==BLACK);\ + cl = c->leftt;\ + cr = c->rightt;\ + if ((cl==NULL||SGLIB___GET_VALUE(cl->bits)==BLACK) && (cr==NULL||SGLIB___GET_VALUE(cr->bits)==BLACK)) {\ + *tree = b;\ + b->rightt = a;\ + SGLIB___SET_VALUE(b->bits,BLACK);\ + a->leftt = c;\ + SGLIB___SET_VALUE(c->bits,RED);\ + res = 0;\ + } else if (cl!=NULL && SGLIB___GET_VALUE(cl->bits)==RED) {\ + if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + *tree = c;\ + c->leftt = b;\ + c->rightt = a;\ + b->leftt = bl;\ + b->rightt = cl;\ + a->leftt = cr;\ + SGLIB___SET_VALUE(cl->bits,BLACK);\ + res = 0;\ + }\ + } else if (cr!=NULL && SGLIB___GET_VALUE(cr->bits)==RED) {\ + assert(cl==NULL || SGLIB___GET_VALUE(cl->bits)==BLACK);\ + d = cr;\ + dl = d->leftt;\ + dr = d->rightt;\ + *tree = d;\ + SGLIB___SET_VALUE(d->bits,BLACK);\ + d->leftt = b;\ + c->rightt = dl;\ + d->rightt = a;\ + a->leftt = dr;\ + res = 0;\ + } else {\ + assert(0);\ + res = 0;\ + }\ + }\ + } else {\ + if ((bl==NULL || SGLIB___GET_VALUE(bl->bits)==BLACK) && (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK)) {\ + res = (SGLIB___GET_VALUE(a->bits)==BLACK);\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + SGLIB___SET_VALUE(b->bits,RED);\ + } else if (bl!=NULL && SGLIB___GET_VALUE(bl->bits)==RED) {\ + if (br==NULL || SGLIB___GET_VALUE(br->bits)==BLACK) {\ + *tree = b;\ + SGLIB___SET_VALUE(b->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + b->rightt = a;\ + a->leftt = br;\ + SGLIB___SET_VALUE(bl->bits,BLACK);\ + res = 0;\ + } else {\ + assert(bl!=NULL);\ + assert(br!=NULL);\ + assert(SGLIB___GET_VALUE(bl->bits)==RED);\ + assert(SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + } else {\ + assert(br!=NULL && SGLIB___GET_VALUE(br->bits)==RED);\ + c = br;\ + cl = c->leftt;\ + cr = c->rightt;\ + *tree = c;\ + SGLIB___SET_VALUE(c->bits,SGLIB___GET_VALUE(a->bits));\ + SGLIB___SET_VALUE(a->bits,BLACK);\ + c->leftt = b;\ + c->rightt = a;\ + b->rightt = cl;\ + a->leftt = cr;\ + res = 0;\ + }\ + }\ + }\ +} + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, bits, comparator, RED, BLACK) \ +static void sglib___##type##_fix_left_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK);\ +}\ +\ +static void sglib___##type##_fix_right_insertion_discrepancy(type **tree) {\ + SGLIB___RBTREE_FIX_INSERTION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK);\ +}\ +\ +static int sglib___##type##_fix_left_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, right, left, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static int sglib___##type##_fix_right_deletion_discrepancy(type **tree) {\ + int res;\ + SGLIB___RBTREE_FIX_DELETION_DISCREPANCY(type, tree, left, right, bits, RED, BLACK, res);\ + return(res);\ +}\ +\ +static void sglib___##type##_add_recursive(type **tree, type *elem) {\ + int cmp;\ + type *t;\ + t = *tree;\ + if (t == NULL) {\ + SGLIB___SET_VALUE(elem->bits,RED);\ + *tree =elem;\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_left_insertion_discrepancy(tree);\ + } else {\ + sglib___##type##_add_recursive(&t->right, elem);\ + if (SGLIB___GET_VALUE(t->bits)==BLACK) sglib___##type##_fix_right_insertion_discrepancy(tree);\ + }\ + }\ +}\ +\ +static int sglib___##type##_delete_rightmost_leaf(type **tree, type **theLeaf) {\ + type *t;\ + int res, deepDecreased;\ + t = *tree;\ + res = 0;\ + assert(t!=NULL);\ + if (t->right == NULL) {\ + *theLeaf = t;\ + if (t->left!=NULL) {\ + if (SGLIB___GET_VALUE(t->bits)==BLACK && SGLIB___GET_VALUE(t->left->bits)==BLACK) res = 1;\ + SGLIB___SET_VALUE(t->left->bits,BLACK);\ + *tree = t->left;\ + } else {\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + }\ + } else {\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->right, theLeaf);\ + if (deepDecreased) res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + return(res);\ +}\ +\ +int sglib___##type##_delete_recursive(type **tree, type *elem) {\ + type *t, *theLeaf;\ + int cmp, res, deepDecreased;\ + t = *tree;\ + res = 0;\ + if (t==NULL) {\ + assert(0 && "The element to delete not found in the tree, use 'delete_if_member'"!=NULL);\ + } else {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + deepDecreased = sglib___##type##_delete_recursive(&t->right, elem);\ + if (deepDecreased) {\ + res = sglib___##type##_fix_right_deletion_discrepancy(tree);\ + }\ + } else {\ + assert(elem==t && "Deleting an element which is non member of the tree, use 'delete_if_member'"!=NULL);\ + if (t->left == NULL) {\ + if (t->right == NULL) {\ + /* a leaf, delete, it; */\ + *tree = NULL;\ + res = (SGLIB___GET_VALUE(t->bits)==BLACK);\ + } else {\ + if (SGLIB___GET_VALUE(t->bits)==0 && SGLIB___GET_VALUE(t->right->bits)==0) res = 1;\ + SGLIB___SET_VALUE(t->right->bits,BLACK);\ + *tree = t->right;\ + }\ + } else {\ + /* propagate deletion until righmost leaf of left subtree */\ + deepDecreased = sglib___##type##_delete_rightmost_leaf(&t->left, &theLeaf);\ + theLeaf->left = t->left;\ + theLeaf->right = t->right;\ + SGLIB___SET_VALUE(theLeaf->bits,SGLIB___GET_VALUE(t->bits));\ + *tree = theLeaf;\ + if (deepDecreased) res = sglib___##type##_fix_left_deletion_discrepancy(tree);\ + }\ + }\ + }\ + return(res);\ +}\ +\ +void sglib_##type##_add(type **tree, type *elem) {\ + elem->left = elem->right = NULL;\ + sglib___##type##_add_recursive(tree, elem);\ + SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +void sglib_##type##_delete(type **tree, type *elem) {\ + sglib___##type##_delete_recursive(tree, elem);\ + if (*tree!=NULL) SGLIB___SET_VALUE((*tree)->bits,BLACK);\ +}\ +\ +type *sglib_##type##_find_member(type *t, type *elem) {\ + type *res;\ + SGLIB___BIN_TREE_FIND_MEMBER(type, t, elem, left, right, comparator, res);\ + return(res);\ +}\ +\ +int sglib_##type##_is_member(type *t, type *elem) {\ + int cmp;\ + while (t!=NULL) {\ + cmp = comparator(elem, t);\ + if (cmp < 0 || (cmp==0 && elemleft;\ + } else if (cmp > 0 || (cmp==0 && elem>t)) {\ + t = t->right;\ + } else {\ + assert(t == elem);\ + return(1);\ + }\ + }\ + return(0);\ +}\ +\ +int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))!=NULL) {\ + sglib_##type##_delete(tree, *memb);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb) {\ + if ((*memb=sglib_##type##_find_member(*tree, elem))==NULL) {\ + sglib_##type##_add(tree, elem);\ + return(1);\ + } else {\ + return(0);\ + }\ +}\ +int sglib_##type##_len(type *t) {\ + int n;\ + type *e;\ + n = 0;\ + SGLIB_BIN_TREE_MAP_ON_ELEMENTS(type, t, e, left, right, n++);\ + return(n);\ +}\ +\ +void sglib__##type##_it_compute_current_elem(struct sglib_##type##_iterator *it) {\ + int i,j,cmp;\ + type *s, *eqt;\ + int (*subcomparator)(type *, type *);\ + eqt = it->equalto;\ + subcomparator = it->subcomparator;\ + it->currentelem = NULL;\ + while(it->pathi > 0 && it->currentelem==NULL) {\ + i = it->pathi-1;\ + if (i >= 0) {\ + if (it->pass[i] >= 2) {\ + /* goto up */\ + it->pathi --;\ + } else {\ + if (it->pass[i] == 0) {\ + /* goto left */\ + s = it->path[i]->left;\ + } else {\ + /* goto right */\ + s = it->path[i]->right;\ + }\ + if (eqt != NULL) {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, comparator, s);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, s, eqt, left, right, subcomparator, s);\ + }\ + }\ + if (s != NULL) {\ + j = i+1;\ + it->path[j] = s;\ + it->pass[j] = 0;\ + it->pathi ++;\ + }\ + it->pass[i] ++;\ + }\ + }\ + if (it->pathi>0 && it->order == it->pass[it->pathi-1]) {\ + it->currentelem = it->path[it->pathi-1];\ + }\ + }\ +}\ +type *sglib__##type##_it_init(struct sglib_##type##_iterator *it, type *tree, int order, int (*subcomparator)(type *, type *), type *equalto) {\ + type *t;\ + assert(it!=NULL);\ + it->order = order;\ + it->equalto = equalto;\ + it->subcomparator = subcomparator;\ + if (equalto == NULL) { \ + t = tree;\ + } else {\ + if (subcomparator == NULL) {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, comparator, t);\ + } else {\ + SGLIB___BIN_TREE_FIND_MEMBER(type, tree, equalto, left, right, subcomparator, t);\ + }\ + }\ + if (t == NULL) {\ + it->pathi = 0;\ + it->currentelem = NULL;\ + } else {\ + it->pathi = 1;\ + it->pass[0] = 0;\ + it->path[0] = t;\ + if (order == 0) {\ + it->currentelem = t;\ + } else {\ + sglib__##type##_it_compute_current_elem(it);\ + }\ + }\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 0, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 1, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree) {\ + return(sglib__##type##_it_init(it, tree, 2, NULL, NULL));\ +}\ +type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto) {\ + return(sglib__##type##_it_init(it, tree, 1, subcomparator, equalto));\ +}\ +type *sglib_##type##_it_current(struct sglib_##type##_iterator *it) {\ + return(it->currentelem);\ +}\ +type *sglib_##type##_it_next(struct sglib_##type##_iterator *it) {\ + sglib__##type##_it_compute_current_elem(it);\ + return(it->currentelem);\ +}\ +\ +static void sglib___##type##_consistency_check_recursive(type *t, int *pathdeep, int cdeep) {\ + if (t==NULL) {\ + if (*pathdeep < 0) *pathdeep = cdeep;\ + else assert(*pathdeep == cdeep);\ + } else {\ + if (t->left!=NULL) assert(comparator(t->left, t) <= 0);\ + if (t->right!=NULL) assert(comparator(t, t->right) <= 0);\ + if (SGLIB___GET_VALUE(t->bits) == RED) {\ + assert(t->left == NULL || SGLIB___GET_VALUE(t->left->bits)==BLACK);\ + assert(t->right == NULL || SGLIB___GET_VALUE(t->right->bits)==BLACK);\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep);\ + } else {\ + sglib___##type##_consistency_check_recursive(t->left, pathdeep, cdeep+1);\ + sglib___##type##_consistency_check_recursive(t->right, pathdeep, cdeep+1);\ + }\ + }\ +}\ +\ +void sglib___##type##_consistency_check(type *t) {\ + int pathDeep;\ + assert(t==NULL || SGLIB___GET_VALUE(t->bits) == BLACK);\ + pathDeep = -1;\ + sglib___##type##_consistency_check_recursive(t, &pathDeep, 0);\ +} + + +#define SGLIB_DEFINE_RBTREE_PROTOTYPES(type, left, right, colorbit, comparator) \ + struct sglib_##type##_iterator {\ + type *currentelem;\ + char pass[SGLIB_MAX_TREE_DEEP];\ + type *path[SGLIB_MAX_TREE_DEEP];\ + short int pathi;\ + short int order;\ + type *equalto;\ + int (*subcomparator)(type *, type *);\ + };\ + extern void sglib___##type##_consistency_check(type *t); \ + extern void sglib_##type##_add(type **tree, type *elem); \ + extern int sglib_##type##_add_if_not_member(type **tree, type *elem, type **memb); \ + extern void sglib_##type##_delete(type **tree, type *elem); \ + extern int sglib_##type##_delete_if_member(type **tree, type *elem, type **memb); \ + extern int sglib_##type##_is_member(type *t, type *elem); \ + extern type *sglib_##type##_find_member(type *t, type *elem); \ + extern int sglib_##type##_len(type *t); \ + extern type *sglib_##type##_it_init(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_preorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_inorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_postorder(struct sglib_##type##_iterator *it, type *tree); \ + extern type *sglib_##type##_it_init_on_equal(struct sglib_##type##_iterator *it, type *tree, int (*subcomparator)(type *, type *), type *equalto); \ + extern type *sglib_##type##_it_current(struct sglib_##type##_iterator *it); \ + extern type *sglib_##type##_it_next(struct sglib_##type##_iterator *it); \ + + +#define SGLIB_DEFINE_RBTREE_FUNCTIONS(type, left, right, colorbit, comparator) \ + SGLIB_DEFINE_RBTREE_FUNCTIONS_GENERAL(type, left, right, colorbit, comparator, 1, 0) + + + +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ +/* - SUPPLEMENTARY DEFINITIONS - */ +/* ---------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------- */ + + +#define SGLIB___GET_VALUE(x) (x) +#define SGLIB___SET_VALUE(x, value) {(x) = (value);} +#define SGLIB_ARRAY_ELEMENTS_EXCHANGER(type, a, i, j) {type _sgl_aee_tmp_; _sgl_aee_tmp_=(a)[(i)]; (a)[(i)]=(a)[(j)]; (a)[(j)]= _sgl_aee_tmp_;} + + +#define SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?1:((x)<(y)?-1:0))) +#define SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) (((x)>(y)?-1:((x)<(y)?1:0))) +#define SGLIB_FAST_NUMERIC_COMPARATOR(x, y) ((int)((x) - (y))) +#define SGLIB_FAST_REVERSE_NUMERIC_COMPARATOR(x, y) ((int)((y) - (x))) +#define SGLIB_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_NUMERIC_COMPARATOR(x, y) +#define SGLIB_REVERSE_NUMERIC_COMPARATOR(x, y) SGLIB_SAFE_REVERSE_NUMERIC_COMPARATOR(x, y) + +#ifndef SGLIB_MAX_TREE_DEEP +#define SGLIB_MAX_TREE_DEEP 128 +#endif + +#ifndef SGLIB_HASH_TAB_SHIFT_CONSTANT +#define SGLIB_HASH_TAB_SHIFT_CONSTANT 16381 /* should be a prime */ +/* #define SGLIB_HASH_TAB_SHIFT_CONSTANT 536870912*/ /* for large tables :) */ +#endif + +#endif /* _SGLIB__h_ */ diff --git a/bundles/n2n_meyerd/n2n_v2/sn.c b/bundles/n2n_meyerd/n2n_v2/sn.c new file mode 100644 index 00000000..647a4b27 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/sn.c @@ -0,0 +1,895 @@ +/* Supernode for n2n-2.x */ + +/* (c) 2009 Richard Andrews + * + * Contributions by: + * Lukasz Taczuk + * Struan Bartlett + */ + + +#include "n2n.h" + + +#define N2N_SN_LPORT_DEFAULT 7654 +#define N2N_SN_PKTBUF_SIZE 2048 + +#define N2N_SN_MGMT_PORT 5645 + + +struct sn_stats +{ + size_t errors; /* Number of errors encountered. */ + size_t reg_super; /* Number of REGISTER_SUPER requests received. */ + size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ + size_t fwd; /* Number of messages forwarded. */ + size_t broadcast; /* Number of messages broadcast to a community. */ + time_t last_fwd; /* Time when last message was forwarded. */ + time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ +}; + +typedef struct sn_stats sn_stats_t; + +struct n2n_sn +{ + time_t start_time; /* Used to measure uptime. */ + sn_stats_t stats; + int daemon; /* If non-zero then daemonise. */ + uint16_t lport; /* Local UDP port to bind to. */ + int sock; /* Main socket for UDP traffic with edges. */ + int mgmt_sock; /* management socket. */ + time_t last_purge; /* last purge time */ + peer_info_t * edges[PEER_HASH_TAB_SIZE]; /* Link list of registered edges. */ +}; + +typedef struct n2n_sn n2n_sn_t; + + +static int try_forward( n2n_sn_t * sss, + const n2n_common_t * cmn, + const n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktsize ); + +static int try_broadcast( n2n_sn_t * sss, + const n2n_common_t * cmn, + const n2n_mac_t srcMac, + const uint8_t * pktbuf, + size_t pktsize ); + + + +/** Initialise the supernode structure */ +static int init_sn( n2n_sn_t * sss ) +{ +#ifdef WIN32 + initWin32(); +#endif + memset( sss, 0, sizeof(n2n_sn_t) ); + + sss->daemon = 1; /* By defult run as a daemon. */ + sss->lport = N2N_SN_LPORT_DEFAULT; + sss->sock = -1; + sss->mgmt_sock = -1; + sss->last_purge = 0; + sglib_hashed_peer_info_t_init(sss->edges); + + return 0; /* OK */ +} + +/** Deinitialise the supernode structure and deallocate any memory owned by + * it. */ +static void deinit_sn( n2n_sn_t * sss ) +{ + if (sss->sock >= 0) + { + closesocket(sss->sock); + } + sss->sock=-1; + + if ( sss->mgmt_sock >= 0 ) + { + closesocket(sss->mgmt_sock); + } + sss->mgmt_sock=-1; + + purge_hashed_peer_list_t(sss->edges, 0xffffffff); +} + + +/** Determine the appropriate lifetime for new registrations. + * + * If the supernode has been put into a pre-shutdown phase then this lifetime + * should not allow registrations to continue beyond the shutdown point. + */ +static uint16_t reg_lifetime( n2n_sn_t * sss ) +{ + return 30; +} + + +/** Update the edge table with the details of the edge which contacted the + * supernode. */ +static int update_edge( n2n_sn_t * sss, + const n2n_REGISTER_SUPER_t * reg, + const n2n_community_t community, + const n2n_sock_t * sender_sock, + time_t now) +{ + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + struct peer_info * scan; + + traceEvent( TRACE_DEBUG, "update_edge for %s [%s]", + macaddr_str( mac_buf, reg->edgeMac ), + sock_to_cstr( sockbuf, sender_sock ) ); + + scan = find_peer_by_mac( sss->edges, reg->edgeMac ); + + if ( NULL == scan ) + { + /* Not known */ + + scan = (struct peer_info*)calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ + + memcpy(scan->community_name, community, sizeof(n2n_community_t) ); + memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t)); + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + + scan->timeout = reg->timeout; + if(reg->aflags & N2N_AFLAGS_LOCAL_SOCKET) { + scan->num_sockets = 2; + scan->sockets = malloc(scan->num_sockets*sizeof(n2n_sock_t)); + scan->sockets[1] = reg->local_sock; + } else { + scan->num_sockets = 1; + scan->sockets = malloc(scan->num_sockets*sizeof(n2n_sock_t)); + } + scan->sockets[0] = scan->sock; + + /* insert this guy at the head of the edges list */ + sglib_hashed_peer_info_t_add(sss->edges, scan); + + traceEvent( TRACE_INFO, "update_edge created %s ==> %s", + macaddr_str( mac_buf, reg->edgeMac ), + sock_to_cstr( sockbuf, sender_sock ) ); + } + else + { + /* Known */ + int num_changes = 0; + scan->timeout = reg->timeout; + if (0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) + { + memcpy(scan->community_name, community, sizeof(n2n_community_t) ); + num_changes++; + } + if (0 != sock_equal(sender_sock, &(scan->sock) )) { + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + memcpy(scan->sockets, sender_sock, sizeof(n2n_sock_t)); + num_changes++; + } + if (scan->num_sockets == 1) { + if (reg->aflags & N2N_AFLAGS_LOCAL_SOCKET) { + scan->num_sockets = 2; + free(scan->sockets); + scan->sockets = malloc(scan->num_sockets*sizeof(n2n_sock_t)); + scan->sockets[0] = scan->sock; + scan->sockets[1] = reg->local_sock; + } + } else { + if (reg->aflags & N2N_AFLAGS_LOCAL_SOCKET) { + if (0 != sock_equal(&(reg->local_sock), scan->sockets+1 )) { + memcpy(scan->sockets+1, &(reg->local_sock), sizeof(n2n_sock_t)); + } + } else { + scan->num_sockets = 1; + free(scan->sockets); + scan->sockets = malloc(scan->num_sockets*sizeof(n2n_sock_t)); + scan->sockets[0] = scan->sock; + } + } + if (num_changes) { + traceEvent( TRACE_INFO, "update_edge updated %s ==> %s", + macaddr_str( mac_buf, reg->edgeMac ), + sock_to_cstr( sockbuf, sender_sock ) ); + } else { + traceEvent( TRACE_DEBUG, "update_edge unchanged %s ==> %s", + macaddr_str( mac_buf, reg->edgeMac ), + sock_to_cstr( sockbuf, sender_sock ) ); + } + + } + + scan->last_seen = now; + return 0; +} + + +/** Send a datagram to the destination embodied in a n2n_sock_t. + * + * @return -1 on error otherwise number of bytes sent + */ +static ssize_t sendto_sock(n2n_sn_t * sss, + const n2n_sock_t * sock, + const uint8_t * pktbuf, + size_t pktsize) +{ + n2n_sock_str_t sockbuf; + + if ( AF_INET == sock->family ) + { + struct sockaddr_in udpsock; + + udpsock.sin_family = AF_INET; + udpsock.sin_port = htons( sock->port ); + memcpy( &(udpsock.sin_addr.s_addr), &(sock->addr.v4), IPV4_SIZE ); + + traceEvent( TRACE_DEBUG, "sendto_sock %lu to [%s]", + pktsize, + sock_to_cstr( sockbuf, sock ) ); + + return sendto( sss->sock, pktbuf, pktsize, 0, + (const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in) ); + } + else + { + /* AF_INET6 not implemented */ + errno = EAFNOSUPPORT; + return -1; + } +} + + + +/** Try to forward a message to a unicast MAC. If the MAC is unknown then + * broadcast to all edges in the destination community. + */ +static int try_forward( n2n_sn_t * sss, + const n2n_common_t * cmn, + const n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktsize ) +{ + struct peer_info * scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + scan = find_peer_by_mac( sss->edges, dstMac ); + + if ( NULL != scan ) + { + int data_sent_len; + data_sent_len = sendto_sock( sss, &(scan->sock), pktbuf, pktsize ); + + if ( data_sent_len == pktsize ) + { + ++(sss->stats.fwd); + traceEvent(TRACE_DEBUG, "unicast %lu to [%s] %s", + pktsize, + sock_to_cstr( sockbuf, &(scan->sock) ), + macaddr_str(mac_buf, scan->mac_addr)); + } + else + { + ++(sss->stats.errors); + traceEvent(TRACE_ERROR, "unicast %lu to [%s] %s FAILED (%d: %s)", + pktsize, + sock_to_cstr( sockbuf, &(scan->sock) ), + macaddr_str(mac_buf, scan->mac_addr), + errno, strerror(errno) ); + } + } + else + { + traceEvent( TRACE_DEBUG, "try_forward unknown MAC" ); + + /* Not a known MAC so drop. */ + } + + return 0; +} + + +/** Try and broadcast a message to all edges in the community. + * + * This will send the exact same datagram to zero or more edges registered to + * the supernode. + */ +static int try_broadcast( n2n_sn_t * sss, + const n2n_common_t * cmn, + const n2n_mac_t srcMac, + const uint8_t * pktbuf, + size_t pktsize ) +{ + peer_info_t * ll; + struct sglib_hashed_peer_info_t_iterator it; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + traceEvent( TRACE_DEBUG, "try_broadcast" ); + + for(ll=sglib_hashed_peer_info_t_it_init(&it,sss->edges); ll!=NULL; ll=sglib_hashed_peer_info_t_it_next(&it)) { + if( 0 == (memcmp(ll->community_name, cmn->community, sizeof(n2n_community_t)) ) + && (0 != memcmp(srcMac, ll->mac_addr, sizeof(n2n_mac_t)) ) ) + /* REVISIT: exclude if the destination socket is where the packet came from. */ + { + int data_sent_len; + + data_sent_len = sendto_sock(sss, &(ll->sock), pktbuf, pktsize); + + if(data_sent_len != pktsize) + { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", + pktsize, + sock_to_cstr( sockbuf, &(ll->sock) ), + macaddr_str(mac_buf, ll->mac_addr), + strerror(errno)); + } + else + { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", + pktsize, + sock_to_cstr( sockbuf, &(ll->sock) ), + macaddr_str(mac_buf, ll->mac_addr)); + } + } + } /* for */ + + return 0; +} + + +static int process_mgmt( n2n_sn_t * sss, + const struct sockaddr_in * sender_sock, + const uint8_t * mgmt_buf, + size_t mgmt_size, + time_t now) +{ + char resbuf[N2N_SN_PKTBUF_SIZE]; + size_t ressize=0; + ssize_t r; + + traceEvent( TRACE_DEBUG, "process_mgmt" ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "----------------\n" ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "uptime %lu\n", (now - sss->start_time) ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "edges %u\n", + (unsigned int)hashed_peer_list_t_size( sss->edges )); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "errors %u\n", + (unsigned int)sss->stats.errors ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "reg_sup %u\n", + (unsigned int)sss->stats.reg_super ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "reg_nak %u\n", + (unsigned int)sss->stats.reg_super_nak ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "fwd %u\n", + (unsigned int) sss->stats.fwd ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "broadcast %u\n", + (unsigned int) sss->stats.broadcast ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "last fwd %lu sec ago\n", + (long unsigned int)(now - sss->stats.last_fwd) ); + + ressize += snprintf( resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "last reg %lu sec ago\n", + (long unsigned int) (now - sss->stats.last_reg_super) ); + + + r = sendto( sss->mgmt_sock, resbuf, ressize, 0/*flags*/, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + + if ( r <= 0 ) + { + ++(sss->stats.errors); + traceEvent( TRACE_ERROR, "process_mgmt : sendto failed. %s", strerror(errno) ); + } + + return 0; +} + + +/** Examine a datagram and determine what to do with it. + * + */ +static int process_udp( n2n_sn_t * sss, + const struct sockaddr_in * sender_sock, + const uint8_t * udp_buf, + size_t udp_size, + time_t now) +{ + n2n_common_t cmn; /* common fields in the packet header */ + n2n_common_t cmn2; /* common fields of newly generated packets */ + size_t rem; + size_t idx; + size_t msg_type; + uint8_t from_supernode; + macstr_t mac_buf; + macstr_t mac_buf2; + n2n_sock_str_t sockbuf; + const uint8_t * rec_buf; /* either udp_buf or encbuf */ + int unicast; /* non-zero if unicast */ + size_t encx=0; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + n2n_ETHFRAMEHDR_t eth; + int i; + + /* for PACKET packages */ + n2n_PACKET_t pkt; + + /* for QUERY_PEER packages */ + n2n_QUERY_PEER_t query; + struct peer_info * scan; + n2n_PEER_INFO_t pi; + + /* for REGISTER packages */ + n2n_REGISTER_t reg; + + /* for REGISTER_SUPER packages */ + n2n_REGISTER_SUPER_t regs; + n2n_REGISTER_SUPER_ACK_t ack; + + traceEvent( TRACE_DEBUG, "process_udp(%lu)", udp_size ); + + /* Use decode_common() to determine the kind of packet then process it: + * + * REGISTER_SUPER adds an edge and generate a return REGISTER_SUPER_ACK + * + * REGISTER, REGISTER_ACK and PACKET messages are forwarded to their + * destination edge. If the destination is not known then PACKETs are + * broadcast. + */ + + rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + if ( decode_common(&cmn, udp_buf, &rem, &idx) < 0 ) + { + traceEvent( TRACE_ERROR, "Failed to decode common section" ); + return -1; /* failed to decode packet */ + } + + msg_type = cmn.pc; /* packet code */ + from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; + + if ( cmn.ttl < 1 ) + { + traceEvent( TRACE_WARNING, "Expired TTL" ); + return 0; /* Don't process further */ + } + + --(cmn.ttl); /* The value copied into all forwarded packets. */ + + switch(msg_type) { + case MSG_TYPE_PACKET: + /* PACKET from one edge to another edge via supernode. */ + + /* pkt will be modified in place and recoded to an output of potentially + * different size due to addition of the socket.*/ + + + sss->stats.last_fwd=now; + decode_PACKET( &pkt, &cmn, udp_buf, &rem, &idx ); + decode_ETHFRAMEHDR( ð, udp_buf+idx ); + + unicast = (0 == is_multi_broadcast(eth.dstMac) ); + + traceEvent( TRACE_DEBUG, "Rx PACKET (%s) %s -> %s %s", + (unicast?"unicast":"multicast"), + macaddr_str( mac_buf, eth.srcMac ), + macaddr_str( mac_buf2, eth.dstMac ), + (from_supernode?"from sn":"local") ); + + if ( !from_supernode ) + { + memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) ); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_FROM_SUPERNODE; + + rec_buf = encbuf; + + /* Re-encode the header. */ + encode_PACKET( encbuf, &encx, &cmn2, &pkt ); + + /* Copy the original payload unchanged */ + encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) ); + } + else + { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + traceEvent( TRACE_DEBUG, "Rx PACKET fwd unmodified" ); + + rec_buf = udp_buf; + encx = udp_size; + } + + /* Common section to forward the final product. */ + if ( unicast ) + { + try_forward( sss, &cmn, eth.dstMac, rec_buf, encx ); + } + else + { + try_broadcast( sss, &cmn, eth.srcMac, rec_buf, encx ); + } + break; + case MSG_TYPE_QUERY_PEER: + decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx ); + + traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", + macaddr_str( mac_buf, query.srcMac ), + macaddr_str( mac_buf2, query.targetMac ) ); + + scan = find_peer_by_mac( sss->edges, query.targetMac ); + if (scan && 0 == memcmp(cmn.community, scan->community_name, + sizeof(n2n_community_t))) { + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_peer_info; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); + + pi.aflags = 0; + pi.timeout = scan->timeout; + memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); + for(i=0; inum_sockets; i++) + pi.sockets[i] = scan->sockets[i]; + if(scan->num_sockets > 1) + pi.aflags |= N2N_AFLAGS_LOCAL_SOCKET; + + encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); + + sendto( sss->sock, encbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + + traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", + macaddr_str( mac_buf, query.srcMac ) ); + } else { + traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s", + macaddr_str( mac_buf, query.targetMac ) ); + } + + break; + case MSG_TYPE_REGISTER: + /* Forwarding a REGISTER from one edge to the next */ + + + sss->stats.last_fwd=now; + decode_REGISTER( ®, &cmn, udp_buf, &rem, &idx ); + + unicast = (0 == is_multi_broadcast(reg.dstMac) ); + + if ( unicast ) + { + traceEvent( TRACE_DEBUG, "Rx REGISTER %s -> %s %s", + macaddr_str( mac_buf, reg.srcMac ), + macaddr_str( mac_buf2, reg.dstMac ), + ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local") ); + + if ( 0 != (cmn.flags & N2N_FLAGS_FROM_SUPERNODE) ) + { + memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) ); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_FROM_SUPERNODE; + + reg.sock.family = AF_INET; + reg.sock.port = ntohs(sender_sock->sin_port); + memcpy( reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE ); + + rec_buf = encbuf; + + /* Re-encode the header. */ + encode_REGISTER( encbuf, &encx, &cmn2, ® ); + + /* Copy the original payload unchanged */ + encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) ); + } + else + { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + rec_buf = udp_buf; + encx = udp_size; + } + + try_forward( sss, &cmn, reg.dstMac, rec_buf, encx ); /* unicast only */ + } + else + { + traceEvent( TRACE_ERROR, "Rx REGISTER with multicast destination" ); + } + break; + case MSG_TYPE_REGISTER_ACK: + traceEvent( TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) SHould not be via supernode" ); + break; + case MSG_TYPE_REGISTER_SUPER: + /* Edge requesting registration with us. */ + + sss->stats.last_reg_super=now; + ++(sss->stats.reg_super); + decode_REGISTER_SUPER( ®s, &cmn, udp_buf, &rem, &idx ); + + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_register_super_ack; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); + + memcpy( &(ack.cookie), &(regs.cookie), sizeof(n2n_cookie_t) ); + memcpy( ack.edgeMac, regs.edgeMac, sizeof(n2n_mac_t) ); + ack.lifetime = reg_lifetime( sss ); + + ack.sock.family = AF_INET; + ack.sock.port = ntohs(sender_sock->sin_port); + memcpy( ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE ); + + ack.num_sn=0; /* No backup */ + memset( &(ack.sn_bak), 0, sizeof(n2n_sock_t) ); + + traceEvent( TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", + macaddr_str( mac_buf, regs.edgeMac ), + sock_to_cstr( sockbuf, &(ack.sock) ) ); + + update_edge( sss, ®s, cmn.community, &(ack.sock), now ); + + encode_REGISTER_SUPER_ACK( encbuf, &encx, &cmn2, &ack ); + + sendto( sss->sock, encbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + + traceEvent( TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", + macaddr_str( mac_buf, regs.edgeMac ), + sock_to_cstr( sockbuf, &(ack.sock) ) ); + break; + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); + break; + } + + return 0; +} + + +/** Help message to print if the command line arguments are not valid. */ +static void exit_help(int argc, char * const argv[]) +{ + fprintf( stderr, "%s usage\n", argv[0] ); + fprintf( stderr, "-l \tSet UDP main listen port to \n" ); + +#if defined(N2N_HAVE_DAEMON) + fprintf( stderr, "-f \tRun in foreground.\n" ); +#endif /* #if defined(N2N_HAVE_DAEMON) */ +#ifndef WIN32 + fprintf( stderr, "-u \tUser ID (numeric) to use when privileges are dropped.\n"); + fprintf( stderr, "-g \tGroup ID (numeric) to use when privileges are dropped.\n"); +#endif /* ifndef WIN32 */ + fprintf( stderr, "-v \tIncrease verbosity. Can be used multiple times.\n" ); + fprintf( stderr, "-h \tThis help message.\n" ); + fprintf( stderr, "\n" ); + exit(1); +} + +static int run_loop( n2n_sn_t * sss ); + +/* *********************************************** */ + +static const struct option long_options[] = { + { "foreground", no_argument, NULL, 'f' }, + { "local-port", required_argument, NULL, 'l' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +/** Main program entry point from kernel. */ +int main( int argc, char * const argv[] ) +{ + n2n_sn_t sss; + +#ifndef WIN32 + uid_t userid=0; /* root is the only guaranteed ID */ + gid_t groupid=0; /* root is the only guaranteed ID */ +#endif + + init_sn( &sss ); + + { + int opt; + + while((opt = getopt_long(argc, argv, "fl:u:g:vh", long_options, NULL)) != -1) + { + switch (opt) + { + case 'l': /* local-port */ + sss.lport = atoi(optarg); + break; + case 'f': /* foreground */ + sss.daemon = 0; + break; +#ifndef WIN32 + case 'u': /* unprivileged uid */ + { + userid = atoi(optarg); + break; + } + case 'g': /* unprivileged uid */ + { + groupid = atoi(optarg); + break; + } +#endif + case 'h': /* help */ + exit_help(argc, argv); + break; + case 'v': /* verbose */ + ++traceLevel; + break; + } + } + + } + +#if defined(N2N_HAVE_DAEMON) + if (sss.daemon) + { + useSyslog=1; /* traceEvent output now goes to syslog. */ + if ( -1 == daemon( 0, 0 ) ) + { + traceEvent( TRACE_ERROR, "Failed to become daemon." ); + exit(-5); + } + } +#endif /* #if defined(N2N_HAVE_DAEMON) */ + + traceEvent( TRACE_DEBUG, "traceLevel is %d", traceLevel); + + sss.sock = open_socket(sss.lport, 1 /*bind ANY*/ ); + if ( -1 == sss.sock ) + { + traceEvent( TRACE_ERROR, "Failed to open main socket. %s", strerror(errno) ); + exit(-2); + } + else + { + traceEvent( TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss.lport ); + } + + sss.mgmt_sock = open_socket(N2N_SN_MGMT_PORT, 0 /* bind LOOPBACK */ ); + if ( -1 == sss.mgmt_sock ) + { + traceEvent( TRACE_ERROR, "Failed to open management socket. %s", strerror(errno) ); + exit(-2); + } + else + { + traceEvent( TRACE_NORMAL, "supernode is listening on UDP %u (management)", N2N_SN_MGMT_PORT ); + } + +#ifndef WIN32 + if ( (userid != 0) || (groupid != 0 ) ) { + traceEvent(TRACE_NORMAL, "Interface up. Dropping privileges to uid=%d, gid=%d", + (signed int)userid, (signed int)groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + setreuid( userid, userid ); + setregid( groupid, groupid ); + } +#endif + traceEvent(TRACE_NORMAL, "supernode started"); + + return run_loop(&sss); +} + + +/** Long lived processing entry point. Split out from main to simply + * daemonisation on some platforms. */ +static int run_loop( n2n_sn_t * sss ) +{ + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; + int keep_running=1; + + sss->start_time = time(NULL); + + while(keep_running) + { + int rc; + ssize_t bread; + int max_sock; + fd_set socket_mask; + struct timeval wait_time; + time_t now=0; + + FD_ZERO(&socket_mask); + max_sock = MAX(sss->sock, sss->mgmt_sock); + + FD_SET(sss->sock, &socket_mask); + FD_SET(sss->mgmt_sock, &socket_mask); + + wait_time.tv_sec = 10; wait_time.tv_usec = 0; + rc = select(max_sock+1, &socket_mask, NULL, NULL, &wait_time); + + now = time(NULL); + + if(rc > 0) + { + if (FD_ISSET(sss->sock, &socket_mask)) + { + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom( sss->sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if ( bread < 0 ) /* For UDP bread of zero just means no data (unlike TCP). */ + { + /* The fd is no good now. Maybe we lost our interface. */ + traceEvent( TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno) ); + keep_running=0; + break; + } + + /* We have a datagram to process */ + if ( bread > 0 ) + { + /* And the datagram has data (not just a header) */ + process_udp( sss, &sender_sock, pktbuf, bread, now ); + } + } + + if (FD_ISSET(sss->mgmt_sock, &socket_mask)) + { + struct sockaddr_in sender_sock; + size_t i; + + i = sizeof(sender_sock); + bread = recvfrom( sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if ( bread <= 0 ) + { + traceEvent( TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno) ); + keep_running=0; + break; + } + + /* We have a datagram to process */ + process_mgmt( sss, &sender_sock, pktbuf, bread, now ); + } + } + else + { + traceEvent( TRACE_DEBUG, "timeout" ); + } + if ((now - sss->last_purge) >= PURGE_REGISTRATION_FREQUENCY) { + hashed_purge_expired_registrations( sss->edges ); + sss->last_purge = now; + } + + } /* while */ + + deinit_sn( sss ); + + return 0; +} + diff --git a/bundles/n2n_meyerd/n2n_v2/supernode.1 b/bundles/n2n_meyerd/n2n_v2/supernode.1 new file mode 100644 index 00000000..26b1f70f --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/supernode.1 @@ -0,0 +1,43 @@ +.TH supernode 1 "Jan 3, 2009" "revision 3679" "USER COMMANDS" +.SH NAME +supernode \- n2n supernode daemon +.SH SYNOPSIS +.B supernode \-l [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Supernode is a node introduction registry, +broadcast conduit and packet relay node for the n2n system. On startup supernode +begins listening on the specified UDP port for node registrations, and other +packets to route. The supernode can service any number of communities and routes +packets only between members of the same community. The supernode does not hold +the community encryption key and so cannot snoop or inject packets into the +community. +.PP +Supernode can service a number of n2n communities concurrently. Traffic does not +cross between communities. +.PP +All logging goes to stdout. +.SH OPTIONS +.TP +\-l +listen on the given UDP port +.TP +\-v +use verbose logging +.TP +\-f +disable daemon mode (UNIX) and run in foreground. +.SH EXAMPLES +.TP +.B supernode -l 7654 -v +Start supernode listening on UDP port 7654 with verbose output. +.PP +.SH RESTART +When suprenode restarts it loses all registration information from associated +edge nodes. It can take up to five minutes for the edge nodes to re-register and +normal traffic flow to resume. +.SH EXIT STATUS +supernode is a daemon and any exit is an error +.SH AUTHOR +Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner +.SH SEE ALSO +ifconfig(8) edge(8) diff --git a/bundles/n2n_meyerd/n2n_v2/transform_aes.c b/bundles/n2n_meyerd/n2n_v2/transform_aes.c new file mode 100644 index 00000000..a8c49690 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/transform_aes.c @@ -0,0 +1,597 @@ +/* (c) 2009 Richard Andrews */ +/* Contributions from: + * - Jozef Kralik + */ + +#include "n2n.h" +#include "n2n_transforms.h" + +#if defined(N2N_HAVE_AES) + + +#include "openssl/aes.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_AES_NUM_SA 32 /* space for SAa */ + +#define N2N_AES_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_AES_IVEC_SIZE 32 /* Enough space for biggest AES ivec */ + +typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE]; + +struct sa_aes +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + AES_KEY enc_key; /* tx key */ + n2n_aes_ivec_t enc_ivec; /* tx CBC state */ + AES_KEY dec_key; /* tx key */ + n2n_aes_ivec_t dec_ivec; /* tx CBC state */ +}; + +typedef struct sa_aes sa_aes_t; + + +/** Aes transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for aes + * consists of the SA number and key material. + * + */ +struct transop_aes +{ + ssize_t tx_sa; + size_t num_sa; + sa_aes_t sa[N2N_AES_NUM_SA]; +}; + +typedef struct transop_aes transop_aes_t; + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t aes_choose_tx_sa( transop_aes_t * priv ) +{ + return priv->tx_sa; /* set in tick */ +} + +#define TRANSOP_AES_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_AES_NONCE_SIZE 4 +#define TRANSOP_AES_SA_SIZE 4 + + +#define AES256_KEY_BYTES (256/8) +#define AES192_KEY_BYTES (192/8) +#define AES128_KEY_BYTES (128/8) + +/* Return the best acceptable AES key size (in bytes) given an input keysize. + * + * The value returned will be one of AES128_KEY_BYTES, AES192_KEY_BYTES or + * AES256_KEY_BYTES. + */ +static size_t aes_best_keysize(size_t numBytes) +{ + if (numBytes >= AES256_KEY_BYTES ) + { + return AES256_KEY_BYTES; + } + else if (numBytes >= AES192_KEY_BYTES) + { + return AES192_KEY_BYTES; + } + else + { + return AES128_KEY_BYTES; + } +} + +/** The aes packet format consists of: + * + * - a 8-bit aes encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int len2=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_AES_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_AES_NONCE_SIZE + TRANSOP_AES_SA_SIZE + TRANSOP_AES_VER_SIZE) <= out_len ) + { + int len=-1; + size_t idx=0; + sa_aes_t * sa; + size_t tx_sa_num = 0; + + /* The transmit sa is periodically updated */ + tx_sa_num = aes_choose_tx_sa( priv ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_aes %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the aes format version. */ + encode_uint8( outbuf, &idx, N2N_AES_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = in_len + TRANSOP_AES_NONCE_SIZE; + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_AES_NONCE_SIZE, inbuf, in_len ); + + /* Need at least one encrypted byte at the end for the padding. */ + len2 = ( (len / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; /* Round up to next whole AES adding at least one byte. */ + assembly[ len2-1 ]=(len2-len); + traceEvent( TRACE_DEBUG, "padding = %u", assembly[ len2-1 ] ); + + memset( &(sa->enc_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + AES_cbc_encrypt( assembly, /* source */ + outbuf + TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE, /* dest */ + len2, /* enc size */ + &(sa->enc_key), sa->enc_ivec, 1 /* encrypt */ ); + + len2 += TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_aes outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_aes inbuf too big to encrypt." ); + } + + return len2; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t aes_find_sa( const transop_aes_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_aes_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/** The aes packet format consists of: + * + * - a 8-bit aes encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int len=0; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - (TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE)) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE + TRANSOP_AES_NONCE_SIZE) ) /* Has at least version, SA and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t aes_enc_ver=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &aes_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_AES_TRANSFORM_VERSION == aes_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = aes_find_sa(priv, sa_rx); + if ( sa_idx >= 0 ) + { + sa_aes_t * sa = &(priv->sa[sa_idx]); + + traceEvent( TRACE_DEBUG, "decode_aes %lu with SA %lu.", in_len, sa_rx, sa->sa_id ); + + len = (in_len - (TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE)); + + if ( 0 == (len % AES_BLOCK_SIZE ) ) + { + uint8_t padding; + + memset( &(sa->dec_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + AES_cbc_encrypt( (inbuf + TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE), + assembly, /* destination */ + len, + &(sa->dec_key), + sa->dec_ivec, 0 /* decrypt */ ); + + /* last byte is how much was padding: max value should be + * AES_BLOCKSIZE-1 */ + padding = assembly[ len-1 ] & 0xff; + + if ( len >= (padding + TRANSOP_AES_NONCE_SIZE)) + { + /* strictly speaking for this to be an ethernet packet + * it is going to need to be even bigger; but this is + * enough to prevent segfaults. */ + traceEvent( TRACE_DEBUG, "padding = %u", padding ); + len -= padding; + + len -= TRANSOP_AES_NONCE_SIZE; /* size of ethernet packet */ + + /* Step over 4-byte random nonce value */ + memcpy( outbuf, + assembly + TRANSOP_AES_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_WARNING, "UDP payload decryption failed." ); + } + } + else + { + traceEvent( TRACE_WARNING, "Encrypted length %d is not a multiple of AES_BLOCK_SIZE (%d)", len, AES_BLOCK_SIZE ); + len = 0; + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes unsupported aes version %u.", aes_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_aes inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_AES_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; + const char * sep = index( op, '_' ); + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + memset( keybuf, 0, N2N_MAX_KEYSIZE ); + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + /* pstat is number of bytes read into keybuf. */ + sa_aes_t * sa = &(priv->sa[priv->num_sa]); + size_t aes_keysize_bytes; + size_t aes_keysize_bits; + + /* Clear out any old possibly longer key matter. */ + memset( &(sa->enc_key), 0, sizeof(AES_KEY) ); + memset( &(sa->dec_key), 0, sizeof(AES_KEY) ); + + memset( &(sa->enc_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + memset( &(sa->dec_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + + aes_keysize_bytes = aes_best_keysize(pstat); + aes_keysize_bits = 8 * aes_keysize_bytes; + + /* Use N2N_MAX_KEYSIZE because the AES key needs to be of fixed + * size. If fewer bits specified then the rest will be + * zeroes. AES acceptable key sizes are 128, 192 and 256 + * bits. */ + AES_set_encrypt_key( keybuf, aes_keysize_bits, &(sa->enc_key)); + AES_set_decrypt_key( keybuf, aes_keysize_bits, &(sa->dec_key)); + /* Leave ivecs set to all zeroes */ + + traceEvent( TRACE_DEBUG, "transop_addspec_aes sa_id=%u, %u bits data=%s.\n", + priv->sa[priv->num_sa].sa_id, aes_keysize_bits, sep+1); + + ++(priv->num_sa); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_aes tick num_sa=%u now=%lu", priv->num_sa, now ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_aes choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_aes tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_aes no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_AESCBC; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) malloc( sizeof(transop_aes_t) ); + + if ( NULL != priv ) + { + size_t i; + sa_aes_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + memset( &(sa->enc_key), 0, sizeof(AES_KEY) ); + memset( &(sa->enc_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + memset( &(sa->dec_key), 0, sizeof(AES_KEY) ); + memset( &(sa->dec_ivec), 0, sizeof(N2N_AES_IVEC_SIZE) ); + } + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + +#else /* #if defined(N2N_HAVE_AES) */ + +struct transop_aes +{ + ssize_t tx_sa; +}; + +typedef struct transop_aes transop_aes_t; + + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + + if ( priv ) + { + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + traceEvent( TRACE_DEBUG, "transop_addspec_aes AES not built into edge.\n"); + + return -1; +} + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + return r; +} + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) malloc( sizeof(transop_aes_t) ); + + if ( NULL != priv ) + { + /* install the private structure. */ + ttt->priv = priv; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + +#endif /* #if defined(N2N_HAVE_AES) */ + diff --git a/bundles/n2n_meyerd/n2n_v2/transform_null.c b/bundles/n2n_meyerd/n2n_v2/transform_null.c new file mode 100644 index 00000000..b486989d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/transform_null.c @@ -0,0 +1,84 @@ +/* (c) 2009 Richard Andrews */ + +#include "n2n.h" +#include "n2n_transforms.h" + +static int transop_deinit_null( n2n_trans_op_t * arg ) +{ + /* nothing to deallocate, nothing to release. */ + return 0; +} + +static int transop_encode_null( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int retval = -1; + + traceEvent( TRACE_DEBUG, "encode_null %lu", in_len ); + if ( out_len >= in_len ) + { + memcpy( outbuf, inbuf, in_len ); + retval = in_len; + } + else + { + traceEvent( TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len ); + } + + return retval; +} + +static int transop_decode_null( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int retval = -1; + + traceEvent( TRACE_DEBUG, "decode_null %lu", in_len ); + if ( out_len >= in_len ) + { + memcpy( outbuf, inbuf, in_len ); + retval = in_len; + } + else + { + traceEvent( TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len ); + } + + return retval; +} + +static int transop_addspec_null( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + return 0; +} + +static n2n_tostat_t transop_tick_null( n2n_trans_op_t * arg, time_t now ) +{ + n2n_tostat_t r; + + r.can_tx=1; + r.tx_spec.t = N2N_TRANSFORM_ID_NULL; + r.tx_spec.valid_from = 0; + r.tx_spec.valid_until = (time_t)(-1); + r.tx_spec.opaque_size=0; + + return r; +} + +void transop_null_init( n2n_trans_op_t * ttt ) +{ + memset(ttt, 0, sizeof(n2n_trans_op_t) ); + + ttt->transform_id = N2N_TRANSFORM_ID_NULL; + ttt->deinit = transop_deinit_null; + ttt->addspec = transop_addspec_null; + ttt->tick = transop_tick_null; + ttt->fwd = transop_encode_null; + ttt->rev = transop_decode_null; +} diff --git a/bundles/n2n_meyerd/n2n_v2/transform_tf.c b/bundles/n2n_meyerd/n2n_v2/transform_tf.c new file mode 100644 index 00000000..93273179 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/transform_tf.c @@ -0,0 +1,491 @@ +/* (c) 2009 Richard Andrews */ + +#include "n2n.h" +#include "n2n_transforms.h" +#include "twofish.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_TWOFISH_NUM_SA 32 /* space for SAa */ + +#define N2N_TWOFISH_TRANSFORM_VERSION 1 /* version of the transform encoding */ + +struct sa_twofish +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + TWOFISH * enc_tf; /* tx state */ + TWOFISH * dec_tf; /* rx state */ +}; + +typedef struct sa_twofish sa_twofish_t; + + +/** Twofish transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for twofish + * consists of the SA number and key material. + * + */ +struct transop_tf +{ + ssize_t tx_sa; + size_t num_sa; + sa_twofish_t sa[N2N_TWOFISH_NUM_SA]; +}; + +typedef struct transop_tf transop_tf_t; + +static int transop_deinit_twofish( n2n_trans_op_t * arg ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + TwoFishDestroy(sa->enc_tf); /* deallocate TWOFISH */ + sa->enc_tf=NULL; + + TwoFishDestroy(sa->dec_tf); /* deallocate TWOFISH */ + sa->dec_tf=NULL; + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t tf_choose_tx_sa( transop_tf_t * priv ) +{ + return priv->tx_sa; /* set in tick */ +} + +#define TRANSOP_TF_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_TF_NONCE_SIZE 4 +#define TRANSOP_TF_SA_SIZE 4 + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int len=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) + { + size_t idx=0; + sa_twofish_t * sa; + size_t tx_sa_num = 0; + + /* The transmit sa is periodically updated */ + tx_sa_num = tf_choose_tx_sa( priv ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_twofish %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the twofish format version. */ + encode_uint8( outbuf, &idx, N2N_TWOFISH_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len ); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = TwoFishEncryptRaw( assembly, /* source */ + outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE, + in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */ + sa->enc_tf); + if ( len > 0 ) + { + len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish encryption failed." ); + } + + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." ); + } + + return len; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t twofish_find_sa( const transop_tf_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_twofish_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_decode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + int len=0; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_NONCE_SIZE) ) /* Has at least version, SA and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t tf_enc_ver=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &tf_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_TWOFISH_TRANSFORM_VERSION == tf_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = twofish_find_sa(priv, sa_rx); + if ( sa_idx >= 0 ) + { + sa_twofish_t * sa = &(priv->sa[sa_idx]); + + traceEvent( TRACE_DEBUG, "decode_twofish %lu with SA %lu.", in_len, sa_rx, sa->sa_id ); + + len = TwoFishDecryptRaw( (void *)(inbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE), + assembly, /* destination */ + (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)), + sa->dec_tf); + + if ( len > 0 ) + { + /* Step over 4-byte random nonce value */ + len -= TRANSOP_TF_NONCE_SIZE; /* size of ethernet packet */ + + memcpy( outbuf, + assembly + TRANSOP_TF_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish decryption failed." ); + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish unsupported twofish version %u.", tf_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +static int transop_addspec_twofish( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_TWOFISH_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; +#ifdef __ANDROID_NDK__ + const char *sep = strchr(op, '_'); +#else + const char * sep = index( op, '_' ); +#endif // __ANDROID_NDK__ + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + priv->sa[priv->num_sa].enc_tf = TwoFishInit( keybuf, pstat); + priv->sa[priv->num_sa].dec_tf = TwoFishInit( keybuf, pstat); + + traceEvent( TRACE_DEBUG, "transop_addspec_twofish sa_id=%u data=%s.\n", + priv->sa[priv->num_sa].sa_id, sep+1); + + ++(priv->num_sa); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_twofish( n2n_trans_op_t * arg, time_t now ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_tf tick num_sa=%u", priv->num_sa ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_tf choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_tf tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_tf no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_TWOFISH; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + + +int transop_twofish_setup( n2n_trans_op_t * ttt, + n2n_sa_t sa_num, + uint8_t * encrypt_pwd, + uint32_t encrypt_pwd_len ) +{ + int retval = 1; + transop_tf_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_twofish( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); + + if ( NULL != priv ) + { + size_t i; + sa_twofish_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + sa->enc_tf=NULL; + sa->dec_tf=NULL; + } + + priv->num_sa=1; /* There is one SA in the array. */ + priv->tx_sa=0; + sa = &(priv->sa[priv->tx_sa]); + sa->sa_id=sa_num; + sa->spec.valid_until = 0x7fffffff; + + /* This is a preshared key setup. Both Tx and Rx are using the same security association. */ + + sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + + if ( (sa->enc_tf) && (sa->dec_tf) ) + { + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + ttt->deinit = transop_deinit_twofish; + ttt->addspec = transop_addspec_twofish; + ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */ + ttt->fwd = transop_encode_twofish; + ttt->rev = transop_decode_twofish; + + retval = 0; + } + else + { + traceEvent( TRACE_ERROR, "TwoFishInit failed" ); + } + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); + } + + return retval; +} + +int transop_twofish_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_tf_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_twofish( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); + + if ( NULL != priv ) + { + size_t i; + sa_twofish_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + ttt->addspec = transop_addspec_twofish; + ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_twofish; + ttt->fwd = transop_encode_twofish; + ttt->rev = transop_decode_twofish; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + sa->enc_tf=NULL; + sa->dec_tf=NULL; + } + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); + } + + return retval; +} diff --git a/bundles/n2n_meyerd/n2n_v2/tuntap_freebsd.c b/bundles/n2n_meyerd/n2n_v2/tuntap_freebsd.c new file mode 100644 index 00000000..7d9096a3 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/tuntap_freebsd.c @@ -0,0 +1,132 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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 see see + */ + +#include "n2n.h" + +#ifdef __FreeBSD__ + +void tun_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_FREEBSD_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tun_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* #ifdef __FreeBSD__ */ diff --git a/bundles/n2n_meyerd/n2n_v2/tuntap_linux.c b/bundles/n2n_meyerd/n2n_v2/tuntap_linux.c new file mode 100644 index 00000000..be3cbb97 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/tuntap_linux.c @@ -0,0 +1,164 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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, see +*/ + +#include "n2n.h" + +#ifdef __linux__ + +static void read_mac(char *ifname, n2n_mac_t mac_addr) { + int _sock, res; + struct ifreq ifr; + macstr_t mac_addr_buf; + + memset (&ifr,0,sizeof(struct ifreq)); + + /* Dummy socket, just to make ioctls with */ + _sock=socket(PF_INET, SOCK_DGRAM, 0); + strcpy(ifr.ifr_name, ifname); + res = ioctl(_sock,SIOCGIFHWADDR,&ifr); + if (res<0) { + perror ("Get hw addr"); + } else + memcpy(mac_addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6); + + traceEvent(TRACE_NORMAL, "Interface %s has MAC %s", + ifname, + macaddr_str(mac_addr_buf, mac_addr )); + close(_sock); +} + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver then uses ifconfig + * to configure address/mask and MTU. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + char *tuntap_device = "/dev/net/tun"; +#define N2N_LINUX_SYSTEMCMD_SIZE 128 + char buf[N2N_LINUX_SYSTEMCMD_SIZE]; + struct ifreq ifr; + int rc; + + device->fd = open(tuntap_device, O_RDWR); + if(device->fd < 0) { + printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), errno); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); + + if(rc < 0) { + traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + + /* Store the device name for later reuse */ + strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) ); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s hw ether %s", + ifr.ifr_name, device_mac ); + system(buf); + traceEvent(TRACE_INFO, "Setting MAC: %s", buf); + } + + if ( 0 == strncmp( "dhcp", address_mode, 5 ) ) + { + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s mtu %d up", + ifr.ifr_name, device_ip, mtu); + } + else + { + snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", + ifr.ifr_name, device_ip, device_mask, mtu); + } + + system(buf); + traceEvent(TRACE_INFO, "Bringing up: %s", buf); + + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + read_mac(dev, device->mac_addr); + return(device->fd); +} + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ + FILE * fp=NULL; + char buf[N2N_LINUX_SYSTEMCMD_SIZE]; + + /* Would rather have a more direct way to get the inet address but a netlink + * socket is overkill and probably less portable than ifconfig and sed. */ + + /* If the interface has no address (0.0.0.0) there will be no inet addr + * line and the returned string will be empty. */ + snprintf( buf, sizeof(buf), "/sbin/ifconfig %s | /bin/sed -e '/inet addr:/!d' -e 's/^.*inet addr://' -e 's/ .*$//'", + tuntap->dev_name ); + fp=popen(buf, "r"); + if (fp ) + { + memset(buf,0,N2N_LINUX_SYSTEMCMD_SIZE); /* make sure buf is NULL terminated. */ + fread(buf, 1, 15, fp); + fclose(fp); + fp=NULL; + + traceEvent(TRACE_INFO, "ifconfig address = %s", buf); + + tuntap->ip_addr = inet_addr(buf); + } +} + + +#endif /* #ifdef __linux__ */ diff --git a/bundles/n2n_meyerd/n2n_v2/tuntap_netbsd.c b/bundles/n2n_meyerd/n2n_v2/tuntap_netbsd.c new file mode 100644 index 00000000..011f7dfb --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/tuntap_netbsd.c @@ -0,0 +1,146 @@ +/* + * (C) 2007-09 - Luca Deri + * (C) 2009 - Alaric Snell-Pym + * + * 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 3 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 see see + */ + +#include "n2n.h" + +#ifdef __NetBSD__ + +#include +#include +#include + +void tun_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_NETBSD_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; + struct ifreq req; + + if (dev) { + snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); + device->fd = open(tap_device, O_RDWR); + snprintf(tap_device, sizeof(tap_device), "%s", dev); + } + else { + device->fd = open("/dev/tap", O_RDWR); + if(device->fd >= 0) { + if (ioctl(device->fd, TAPGIFNAME, &req) == -1) { + traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); + close(device->fd); + return(-1); + } + else { + snprintf(tap_device, sizeof(tap_device), req.ifr_name); + } + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); + return(-1); + } else { + char buf[256]; + FILE *fd; + + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig %s link %s active", + tap_device, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s mtu %d up", + tap_device, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", + tap_device, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig %s |grep address|cut -c 11-28", tap_device); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tun_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address", tap_device); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* #ifdef __NetBSD__ */ diff --git a/bundles/n2n_meyerd/n2n_v2/tuntap_osx.c b/bundles/n2n_meyerd/n2n_v2/tuntap_osx.c new file mode 100644 index 00000000..d8c7c2be --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/tuntap_osx.c @@ -0,0 +1,132 @@ +/* + * (C) 2007-09 - Luca Deri + * + * 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 3 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 see see + */ + +#include "n2n.h" + +#ifdef _DARWIN_ + +void tuntap_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_OSX_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_OSX_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* _DARWIN_ */ diff --git a/bundles/n2n_meyerd/n2n_v2/twofish.c b/bundles/n2n_meyerd/n2n_v2/twofish.c new file mode 100644 index 00000000..57661d74 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/twofish.c @@ -0,0 +1,1031 @@ +/* $Id: twofish.c,v 2.0 2002/08/11 22:32:25 fknobbe Exp $ + * + * + * Copyright (C) 1997-2000 The Cryptix Foundation Limited. + * Copyright (C) 2000 Farm9. + * Copyright (C) 2001 Frank Knobbe. + * All rights reserved. + * + * For Cryptix code: + * Use, modification, copying and distribution of this software is subject + * the terms and conditions of the Cryptix General Licence. You should have + * received a copy of the Cryptix General Licence along with this library; + * if not, you can download a copy from http://www.cryptix.org/ . + * + * For Farm9: + * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and + * ciphertext stealing technique, added AsciiTwofish class for easy encryption + * decryption of text strings + * + * Frank Knobbe : + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_SOURCE__ +#define __TWOFISH_LIBRARY_SOURCE__ + +#include +#include +#include +#include +#include +#include "twofish.h" + + +bool TwoFish_srand=TRUE; /* if TRUE, first call of TwoFishInit will seed rand(); */ +/* of TwoFishInit */ + +/* Fixed 8x8 permutation S-boxes */ +static const uint8_t TwoFish_P[2][256] = + { + { /* p0 */ + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0 + }, + { /* p1 */ + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 + } + }; + +static bool TwoFish_MDSready=FALSE; +static uint32_t TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */ + + +#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0)) +#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0)) + +#define TwoFish_Mx_1(x) ((uint32_t)(x)) /* force result to dword so << will work */ +#define TwoFish_Mx_X(x) ((uint32_t)((x)^TwoFish_LFSR2(x))) /* 5B */ +#define TwoFish_Mx_Y(x) ((uint32_t)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */ +#define TwoFish_RS_rem(x) { uint8_t b=(uint8_t)(x>>24); uint32_t g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; uint32_t g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; } + +/*#define TwoFish__b(x,N) (((uint8_t *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */ + +#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of uint32_t */ +#define TwoFish_b1(x) TwoFish__b(x,1) +#define TwoFish_b2(x) TwoFish__b(x,2) +#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of uint32_t */ + +uint8_t TwoFish__b(uint32_t x,int n) +{ n&=3; + while(n-->0) + x>>=8; + return (uint8_t)x; +} + + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ + +TWOFISH *TwoFishInit(const uint8_t *userkey, uint32_t keysize) +{ TWOFISH *tfdata; + int i,x,m; + uint8_t tkey[TwoFish_KEY_LENGTH+40]; + + memset( tkey, 0, TwoFish_KEY_LENGTH+40 ); + tfdata=(TWOFISH *)malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */ + if(tfdata!=NULL) + { + + /* Changes here prevented a dangerous random key segment for keys of length < TwoFish_KEY_LENGTH */ + if(keysize > 0) + { + memcpy( tkey, userkey, keysize ); /* The rest will be zeros */ + } + else + { + memcpy( tkey, TwoFish_DEFAULT_PW, TwoFish_DEFAULT_PW_LEN ); /* if no key defined, use default password */ + } + + /* This loop is awful - surely a loop on memcpy() would be clearer and more efficient */ + for(i=0,x=0,m=keysize;ikey[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */ + if(x==m) + x=0; + } + + if(!TwoFish_MDSready) + _TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */ + _TwoFish_MakeSubKeys(tfdata); /* generate subkeys */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC */ + tfdata->output=NULL; /* nothing to output yet */ + tfdata->dontflush=FALSE; /* reset decrypt skip block flag */ + if(TwoFish_srand) + { + TwoFish_srand=FALSE; + /* REVISIT: BbMaj7 : Should choose something with less predictability + * particularly for embedded targets with no real-time clock. */ + srand((unsigned int)time(NULL)); + } + } + return tfdata; /* return the data pointer */ +} + + +void TwoFishDestroy(TWOFISH *tfdata) +{ if(tfdata!=NULL) + free(tfdata); +} + + +/* en/decryption with CBC mode */ +uint32_t _TwoFish_CryptRawCBC(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ uint32_t rl; + + rl=len; /* remember how much data to crypt. */ + while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */ + { _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */ + in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */ + out+=TwoFish_BLOCK_SIZE; + len-=TwoFish_BLOCK_SIZE; + } + if(len>0) /* if we have less than a block left... */ + _TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */ + if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */ + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */ + /* ...remaining bytes of the buffer */ + return rl; +} + +/* en/decryption on one block only */ +uint32_t _TwoFish_CryptRaw16(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ /* qBlockPlain already zero'ed through ResetCBC */ + memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */ + _TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */ + memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */ + return TwoFish_BLOCK_SIZE; +} + +/* en/decryption without reset of CBC and output assignment */ +uint32_t _TwoFish_CryptRaw(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ + if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */ + { if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */ + return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */ + else + return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */ + } + return 0; +} + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +uint32_t TwoFishEncryptRaw(uint8_t *in, + uint8_t *out, + uint32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */ +} + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +uint32_t TwoFishDecryptRaw(uint8_t *in, + uint8_t *out, + uint32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */ +} + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishFree(TWOFISH *tfdata) +{ if(tfdata->output!=NULL) /* if a valid buffer is present... */ + { free(tfdata->output); /* ...then we free it for you... */ + tfdata->output=NULL; /* ...and mark as such. */ + } +} + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishSetOutput(uint8_t *outp,TWOFISH *tfdata) +{ tfdata->output=outp; /* (do we really need a function for this?) */ +} + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer that would be required + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ + +void *TwoFishAlloc(uint32_t len,bool binhex,bool decrypt,TWOFISH *tfdata) +{ + /* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */ + if(decrypt) /* if decrypting... */ + { if(binhex) /* ...and input is binhex encoded... */ + len/=2; /* ...use half as much for output. */ + len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */ + } + else + { len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */ + if(binhex) + len*=2; /* ...and doubled if output is to be binhexed. */ + } + tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */ + + return tfdata->output; /* ...and return to caller. */ +} + +/* bin2hex and hex2bin conversion */ +void _TwoFish_BinHex(uint8_t *buf,uint32_t len,bool bintohex) +{ uint8_t *pi,*po,c; + + if(bintohex) + { for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */ + { c=*pi; /* grab value. */ + c&=15; /* use lower 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po--=c; /* set the lower nibble. */ + c=*pi; /* grab value again. */ + c>>=4; /* right shift 4 bits. */ + c&=15; /* make sure we only have 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po=c; /* set the higher nibble. */ + } /* and keep going. */ + } + else + { for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */ + { c=tolower(*pi++)-'0'; /* grab higher nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po=c<<4; /* left shit 4 bits. */ + c=tolower(*pi)-'0'; /* grab lower nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po|=c; /* and add to value. */ + } + } +} + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +uint32_t TwoFishEncrypt(uint8_t *in, + uint8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ uint32_t ilen,olen; + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { tfdata->output=*out; /* set output buffer. */ + tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */ + tfdata->header.length[0]= (uint8_t)(ilen); + tfdata->header.length[1]= (uint8_t)(ilen>>8); + tfdata->header.length[2]= (uint8_t)(ilen>>16); + tfdata->header.length[3]= (uint8_t)(ilen>>24); + memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */ + olen=TwoFish_BLOCK_SIZE; /* set output counter. */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag */ + _TwoFish_BlockCrypt((uint8_t *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */ + olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */ + if(binhex) /* if binhex... */ + { _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */ + olen*=2; /* ...and size twice as large. */ + } + tfdata->output=*out; + return olen; + } + } + return 0; +} + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +uint32_t TwoFishDecrypt(uint8_t *in, + uint8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ uint32_t ilen,elen,olen; + const uint8_t cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC; + uint8_t *tbuf; + + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { if(binhex) /* if binhex... */ + { _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */ + ilen/=2; /* ...and size half as much. */ + } + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */ + + tbuf=(uint8_t *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */ + if(tbuf==NULL) + return 0; + tfdata->output=tbuf; /* set output to temp buffer. */ + + olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */ + memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */ + tfdata->output=*out; + for(elen=0;elenheader.magic[elen]!=cmagic[elen]) + break; + if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */ + { elen=(tfdata->header.length[0]) | + (tfdata->header.length[1])<<8 | + (tfdata->header.length[2])<<16 | + (tfdata->header.length[3])<<24; /* .. we know how much to expect. */ + if(elen>olen) /* adjust if necessary. */ + elen=olen; + memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */ + free(tbuf); + return elen; + } + free(tbuf); + } + } + return 0; +} + +void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */ +{ uint32_t m1[2]; + uint32_t mX[2]; + uint32_t mY[2]; + uint32_t i, j; + + for (i = 0; i < 256; i++) + { j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */ + m1[0] = j; + mX[0] = TwoFish_Mx_X( j ) & 0xFF; + mY[0] = TwoFish_Mx_Y( j ) & 0xFF; + + j = TwoFish_P[1][i] & 0xFF; + m1[1] = j; + mX[1] = TwoFish_Mx_X( j ) & 0xFF; + mY[1] = TwoFish_Mx_Y( j ) & 0xFF; + + TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */ + mX[TwoFish_P_00] << 8 | + mY[TwoFish_P_00] << 16 | + mY[TwoFish_P_00] << 24; + TwoFish_MDS[1][i] = mY[TwoFish_P_10] | + mY[TwoFish_P_10] << 8 | + mX[TwoFish_P_10] << 16 | + m1[TwoFish_P_10] << 24; + TwoFish_MDS[2][i] = mX[TwoFish_P_20] | + mY[TwoFish_P_20] << 8 | + m1[TwoFish_P_20] << 16 | + mY[TwoFish_P_20] << 24; + TwoFish_MDS[3][i] = mX[TwoFish_P_30] | + m1[TwoFish_P_30] << 8 | + mY[TwoFish_P_30] << 16 | + mX[TwoFish_P_30] << 24; + } + TwoFish_MDSready=TRUE; +} + + +void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */ +{ uint32_t k64Cnt = TwoFish_KEY_LENGTH / 8; + uint32_t k32e[4]; /* even 32-bit entities */ + uint32_t k32o[4]; /* odd 32-bit entities */ + uint32_t sBoxKey[4]; + uint32_t offset,i,j; + uint32_t A, B, q=0; + uint32_t k0,k1,k2,k3; + uint32_t b0,b1,b2,b3; + + /* split user key material into even and odd 32-bit entities and */ + /* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */ + + + for (offset=0,i=0,j=k64Cnt-1;i<4 && offsetkey[offset++]; + k32e[i]|= tfdata->key[offset++]<<8; + k32e[i]|= tfdata->key[offset++]<<16; + k32e[i]|= tfdata->key[offset++]<<24; + k32o[i] = tfdata->key[offset++]; + k32o[i]|= tfdata->key[offset++]<<8; + k32o[i]|= tfdata->key[offset++]<<16; + k32o[i]|= tfdata->key[offset++]<<24; + sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */ + } + + /* compute the round decryption subkeys for PHT. these same subkeys */ + /* will be used in encryption but will be applied in reverse order. */ + i=0; + while(i < TwoFish_TOTAL_SUBKEYS) + { A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */ + q += TwoFish_SK_BUMP; + + B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */ + q += TwoFish_SK_BUMP; + + B = B << 8 | B >> 24; + + A += B; + tfdata->subKeys[i++] = A; /* combine with a PHT */ + + A += B; + tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL); + } + + /* fully expand the table for speed */ + k0 = sBoxKey[0]; + k1 = sBoxKey[1]; + k2 = sBoxKey[2]; + k3 = sBoxKey[3]; + + for (i = 0; i < 256; i++) + { b0 = b1 = b2 = b3 = i; + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)]; + tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)]; + tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)]; + tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3); + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys */ + tfdata->sBox[ 2*i ]= + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^ + TwoFish_b0(k1)]) ^ TwoFish_b0(k0)]; + + tfdata->sBox[ 2*i+1]= + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^ + TwoFish_b1(k1)]) ^ TwoFish_b1(k0)]; + + tfdata->sBox[0x200+2*i ]= + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^ + TwoFish_b2(k1)]) ^ TwoFish_b2(k0)]; + + tfdata->sBox[0x200+2*i+1]= + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^ + TwoFish_b3(k1)]) ^ TwoFish_b3(k0)]; + } + } +} + + +/** + * Encrypt or decrypt exactly one block of plaintext in CBC mode. + * Use "ciphertext stealing" technique described on pg. 196 + * of "Applied Cryptography" to encrypt the final partial + * (i.e. <16 byte) block if necessary. + * + * jojo: the "ciphertext stealing" requires we read ahead and have + * special handling for the last two blocks. Because of this, the + * output from the TwoFish algorithm is handled internally here. + * It would be better to have a higher level handle this as well as + * CBC mode. Unfortunately, I've mixed the two together, which is + * pretty crappy... The Java version separates these out correctly. + * + * fknobbe: I have reduced the CBC mode to work on memory buffer only. + * Higher routines should use an intermediate buffer and handle + * their output seperately (mainly so the data can be flushed + * in one chunk, not seperate 16 byte blocks...) + * + * @param in The plaintext. + * @param out The ciphertext + * @param size how much to encrypt + * @param tfdata: Pointer to the global data structure containing session keys. + * @return none + */ +void _TwoFish_BlockCrypt(uint8_t *in,uint8_t *out,uint32_t size,int decrypt,TWOFISH *tfdata) +{ uint8_t PnMinusOne[TwoFish_BLOCK_SIZE]; + uint8_t CnMinusOne[TwoFish_BLOCK_SIZE]; + uint8_t CBCplusCprime[TwoFish_BLOCK_SIZE]; + uint8_t Pn[TwoFish_BLOCK_SIZE]; + uint8_t *p,*pout; + uint32_t i; + + /* here is where we implement CBC mode and cipher block stealing */ + if(size==TwoFish_BLOCK_SIZE) + { /* if we are encrypting, CBC means we XOR the plain text block with the */ + /* previous cipher text block before encrypting */ + if(!decrypt && tfdata->qBlockDefined) + { for(p=in,i=0;iqBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */ + } + else + memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */ + + /* TwoFish block level encryption or decryption */ + _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); + + /* if we are decrypting, CBC means we XOR the result of the decryption */ + /* with the previous cipher text block to get the resulting plain text */ + if(decrypt && tfdata->qBlockDefined) + { for (p=out,i=0;iqBlockPlain[i]; + } + + /* save the input and output blocks, since CBC needs these for XOR */ + /* operations */ + _TwoFish_qBlockPush(Pn,out,tfdata); + } + else + { /* cipher block stealing, we are at Pn, */ + /* but since Cn-1 must now be replaced with CnC' */ + /* we pop it off, and recalculate Cn-1 */ + + if(decrypt) + { /* We are on an odd block, and had to do cipher block stealing, */ + /* so the PnMinusOne has to be derived differently. */ + + /* First we decrypt it into CBC and C' */ + _TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata); + + /* we then xor the first few bytes with the "in" bytes (Cn) */ + /* to recover Pn, which we put in out */ + for(p=in,pout=out,i=0;iprevCipher[i]; + + /* So at this point, out has PnMinusOne */ + _TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(out,size,tfdata); + } + else + { _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata); + memset(Pn,0,TwoFish_BLOCK_SIZE); + memcpy(Pn,in,size); + for(i=0;iqBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */ + } + tfdata->qBlockDefined=FALSE; + } +} + +void _TwoFish_qBlockPush(uint8_t *p,uint8_t *c,TWOFISH *tfdata) +{ if(tfdata->qBlockDefined) + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE); + tfdata->qBlockDefined=TRUE; +} + +void _TwoFish_qBlockPop(uint8_t *p,uint8_t *c,TWOFISH *tfdata) +{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE ); + memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE ); + tfdata->qBlockDefined=FALSE; +} + +/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */ +void _TwoFish_ResetCBC(TWOFISH *tfdata) +{ tfdata->qBlockDefined=FALSE; + memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE); +} + +void _TwoFish_FlushOutput(uint8_t *b,uint32_t len,TWOFISH *tfdata) +{ uint32_t i; + + for(i=0;idontflush;i++) + *tfdata->output++ = *b++; + tfdata->dontflush=FALSE; +} + +void _TwoFish_BlockCrypt16(uint8_t *in,uint8_t *out,bool decrypt,TWOFISH *tfdata) +{ uint32_t x0,x1,x2,x3; + uint32_t k,t0,t1,R; + + + x0=*in++; + x0|=(*in++ << 8 ); + x0|=(*in++ << 16); + x0|=(*in++ << 24); + x1=*in++; + x1|=(*in++ << 8 ); + x1|=(*in++ << 16); + x1|=(*in++ << 24); + x2=*in++; + x2|=(*in++ << 8 ); + x2|=(*in++ << 16); + x2|=(*in++ << 24); + x3=*in++; + x3|=(*in++ << 8 ); + x3|=(*in++ << 16); + x3|=(*in++ << 24); + + if(decrypt) + { x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */ + x1 ^= tfdata->subKeys[5]; + x2 ^= tfdata->subKeys[6]; + x3 ^= tfdata->subKeys[7]; + + k = 7+(TwoFish_ROUNDS*2); + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x3 = x3 >> 1 | x3 << 31; + x2 = x2 << 1 | x2 >> 31; + x2 ^= t0 + t1 + tfdata->subKeys[k--]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x1 = x1 >> 1 | x1 << 31; + x0 = x0 << 1 | x0 >> 31; + x0 ^= t0 + t1 + tfdata->subKeys[k--]; + } + + x2 ^= tfdata->subKeys[0]; + x3 ^= tfdata->subKeys[1]; + x0 ^= tfdata->subKeys[2]; + x1 ^= tfdata->subKeys[3]; + } + else + { x0 ^= tfdata->subKeys[0]; + x1 ^= tfdata->subKeys[1]; + x2 ^= tfdata->subKeys[2]; + x3 ^= tfdata->subKeys[3]; + + k = 8; + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x2 ^= t0 + t1 + tfdata->subKeys[k++]; + x2 = x2 >> 1 | x2 << 31; + x3 = x3 << 1 | x3 >> 31; + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x0 ^= t0 + t1 + tfdata->subKeys[k++]; + x0 = x0 >> 1 | x0 << 31; + x1 = x1 << 1 | x1 >> 31; + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + } + + x2 ^= tfdata->subKeys[4]; + x3 ^= tfdata->subKeys[5]; + x0 ^= tfdata->subKeys[6]; + x1 ^= tfdata->subKeys[7]; + } + + *out++ = (uint8_t)(x2 ); + *out++ = (uint8_t)(x2 >> 8); + *out++ = (uint8_t)(x2 >> 16); + *out++ = (uint8_t)(x2 >> 24); + + *out++ = (uint8_t)(x3 ); + *out++ = (uint8_t)(x3 >> 8); + *out++ = (uint8_t)(x3 >> 16); + *out++ = (uint8_t)(x3 >> 24); + + *out++ = (uint8_t)(x0 ); + *out++ = (uint8_t)(x0 >> 8); + *out++ = (uint8_t)(x0 >> 16); + *out++ = (uint8_t)(x0 >> 24); + + *out++ = (uint8_t)(x1 ); + *out++ = (uint8_t)(x1 >> 8); + *out++ = (uint8_t)(x1 >> 16); + *out++ = (uint8_t)(x1 >> 24); +} + +/** + * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box + * 32-bit entity from two key material 32-bit entities. + * + * @param k0 1st 32-bit entity. + * @param k1 2nd 32-bit entity. + * @return Remainder polynomial generated using RS code + */ +uint32_t _TwoFish_RS_MDS_Encode(uint32_t k0,uint32_t k1) +{ uint32_t i,r; + + for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */ + TwoFish_RS_rem(r); + r ^= k0; + for(i=0;i<4;i++) + TwoFish_RS_rem(r); + + return r; +} + +uint32_t _TwoFish_F32(uint32_t k64Cnt,uint32_t x,uint32_t *k32) +{ uint8_t b0,b1,b2,b3; + uint32_t k0,k1,k2,k3,result = 0; + + b0=TwoFish_b0(x); + b1=TwoFish_b1(x); + b2=TwoFish_b2(x); + b3=TwoFish_b3(x); + k0=k32[0]; + k1=k32[1]; + k2=k32[2]; + k3=k32[3]; + + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3); + + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys (optimize for this case) */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)]; + break; + } + return result; +} + +uint32_t _TwoFish_Fe320(uint32_t *lsBox,uint32_t x) +{ return lsBox[ TwoFish_b0(x)<<1 ]^ + lsBox[ ((TwoFish_b1(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b2(x)<<1) ]^ + lsBox[0x200+((TwoFish_b3(x)<<1)|1)]; +} + +uint32_t _TwoFish_Fe323(uint32_t *lsBox,uint32_t x) +{ return lsBox[ (TwoFish_b3(x)<<1) ]^ + lsBox[ ((TwoFish_b0(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b1(x)<<1) ]^ + lsBox[0x200+((TwoFish_b2(x)<<1)|1)]; +} + +uint32_t _TwoFish_Fe32(uint32_t *lsBox,uint32_t x,uint32_t R) +{ return lsBox[ 2*TwoFish__b(x,R ) ]^ + lsBox[ 2*TwoFish__b(x,R+1)+1]^ + lsBox[0x200+2*TwoFish__b(x,R+2) ]^ + lsBox[0x200+2*TwoFish__b(x,R+3)+1]; +} + + +#endif + +/* ******************************************* */ +#if defined TWOFISH_UNIT_TEST +#include + +#define TEST_DATA_SIZE 327 + +int main(int argc, char* argv[]) +{ + int i; + int n; + + char outbuf[4096]; + char * outp = outbuf; + + uint8_t key[] = { 0xfc, 0x77, 0x1a, 0xda, 0xaa }; + TWOFISH *tfa = TwoFishInit( key, 5 ); + TWOFISH *tfb = TwoFishInit( key, 5 ); + + uint8_t out[2048], out2[2048]; + uint8_t in[TEST_DATA_SIZE]; + + for ( i=0; i: + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_HEADER__ +#define __TWOFISH_LIBRARY_HEADER__ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !FALSE +#endif +#ifndef bool +#define bool int +#endif + +#ifdef WIN32 +#include "win32/n2n_win32.h" +#endif + +#ifndef _MSC_VER +/* Not shipped with Visual Studio (as stated by the stdint.h wikipedia page) */ +#include /* defines uintN_t types */ +#endif + +#ifdef __sun__ /* Should be HAVE_SYS_TYPES */ +/* The following are redefinitions if sys/types.h has been included too.*/ +typedef uint32_t uint32_t; +typedef uint8_t uint8_t; +#endif /* #ifdef __sun__ */ + +/* Constants */ + +#define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */ +#define TwoFish_DEFAULT_PW_LEN 32 +#define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */ + +enum +{ TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */ + /* User 256, other key sizes have not been tested. */ + /* (But should work. I substitutes as much as */ + /* I could with this define.) */ + TwoFish_ROUNDS = 16, + TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */ + TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */ + TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS, + TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8, + TwoFish_SK_BUMP = 0x01010101, + TwoFish_SK_ROTL = 9, + TwoFish_P_00 = 1, + TwoFish_P_01 = 0, + TwoFish_P_02 = 0, + TwoFish_P_03 = TwoFish_P_01 ^ 1, + TwoFish_P_04 = 1, + TwoFish_P_10 = 0, + TwoFish_P_11 = 0, + TwoFish_P_12 = 1, + TwoFish_P_13 = TwoFish_P_11 ^ 1, + TwoFish_P_14 = 0, + TwoFish_P_20 = 1, + TwoFish_P_21 = 1, + TwoFish_P_22 = 0, + TwoFish_P_23 = TwoFish_P_21 ^ 1, + TwoFish_P_24 = 0, + TwoFish_P_30 = 0, + TwoFish_P_31 = 1, + TwoFish_P_32 = 1, + TwoFish_P_33 = TwoFish_P_31 ^ 1, + TwoFish_P_34 = 1, + TwoFish_GF256_FDBK = 0x169, + TwoFish_GF256_FDBK_2 = 0x169 / 2, + TwoFish_GF256_FDBK_4 = 0x169 / 4, + TwoFish_RS_GF_FDBK = 0x14D, /* field generator */ + TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */ +}; + + +/* Global data structure for callers */ + +typedef struct +{ + uint32_t sBox[4 * 256]; /* Key dependent S-box */ + uint32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */ + uint8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */ + uint8_t *output; /* Pointer to output buffer */ + uint8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */ + uint8_t qBlockCrypt[TwoFish_BLOCK_SIZE]; + uint8_t prevCipher[TwoFish_BLOCK_SIZE]; + struct /* Header for crypt functions. Has to be at least one block long. */ + { uint32_t salt; /* Random salt in first block (will salt the rest through CBC) */ + uint8_t length[4]; /* The amount of data following the header */ + uint8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */ + } header; + bool qBlockDefined; + bool dontflush; +} TWOFISH; + +#ifndef __TWOFISH_LIBRARY_SOURCE__ + +extern bool TwoFish_srand; /* if set to TRUE (default), first call of TwoFishInit will seed rand(); */ + /* call of TwoFishInit */ +#endif + + +/**** Public Functions ****/ + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ +TWOFISH *TwoFishInit(const uint8_t *userkey, uint32_t keysize ); + + +/* TwoFish Destroy + * + * Nothing else but a free... + * + * Input: Pointer to the TwoFish structure. + * + */ +void TwoFishDestroy(TWOFISH *tfdata); + + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer as required. + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ +void *TwoFishAlloc(uint32_t len,bool binhex,bool decrypt,TWOFISH *tfdata); + + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishFree(TWOFISH *tfdata); + + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishSetOutput(uint8_t *outp,TWOFISH *tfdata); + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +uint32_t TwoFishEncryptRaw(uint8_t *in,uint8_t *out,uint32_t len,TWOFISH *tfdata); + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +uint32_t TwoFishDecryptRaw(uint8_t *in,uint8_t *out,uint32_t len,TWOFISH *tfdata); + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +uint32_t TwoFishEncrypt(uint8_t *in,uint8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +uint32_t TwoFishDecrypt(uint8_t *in,uint8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/**** Private Functions ****/ + +uint8_t TwoFish__b(uint32_t x,int n); +void _TwoFish_BinHex(uint8_t *buf,uint32_t len,bool bintohex); +uint32_t _TwoFish_CryptRawCBC(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_CryptRaw16(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_CryptRaw(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +void _TwoFish_PrecomputeMDSmatrix(void); +void _TwoFish_MakeSubKeys(TWOFISH *tfdata); +void _TwoFish_qBlockPush(uint8_t *p,uint8_t *c,TWOFISH *tfdata); +void _TwoFish_qBlockPop(uint8_t *p,uint8_t *c,TWOFISH *tfdata); +void _TwoFish_ResetCBC(TWOFISH *tfdata); +void _TwoFish_FlushOutput(uint8_t *b,uint32_t len,TWOFISH *tfdata); +void _TwoFish_BlockCrypt(uint8_t *in,uint8_t *out,uint32_t size,int decrypt,TWOFISH *tfdata); +void _TwoFish_BlockCrypt16(uint8_t *in,uint8_t *out,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_RS_MDS_Encode(uint32_t k0,uint32_t k1); +uint32_t _TwoFish_F32(uint32_t k64Cnt,uint32_t x,uint32_t *k32); +uint32_t _TwoFish_Fe320(uint32_t *lsBox,uint32_t x); +uint32_t _TwoFish_Fe323(uint32_t *lsBox,uint32_t x); +uint32_t _TwoFish_Fe32(uint32_t *lsBox,uint32_t x,uint32_t R); + + +#endif diff --git a/bundles/n2n_meyerd/n2n_v2/unix-scm.c b/bundles/n2n_meyerd/n2n_v2/unix-scm.c new file mode 100644 index 00000000..45350d30 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/unix-scm.c @@ -0,0 +1,52 @@ +/* + * unix-scm.c - unix stubs for service control manager functions + * + * Copyright (c) 2010 Hamish Coleman + * 2003 Benjamin Schweizer + * 1998 Stephen Early + * + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "scm.h" + +int SCM_Start(struct SCM_def *sd, int argc, char **argv) { + sd->mode=SVC_CONSOLE; + + int err; + + if (sd->init) { + err = sd->init(argc,argv); + if (err!=0) { + return SVC_FAIL; + } + } + + sd->main(argc,argv); + return SVC_OK; +} + +char *SCM_Install(struct SCM_def *sd,char *args) { + return NULL; +} + +int SCM_Remove(struct SCM_def *sd) { + return SVC_FAIL; +} + diff --git a/bundles/n2n_meyerd/n2n_v2/version.c b/bundles/n2n_meyerd/n2n_v2/version.c new file mode 100644 index 00000000..b58ca13a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/version.c @@ -0,0 +1,5 @@ +const char * n2n_sw_version = N2N_VERSION; +const char * n2n_sw_osName = N2N_OSNAME; +const char * n2n_sw_buildDate = __DATE__ " " __TIME__; +const char * n2n_mod_version = N2N_MODIFY_VERSION; +const char * n2n_mod_author = N2N_MODIFY_AUTHOR; diff --git a/bundles/n2n_meyerd/n2n_v2/win32/CMakeLists.txt b/bundles/n2n_meyerd/n2n_v2/win32/CMakeLists.txt new file mode 100644 index 00000000..12f3f988 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(n2n_win32 + getopt1.c + getopt.c + wintap.c + win-scm.c + n2n_win32.c) +target_link_libraries(n2n_win32 ws2_32) diff --git a/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.sln b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.sln new file mode 100644 index 00000000..95698872 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge", "n2n.vcproj", "{4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "supernode", "supernode.vcproj", "{BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.Build.0 = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.ActiveCfg = Release|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.Build.0 = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.ActiveCfg = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.Build.0 = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.ActiveCfg = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.suo b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.suo new file mode 100644 index 0000000000000000000000000000000000000000..aae212bdc7603fcc776941462dec540d87901d0e GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.vcproj b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.vcproj new file mode 100644 index 00000000..d130fdd1 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/n2n.vcproj @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/DotNet/supernode.vcproj b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/supernode.vcproj new file mode 100644 index 00000000..e6a9e0d1 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/DotNet/supernode.vcproj @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/getopt.c b/bundles/n2n_meyerd/n2n_v2/win32/getopt.c new file mode 100644 index 00000000..6bbb735a --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/getopt.c @@ -0,0 +1,1074 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include +#ifdef WIN32 +#include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT<_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +#ifndef DARWIN +char *optarg; +#endif + + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +#ifndef DARWIN +int optind = 1; +#endif + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +#ifndef DARWIN +#ifdef WIN32 +int opterr = 0; +#else +int opterr = 1; +#endif +#endif + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ +#ifndef DARWIN +int optopt = '?'; +#endif + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +#ifndef WIN32 +# if HAVE_STRING_H +# include +# else +# include +# endif +#endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt____ (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/getopt.h b/bundles/n2n_meyerd/n2n_v2/win32/getopt.h new file mode 100644 index 00000000..b0147e9d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/bundles/n2n_meyerd/n2n_v2/win32/getopt1.c b/bundles/n2n_meyerd/n2n_v2/win32/getopt1.c new file mode 100644 index 00000000..3d264f2d --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/getopt1.c @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.c b/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.c new file mode 100644 index 00000000..681a9523 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.c @@ -0,0 +1,19 @@ +/* + * win32 compile fix 05/01/2011 Dominik Meyer + */ + +#include "n2n_win32.h" + +int gettimeofday (struct timeval *tv, void* tz) +{ + union { + long long ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } now; + + GetSystemTimeAsFileTime (&now.ft); + tv->tv_usec = (long) ((now.ns100 / 10LL) % 1000000LL); + tv->tv_sec = (long) ((now.ns100 - 116444736000000000LL) / 10000000LL); + return (0); +}; + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.h b/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.h new file mode 100644 index 00000000..1cc86fd6 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/n2n_win32.h @@ -0,0 +1,117 @@ +/* + + (C) 2007-09 - Luca Deri + +*/ + +#ifndef _N2N_WIN32_H_ +#define _N2N_WIN32_H_ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__MINGW32__) +/* should be defined here and before winsock gets included */ +#define _WIN32_WINNT 0x501 //Otherwise the linker doesnt find getaddrinfo +#include +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif /* #if defined(__MINGW32__) */ + +#include +#include +#include + + +#include "wintap.h" + +#ifdef _MSC_VER +#include "getopt.h" + +/* Other Win environments are expected to support stdint.h */ + +/* stdint.h typedefs (C99) (not present in Visual Studio) */ +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* sys/types.h typedefs (not present in Visual Studio) */ +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +typedef unsigned char u_int8_t; + +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; + +typedef int ssize_t; +#endif /* #ifdef _MSC_VER */ + +typedef unsigned long in_addr_t; + + +//#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define MAX(a,b) (a > b ? a : b) +#define MIN(a,b) (a < b ? a : b) + +#define snprintf _snprintf +#define strdup _strdup + +#define socklen_t int + +#define ETH_ADDR_LEN 6 +/* + * Structure of a 10Mb/s Ethernet header. + */ +struct ether_hdr +{ + uint8_t dhost[ETH_ADDR_LEN]; + uint8_t shost[ETH_ADDR_LEN]; + uint16_t type; /* higher layer protocol encapsulated */ +}; + +typedef struct ether_hdr ether_hdr_t; + +/* ************************************* */ + +struct ip { +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#else + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif + u_char ip_tos; /* type of service */ + short ip_len; /* total length */ + u_short ip_id; /* identification */ + short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + + +/* ************************************* */ + +typedef struct tuntap_dev { + HANDLE device_handle; + char *device_name; + char *ifName; + OVERLAPPED overlap_read, overlap_write; + uint8_t mac_addr[6]; + uint32_t ip_addr, device_mask; + unsigned int mtu; +} tuntap_dev; + +#define index(a, b) strchr(a, b) + +int gettimeofday (struct timeval *tv, void* tz); + +#endif + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/version-msvc.c b/bundles/n2n_meyerd/n2n_v2/win32/version-msvc.c new file mode 100644 index 00000000..92cce068 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/version-msvc.c @@ -0,0 +1,3 @@ +const char * n2n_sw_version = "2.0.0"; +const char * n2n_sw_osName = "Win32"; +const char * n2n_sw_buildDate = __DATE__ " " __TIME__; diff --git a/bundles/n2n_meyerd/n2n_v2/win32/win-scm.c b/bundles/n2n_meyerd/n2n_v2/win32/win-scm.c new file mode 100644 index 00000000..bb5d46ba --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/win-scm.c @@ -0,0 +1,255 @@ +/* + * win-scm.c - windows service control manager functions + * + * Copyright (c) 2008 Hamish Coleman + * 2003 Benjamin Schweizer + * 1998 Stephen Early + * + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "../scm.h" + +/* Service status: our current status, and handle on service manager */ +SERVICE_STATUS svcStatus; +SERVICE_STATUS_HANDLE svcHandle; + +/* global pointer to our service definition */ +struct SCM_def *global_sd; + +VOID WINAPI ServiceCtrlHandler(DWORD opcode) { + svcStatus.dwWin32ExitCode = NO_ERROR; + if (opcode == SERVICE_CONTROL_STOP) { + svcStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus( svcHandle, &svcStatus ); + global_sd->stop(NULL); + return; + } + SetServiceStatus( svcHandle, &svcStatus ); +} + +VOID WINAPI ServiceMain(DWORD argc, LPSTR *argv) +{ + int err; + /* + * TODO + * - work out a race-free way to determine the correct sd ptr + * - once the correct sd is known, a void* could be passed to all the + * service functions, allowing the service to know + */ + struct SCM_def *sd = global_sd; + + /* TODO - use RegisterServiceCtrlHandlerEx and pass the sd to it? */ + svcHandle = RegisterServiceCtrlHandler(sd->name,ServiceCtrlHandler); + if (!svcHandle) { + /* FIXME - use SvcReportEvent() */ + printf("RegisterServiceCtrlHandler failed %u\n", + (unsigned int)GetLastError()); + return; + } + + svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + svcStatus.dwCurrentState = 0; + svcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + svcStatus.dwWin32ExitCode = NO_ERROR; + svcStatus.dwServiceSpecificExitCode = 0; + svcStatus.dwCheckPoint = 0; + svcStatus.dwWaitHint = 5000; + + /* Report initial status to the SCM. */ + svcStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus( svcHandle, &svcStatus ); + + /* + * If there is only one SCM arg, it is just the servicename, so use + * the original cmdline instead. + * Otherwise, let the SCM args completely override the original ones + */ + if (argc==1) { + argc=sd->argc; + argv=sd->argv; + } + + sd->mode=SVC_OK; + if (sd->init) { + if ((err=sd->init(argc,argv))!=0) { + svcStatus.dwCurrentState = SERVICE_STOPPED; + svcStatus.dwWin32ExitCode = err; + SetServiceStatus( svcHandle, &svcStatus ); + return; + } + } + + svcStatus.dwCurrentState = SERVICE_RUNNING; + svcStatus.dwWin32ExitCode = NO_ERROR; + SetServiceStatus( svcHandle, &svcStatus ); + + err=sd->main(argc,argv); + + svcStatus.dwCurrentState = SERVICE_STOPPED; + svcStatus.dwWin32ExitCode = NO_ERROR; + SetServiceStatus( svcHandle, &svcStatus ); + return; +} + +int SCM_Start_Console(struct SCM_def *sd) { + + sd->mode=SVC_CONSOLE; + int err; + if (sd->init) { + err = sd->init(sd->argc,sd->argv); + if (err!=0) { + return SVC_FAIL; + } + } + + sd->main(sd->argc,sd->argv); + return SVC_OK; +} + +int SCM_Start(struct SCM_def *sd, int argc, char **argv) { + SERVICE_TABLE_ENTRY ServiceTable[] = { + { "", ServiceMain }, + { NULL, NULL } + }; + + /* save the cmdline for possible use later */ + sd->argc=argc; + sd->argv=argv; + + global_sd = sd; + + /* + * Attempt to detect if we have been run from an interactive session. + * checking the environ is still not perfect, since if the + * service is set to login as a user, it gets a USERNAME env + * and if that user is currently logged in interactively, it + * gets a SESSIONNAME env :-( + * So, also check if there is a console window + * + * Other avenues of investigation: + * from http://bytes.com/topic/net/answers/124885-multiple-use-exe-determine-if-running-service + * - work out how System.Environment.UserInteractive works + * - Check if parent process name is "services.exe" + * from http://stackoverflow.com/questions/200163/am-i-running-as-a-service#200183 + */ + char buf[100]; + if (getenv("USERNAME") && getenv("SESSIONNAME") + && GetConsoleTitle((LPTSTR)&buf,sizeof(buf))) { + return SCM_Start_Console(sd); + } + + /* try to run as a service */ + /* + * Note, this will eventually fail if we are not started as a service + * however, it will take an noticably long time to do so, thus we + * try to short circuit this delay above. + */ + if (StartServiceCtrlDispatcher(ServiceTable)==0) { + int err = GetLastError(); + + if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { + return SCM_Start_Console(sd); + } + + /* any other error, assume fatal */ + printf("StartServiceCtrlDispatcher failed %d\n", err); + return SVC_FAIL; + } + return SVC_OK; +} + +char *SCM_Install(struct SCM_def *sd, char *args) { + SC_HANDLE schSCManager, schService; + + static char path[MAX_PATH]; + + if( !GetModuleFileName( NULL, path, MAX_PATH ) ) { + printf("GetModuleFileName failed %u\n", + (unsigned int)GetLastError()); + return NULL; + } + + /* + * Note - the above path calculation does not work for paths containing + * spaces. This is because Windows is stupid, mosttly due to bad + * design - see the next below. + */ + + static char cmdline[MAX_PATH+10]; + if (args) { + /* + * The "BinaryPathName" can also have cmdline params + * embedded into it. Stupid windows + */ + + snprintf(cmdline,sizeof(cmdline),"\"%s\" %s",path,args); + } else { + snprintf(cmdline,sizeof(cmdline),"\"%s\"",path); + } + + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + schService = CreateService( + schSCManager, + sd->name, + sd->desc, + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + cmdline, + NULL, NULL, NULL, NULL, NULL); + + if (schService == NULL) { + printf("CreateService failed\n"); + CloseServiceHandle(schService); + return NULL; + } + + CloseServiceHandle(schService); + return (char *)&path; +} + +int SCM_Remove(struct SCM_def *sd) { + SC_HANDLE schSCManager, schService; + + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (schSCManager == NULL) { + printf("Couldn't open service manager\n"); + return -1; + } + + schService = OpenService(schSCManager, sd->name, DELETE); + if (schService == NULL) { + printf("Couldn't open %s service\n",sd->name); + return -1; + } + + if (!DeleteService(schService)) { + printf("Couldn't delete %s service\n",sd->name); + return -1; + } + + CloseServiceHandle(schService); + return 0; +} + diff --git a/bundles/n2n_meyerd/n2n_v2/win32/wintap.c b/bundles/n2n_meyerd/n2n_v2/win32/wintap.c new file mode 100644 index 00000000..84180ad1 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/wintap.c @@ -0,0 +1,310 @@ +/* + (C) 2007-09 - Luca Deri +*/ + +#include "../n2n.h" +#include "n2n_win32.h" + +/* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */ +#define MTU 1518 + +void initWin32() { + WSADATA wsaData; + int err; + + err = WSAStartup(MAKEWORD(2, 2), &wsaData ); + if( err != 0 ) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("FATAL ERROR: unable to initialise Winsock 2.x."); + exit(-1); + } +} + +int open_wintap(struct tuntap_dev *device, + const char * address_mode, /* "static" or "dhcp" */ + char *device_ip, + char *device_mask, + const char *device_mac, + int mtu) { + HKEY key, key2; + LONG rc; + char regpath[1024], cmd[256]; + char adapterid[1024]; + char adaptername[1024]; + char tapname[1024]; + long len; + int found = 0; + int err, i; + ULONG status = TRUE; + + memset(device, 0, sizeof(struct tuntap_dev)); + device->device_handle = INVALID_HANDLE_VALUE; + device->device_name = NULL; + device->ifName = NULL; + device->ip_addr = inet_addr(device_ip); + + /* Open registry and look for network adapters */ + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: [rc=%d]\n", rc); + exit(-1); + /* MSVC Note: If you keep getting rc=2 errors, make sure you set: + Project -> Properties -> Configuration Properties -> General -> Character set + to: "Use Multi-Byte Character Set" + */ + } + + for (i = 0; ; i++) { + len = sizeof(adapterid); + if(RegEnumKeyEx(key, i, (LPTSTR)adapterid, &len, 0, 0, 0, NULL)) + break; + + /* Find out more about this adapter */ + + _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adaptername); + err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); + + RegCloseKey(key2); + + if(err) + continue; + + if(device->device_name) { + if(!strcmp(device->device_name, adapterid)) { + found = 1; + break; + } else + continue; + } + + if(device->ifName) { + if(!strcmp(device->ifName, adaptername)) { + found = 1; + break; + } else + continue; + } + + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, + 0, /* Don't let other processes share or open + the resource until the handle's been closed */ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(device->device_handle != INVALID_HANDLE_VALUE) { + found = 1; + break; + } + } + + RegCloseKey(key); + + if(!found) { + printf("No Windows tap device found!\n"); + exit(0); + } + + /* ************************************** */ + + if(!device->device_name) + device->device_name = _strdup(adapterid); + + if(!device->ifName) + device->ifName = _strdup(adaptername); + + /* Try to open the corresponding tap device->device_name */ + + if(device->device_handle == INVALID_HANDLE_VALUE) { + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device->device_name); + device->device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + } + + if(device->device_handle == INVALID_HANDLE_VALUE) { + printf("%s (%s) is not a usable Windows tap device\n", device->device_name, device->ifName); + exit(-1); + } + + /* Get MAC address from tap device->device_name */ + + if(!DeviceIoControl(device->device_handle, TAP_IOCTL_GET_MAC, + device->mac_addr, sizeof(device->mac_addr), + device->mac_addr, sizeof(device->mac_addr), &len, 0)) { + printf("Could not get MAC address from Windows tap %s (%s)\n", + device->device_name, device->ifName); + return -1; + } + + device->mtu = mtu; + + printf("Open device [name=%s][ip=%s][ifName=%s][MTU=%d][mac=%02X:%02X:%02X:%02X:%02X:%02X]\n", + device->device_name, device_ip, device->ifName, device->mtu, + device->mac_addr[0] & 0xFF, + device->mac_addr[1] & 0xFF, + device->mac_addr[2] & 0xFF, + device->mac_addr[3] & 0xFF, + device->mac_addr[4] & 0xFF, + device->mac_addr[5] & 0xFF); + + /* ****************** */ + + printf("Setting %s device address...\n", device->ifName); + + if ( 0 == strcmp("dhcp", address_mode) ) + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" dhcp", + device->ifName); + } + else + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" static %s %s", + device->ifName, device_ip, device_mask); + } + + if(system(cmd) == 0) { + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + printf("Device %s set to %s/%s\n", + device->ifName, device_ip, device_mask); + } else + printf("WARNING: Unable to set device %s IP address [%s]\n", + device->ifName, cmd); + + /* ****************** */ + + if(device->mtu != DEFAULT_MTU) + printf("WARNING: MTU set is not supported on Windows\n"); + + /* set driver media status to 'connected' (i.e. set the interface up) */ + if (!DeviceIoControl (device->device_handle, TAP_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), + &status, sizeof (status), &len, NULL)) + printf("WARNING: Unable to enable TAP adapter\n"); + + /* + * Initialize overlapped structures + */ + device->overlap_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device->overlap_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!device->overlap_read.hEvent || !device->overlap_write.hEvent) { + return -1; + } + + return(0); +} + +/* ************************************************ */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD read_size, last_err; + + ResetEvent(tuntap->overlap_read.hEvent); + if (ReadFile(tuntap->device_handle, buf, len, &read_size, &tuntap->overlap_read)) { + //printf("tun_read(len=%d)\n", read_size); + return read_size; + } + switch (last_err = GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_read.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_read, &read_size, FALSE); + return read_size; + break; + default: + printf("GetLastError() returned %d\n", last_err); + break; + } + + return -1; +} +/* ************************************************ */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD write_size; + + //printf("tun_write(len=%d)\n", len); + + ResetEvent(tuntap->overlap_write.hEvent); + if (WriteFile(tuntap->device_handle, + buf, + len, + &write_size, + &tuntap->overlap_write)) { + //printf("DONE tun_write(len=%d)\n", write_size); + return write_size; + } + switch (GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_write.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_write, + &write_size, FALSE); + return write_size; + break; + default: + break; + } + + return -1; +} + +/* ************************************************ */ + +int tuntap_open(struct tuntap_dev *device, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + return(open_wintap(device, address_mode, device_ip, device_mask, device_mac, mtu)); +} + +/* ************************************************ */ + +void tuntap_close(struct tuntap_dev *tuntap) { + CloseHandle(tuntap->device_handle); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +/* ************************************************ */ + +#if 0 +int main(int argc, char* argv[]) { + struct tuntap_dev tuntap; + int i; + int mtu = 1400; + + printf("Welcome to n2n\n"); + initWin32(); + open_wintap(&tuntap, "static", "1.2.3.20", "255.255.255.0", mtu); + + for(i=0; i<10; i++) { + u_char buf[MTU]; + int rc; + + rc = tun_read(&tuntap, buf, sizeof(buf)); + buf[0]=2; + buf[1]=3; + buf[2]=4; + + printf("tun_read returned %d\n", rc); + rc = tun_write(&tuntap, buf, rc); + printf("tun_write returned %d\n", rc); + } + // rc = tun_open (device->device_name, IF_MODE_TUN); + WSACleanup (); + return(0); +} + +#endif diff --git a/bundles/n2n_meyerd/n2n_v2/win32/wintap.h b/bundles/n2n_meyerd/n2n_v2/win32/wintap.h new file mode 100644 index 00000000..db4acdd7 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/win32/wintap.h @@ -0,0 +1,68 @@ +/* + (C) 2007 - Luca Deri +*/ + +#ifndef _WINTAP_H_ +#define _WINTAP_H_ + +#undef UNICODE +#undef _UNICODE +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include + + + +//=============================================== +// This file is included both by OpenVPN and +// the TAP-Win32 driver and contains definitions +// common to both. +//=============================================== + +//============= +// TAP IOCTLs +//============= + +#define TAP_CONTROL_CODE(request,method) \ + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + +#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) +#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) +#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) +#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) +#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) +#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) + +//================= +// Registry keys +//================= + +#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +//====================== +// Filesystem prefixes +//====================== + +#define USERMODEDEVICEDIR "\\\\.\\Global\\" +#define SYSDEVICEDIR "\\Device\\" +#define USERDEVICEDIR "\\DosDevices\\Global\\" +#define TAPSUFFIX ".tap" + +//========================================================= +// TAP_COMPONENT_ID -- This string defines the TAP driver +// type -- different component IDs can reside in the system +// simultaneously. +//========================================================= + +#define TAP_COMPONENT_ID "tap0801" + +extern void initWin32(); + +#endif + diff --git a/bundles/n2n_meyerd/n2n_v2/wire.c b/bundles/n2n_meyerd/n2n_v2/wire.c new file mode 100644 index 00000000..f8306cdb --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wire.c @@ -0,0 +1,507 @@ +/* (c) 2009 Richard Andrews */ + +/** Routines for encoding and decoding n2n packets on the wire. + * + * encode_X(base,idx,v) prototypes are inspired by the erlang internal + * encoding model. Passing the start of a buffer in base and a pointer to an + * integer (initially set to zero). Each encode routine increases idx by the + * amount written and returns the amount written. In this way complex sequences + * of encodings can be represented cleanly. See encode_register() for an + * example. + */ + +#include "n2n_wire.h" +#include + +int encode_uint8( uint8_t * base, + size_t * idx, + const uint8_t v ) +{ + *(base + (*idx)) = (v & 0xff); + ++(*idx); + return 1; +} + +int decode_uint8( uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 1 ) { return 0; } + + *out = ( base[*idx] & 0xff ); + ++(*idx); + --(*rem); + return 1; +} + +int encode_uint16( uint8_t * base, + size_t * idx, + const uint16_t v ) +{ + *(base + (*idx)) = ( v >> 8) & 0xff; + *(base + (1 + *idx)) = ( v & 0xff ); + *idx += 2; + return 2; +} + +int decode_uint16( uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 2 ) { return 0; } + + *out = ( base[*idx] & 0xff ) << 8; + *out |= ( base[1 + *idx] & 0xff ); + *idx += 2; + *rem -= 2; + return 2; +} + +int encode_uint32( uint8_t * base, + size_t * idx, + const uint32_t v ) +{ + *(base + (0 + *idx)) = ( v >> 24) & 0xff; + *(base + (1 + *idx)) = ( v >> 16) & 0xff; + *(base + (2 + *idx)) = ( v >> 8) & 0xff; + *(base + (3 + *idx)) = ( v & 0xff ); + *idx += 4; + return 4; +} + +int decode_uint32( uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 4 ) { return 0; } + + *out = ( base[0 + *idx] & 0xff ) << 24; + *out |= ( base[1 + *idx] & 0xff ) << 16; + *out |= ( base[2 + *idx] & 0xff ) << 8; + *out |= ( base[3 + *idx] & 0xff ); + *idx += 4; + *rem -= 4; + return 4; +} + +int encode_buf( uint8_t * base, + size_t * idx, + const void * p, + size_t s) +{ + memcpy( (base + (*idx)), p, s ); + *idx += s; + return s; +} + +/* Copy from base to out of size bufsize */ +int decode_buf( uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < bufsize ) { return 0; } + + memcpy( out, (base + *idx), bufsize ); + *idx += bufsize; + *rem -= bufsize; + return bufsize; +} + + + +int encode_mac( uint8_t * base, + size_t * idx, + const n2n_mac_t m ) +{ + return encode_buf( base, idx, m, N2N_MAC_SIZE ); +} + +int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passing a n2n_mac_t */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + return decode_buf( out, N2N_MAC_SIZE, base, rem, idx ); +} + + + +int encode_common( uint8_t * base, + size_t * idx, + const n2n_common_t * common ) +{ + uint16_t flags=0; + encode_uint8( base, idx, N2N_PKT_VERSION ); + encode_uint8( base, idx, common->ttl ); + + flags = common->pc & N2N_FLAGS_TYPE_MASK; + flags |= common->flags & N2N_FLAGS_BITS_MASK; + + encode_uint16( base, idx, flags ); + encode_buf( base, idx, common->community, N2N_COMMUNITY_SIZE ); + + return -1; +} + +int decode_common( n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t idx0=*idx; + uint8_t dummy=0; + decode_uint8( &dummy, base, rem, idx ); + + if ( N2N_PKT_VERSION != dummy ) + { + return -1; + } + + decode_uint8( &(out->ttl), base, rem, idx ); + decode_uint16( &(out->flags), base, rem, idx ); + out->pc = ( out->flags & N2N_FLAGS_TYPE_MASK ); + out->flags &= N2N_FLAGS_BITS_MASK; + + decode_buf( out->community, N2N_COMMUNITY_SIZE, base, rem, idx ); + + return (*idx - idx0); +} + + +int encode_sock( uint8_t * base, + size_t * idx, + const n2n_sock_t * sock ) +{ + int retval=0; + uint16_t f; + + switch (sock->family) + { + case AF_INET: + { + f = 0; + retval += encode_uint16(base,idx,f); + retval += encode_uint16(base,idx,sock->port); + retval += encode_buf(base,idx,sock->addr.v4,IPV4_SIZE); + break; + } + case AF_INET6: + { + f = 0x8000; + retval += encode_uint16(base,idx,f); + retval += encode_uint16(base,idx,sock->port); + retval += encode_buf(base,idx,sock->addr.v6,IPV6_SIZE); + break; + } + default: + retval=-1; + } + + return retval; +} + + +int decode_sock( n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t * idx0=idx; + uint16_t f; + + decode_uint16( &f, base, rem, idx ); + + if( f & 0x8000 ) + { + /* IPv6 */ + sock->family = AF_INET6; + decode_uint16( &(sock->port), base, rem, idx ); + decode_buf( sock->addr.v6, IPV6_SIZE, base, rem, idx ); + } + else + { + /* IPv4 */ + sock->family = AF_INET; + decode_uint16( &(sock->port), base, rem, idx ); + memset( sock->addr.v6, 0, IPV6_SIZE ); /* so memcmp() works for equality. */ + decode_buf( sock->addr.v4, IPV4_SIZE, base, rem, idx ); + } + + return (idx-idx0); +} + +int encode_REGISTER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->srcMac ); + retval += encode_mac( base, idx, reg->dstMac ); + + return retval; +} + +int decode_REGISTER( n2n_REGISTER_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->srcMac, base, rem, idx ); + retval += decode_mac( reg->dstMac, base, rem, idx ); + + return retval; +} + +int encode_REGISTER_SUPER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_uint16( base, idx, reg->aflags ); + retval += encode_uint16( base, idx, reg->timeout ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->edgeMac ); + retval += encode_uint16( base, idx, 0 ); /* NULL auth scheme */ + retval += encode_uint16( base, idx, 0 ); /* No auth data */ + if(reg->aflags & N2N_AFLAGS_LOCAL_SOCKET) + retval += encode_sock( base, idx, &(reg->local_sock) ); + + return retval; +} + +int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_SUPER_t) ); + retval += decode_uint16( &(reg->aflags), base, rem, idx ); + retval += decode_uint16( &(reg->timeout), base, rem, idx ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->edgeMac, base, rem, idx ); + retval += decode_uint16( &(reg->auth.scheme), base, rem, idx ); + retval += decode_uint16( &(reg->auth.toksize), base, rem, idx ); + retval += decode_buf( reg->auth.token, reg->auth.toksize, base, rem, idx ); + if(reg->aflags & N2N_AFLAGS_LOCAL_SOCKET) + retval += decode_sock( &(reg->local_sock), base, rem, idx ); + + return retval; +} + +int encode_PEER_INFO( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PEER_INFO_t * pi ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_uint16( base, idx, pi->aflags ); + retval += encode_uint16( base, idx, pi->timeout ); + retval += encode_mac( base, idx, pi->mac ); + retval += encode_sock( base, idx, pi->sockets ); + if(pi->aflags & N2N_AFLAGS_LOCAL_SOCKET) + retval += encode_sock( base, idx, pi->sockets+1 ); + + return retval; +} + +int decode_PEER_INFO( n2n_PEER_INFO_t * pi, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( pi, 0, sizeof(n2n_PEER_INFO_t) ); + retval += decode_uint16( &(pi->aflags), base, rem, idx ); + retval += decode_uint16( &(pi->timeout), base, rem, idx ); + retval += decode_mac( pi->mac, base, rem, idx ); + retval += decode_sock( pi->sockets, base, rem, idx ); + if(pi->aflags & N2N_AFLAGS_LOCAL_SOCKET) + retval += decode_sock( pi->sockets+1, base, rem, idx ); + + return retval; +} + +int encode_QUERY_PEER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * qp ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_mac( base, idx, qp->srcMac ); + retval += encode_mac( base, idx, qp->targetMac ); + + return retval; +} + +int decode_QUERY_PEER( n2n_QUERY_PEER_t * qp, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( qp, 0, sizeof(n2n_QUERY_PEER_t) ); + retval += decode_mac( qp->srcMac, base, rem, idx ); + retval += decode_mac( qp->targetMac, base, rem, idx ); + + return retval; +} + +int encode_REGISTER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_ACK_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->dstMac ); + retval += encode_mac( base, idx, reg->srcMac ); + + return retval; +} + +int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_ACK_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->dstMac, base, rem, idx ); + retval += decode_mac( reg->srcMac, base, rem, idx ); + + return retval; +} + +int encode_REGISTER_SUPER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_ACK_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->edgeMac ); + retval += encode_uint16( base, idx, reg->lifetime ); + retval += encode_sock( base, idx, &(reg->sock) ); + retval += encode_uint8( base, idx, reg->num_sn ); + if ( reg->num_sn > 0 ) + { + /* We only support 0 or 1 at this stage */ + retval += encode_sock( base, idx, &(reg->sn_bak) ); + } + + return retval; +} + +int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + + memset( reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->edgeMac, base, rem, idx ); + retval += decode_uint16( &(reg->lifetime), base, rem, idx ); + + /* Socket is mandatory in this message type */ + retval += decode_sock( &(reg->sock), base, rem, idx ); + + /* Following the edge socket are an array of backup supernodes. */ + retval += decode_uint8( &(reg->num_sn), base, rem, idx ); + if ( reg->num_sn > 0 ) + { + /* We only support 0 or 1 at this stage */ + retval += decode_sock( &(reg->sn_bak), base, rem, idx ); + } + + return retval; +} + +int fill_sockaddr( struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock ) +{ + int retval=-1; + + if ( AF_INET == sock->family ) + { + if ( addrlen >= sizeof(struct sockaddr_in) ) + { + struct sockaddr_in * si = (struct sockaddr_in *)addr; + si->sin_family = sock->family; + si->sin_port = htons( sock->port ); + memcpy( &(si->sin_addr.s_addr), sock->addr.v4, IPV4_SIZE ); + retval=0; + } + } + + return retval; +} + + +int encode_PACKET( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_uint16( base, idx, pkt->transform ); + + return retval; +} + + +int decode_PACKET( n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( pkt, 0, sizeof(n2n_PACKET_t) ); + retval += decode_uint16( &(pkt->transform), base, rem, idx ); + + return retval; +} + +void decode_ETHFRAMEHDR( n2n_ETHFRAMEHDR_t * eth, + const uint8_t * base ) +{ + memcpy( eth->dstMac, base, N2N_MAC_SIZE ); + base += N2N_MAC_SIZE; + memcpy( eth->srcMac, base, N2N_MAC_SIZE ); +} + +int copy_ETHFRAMEHDR(uint8_t * base, + uint8_t * pkt) +{ + memcpy( base, pkt, ETH_FRAMEHDRSIZE); + return ETH_FRAMEHDRSIZE; +} diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/AUTHORS b/bundles/n2n_meyerd/n2n_v2/wireshark/AUTHORS new file mode 100644 index 00000000..1cd34dbc --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/AUTHORS @@ -0,0 +1,2 @@ +Author : +Lukas Schwaighofer diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/CMakeLists.txt b/bundles/n2n_meyerd/n2n_v2/wireshark/CMakeLists.txt new file mode 100644 index 00000000..b4061e45 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/CMakeLists.txt @@ -0,0 +1,65 @@ +# CMakeLists.txt +# +# $Id: CMakeLists.txt 34243 2010-09-24 20:41:34Z guy $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +set(DISSECTOR_SRC + packet-n2n.c +) + +set(PLUGIN_FILES + plugin.c + ${DISSECTOR_SRC} +) + +set(CLEAN_FILES + ${PLUGIN_FILES} +) + +if (WERROR) + set_source_files_properties( + ${CLEAN_FILES} + PROPERTIES + COMPILE_FLAGS -Werror + ) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +register_dissector_files(plugin.c + plugin + ${DISSECTOR_SRC} +) + +add_library(n2n ${LINK_MODE_MODULE} + ${PLUGIN_FILES} +) +set_target_properties(n2n PROPERTIES PREFIX "") +set_target_properties(n2n PROPERTIES LINK_FLAGS "${WS_LINK_FLAGS}") + +target_link_libraries(n2n epan) + +install(TARGETS n2n + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} NAMELINK_SKIP + RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/@CPACK_PACKAGE_NAME@/plugins/${CPACK_PACKAGE_VERSION} +) + diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/COPYING b/bundles/n2n_meyerd/n2n_v2/wireshark/COPYING new file mode 100644 index 00000000..d60c31a9 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/ChangeLog b/bundles/n2n_meyerd/n2n_v2/wireshark/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.am b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.am new file mode 100644 index 00000000..4aa9d272 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.am @@ -0,0 +1,131 @@ +# Makefile.am +# Automake file for N2N plugin +# By Steve Limkemann +# Copyright 1998 Steve Limkemann +# +# $Id: Makefile.am 32808 2010-05-14 16:48:17Z jake $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) + +include Makefile.common + +if HAVE_WARNINGS_AS_ERRORS +AM_CFLAGS = -Werror +endif + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = n2n.la +n2n_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_SUPPORT_SRC) \ + $(DISSECTOR_INCLUDES) +n2n_la_LDFLAGS = -module -avoid-version +n2n_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n "$(PYTHON)"; then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + n2n \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake \ + moduleinfo.nmake \ + plugin.rc.in \ + CMakeLists.txt + +checkapi: + $(PERL) $(top_srcdir)/tools/checkAPIs.pl -g abort -g termoutput $(DISSECTOR_SRC) $(DISSECTOR_INCLUDES) diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.common b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.common new file mode 100644 index 00000000..b4f61d10 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.common @@ -0,0 +1,39 @@ +# Makefile.common for N2N plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 27491 2009-02-21 16:33:48Z jake $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# the name of the plugin +PLUGIN_NAME = n2n + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-n2n.c + +# corresponding headers +DISSECTOR_INCLUDES = + +# Dissector helpers. They're included in the source files in this +# directory, but they're not dissectors themselves, i.e. they're not +# used to generate "plugin.c". +DISSECTOR_SUPPORT_SRC = diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.nmake b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.nmake new file mode 100644 index 00000000..9fb1e806 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/Makefile.nmake @@ -0,0 +1,104 @@ +# Makefile.nmake +# nmake file for Wireshark plugin +# +# $Id: Makefile.nmake 35747 2011-02-02 01:19:53Z wmeier $ +# + +include ..\..\config.nmake +include moduleinfo.nmake + +include Makefile.common + +CFLAGS=$(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \ + /I../.. $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include + +.c.obj:: + $(CC) $(CFLAGS) -Fd.\ -c $< + +LDFLAGS = $(PLUGIN_LDFLAGS) + +!IFDEF ENABLE_LIBWIRESHARK +LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib +CFLAGS=/D_NEED_VAR_IMPORT_ $(CFLAGS) + +DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj) + +DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj) + +OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj + +RESOURCE=$(PLUGIN_NAME).res + +all: $(PLUGIN_NAME).dll + +$(PLUGIN_NAME).rc : moduleinfo.nmake + sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \ + -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \ + -e s/@RC_VERSION@/$(RC_VERSION)/ \ + -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \ + -e s/@PACKAGE@/$(PACKAGE)/ \ + -e s/@VERSION@/$(VERSION)/ \ + -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \ + < plugin.rc.in > $@ + +$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE) + link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) $(RESOURCE) + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +!IFDEF PYTHON +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg.py + @echo Making plugin.c (using python) + @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC) +!ELSE +plugin.c: $(DISSECTOR_SRC) moduleinfo.h ../../tools/make-dissector-reg + @echo Making plugin.c (using sh) + @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC) +!ENDIF + +!ENDIF + +clean: + rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \ + $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \ + $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc + +distclean: clean + +maintainer-clean: distclean + +checkapi: + $(PERL) ../../tools/checkAPIs.pl -g abort -g termoutput $(DISSECTOR_SRC) $(DISSECTOR_INCLUDES) diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.h b/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.h new file mode 100644 index 00000000..121cc297 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.h @@ -0,0 +1,17 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "n2n" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.nmake b/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.nmake new file mode 100644 index 00000000..1aec6f1e --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/moduleinfo.nmake @@ -0,0 +1,28 @@ +# +# $Id: moduleinfo.nmake 20161 2006-12-19 22:24:40Z jake $ +# + +# The name +PACKAGE=n2n + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=0 +MODULE_VERSION_MICRO=1 +MODULE_VERSION_EXTRA=0 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/packet-n2n.c b/bundles/n2n_meyerd/n2n_v2/wireshark/packet-n2n.c new file mode 100644 index 00000000..4fa616a3 --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/packet-n2n.c @@ -0,0 +1,153 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#define N2N_PORT 1234 + +#define N2N_FLAGS_FROM_SUPERNODE 0x0020 +#define N2N_PKTTYPE_MASK 0x001f + +static int proto_n2n = -1; +static int hf_n2n_version = -1; +static int hf_n2n_ttl = -1; +static int hf_n2n_flag_supernode = -1; +static int hf_n2n_pkttype = -1; +static int hf_n2n_community = -1; +static int hf_n2n_transportid = -1; +static int hf_n2n_dstmac = -1; +static int hf_n2n_srcmac = -1; +static int hf_n2n_ethertype = -1; +static gint ett_n2n = -1; + +static const value_string packettypenames[] = { + { 1, "Register" }, + { 2, "Deregister" }, + { 3, "Packet" }, + { 4, "Register_ACK" }, + { 5, "Register_SUPER" }, + { 6, "Register_SUPER_ACK" }, + { 7, "Register_SUPER_NAK" }, + { 8, "Federation" }, + { 9, "Peer Info" }, + {10, "Query Peer" } +}; + +void +proto_register_n2n(void) +{ + static hf_register_info hf[] = { + { &hf_n2n_version, + { "N2N Version", "n2n.version", + FT_UINT8, BASE_DEC, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_n2n_ttl, + { "Time to Live", "n2n.ttl", + FT_UINT8, BASE_DEC, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_n2n_flag_supernode, + { "From Supernode", "n2n.flags.from_supernode", + FT_BOOLEAN, 16, + NULL, N2N_FLAGS_FROM_SUPERNODE, + NULL, HFILL } + }, + { &hf_n2n_pkttype, + { "Packet Type", "n2n.pkttype", + FT_UINT16, BASE_DEC, + VALS(packettypenames), N2N_PKTTYPE_MASK, + NULL, HFILL } + }, + { &hf_n2n_community, + { "Community", "n2n.community", + FT_STRING, BASE_NONE, + NULL, 0x0, + NULL, HFILL } + }, + { &hf_n2n_transportid, + { "Transport ID", "n2n.transportid", + FT_UINT16, BASE_DEC, + NULL, 0x0, + NULL, HFILL} + }, + { &hf_n2n_dstmac, + { "Destination MAC", "n2n.dstmac", + FT_ETHER, BASE_NONE, + NULL, 0x0, + NULL, HFILL} + }, + { &hf_n2n_srcmac, + { "Source MAC", "n2n.srcmac", + FT_ETHER, BASE_NONE, + NULL, 0x0, + NULL, HFILL} + }, + { &hf_n2n_ethertype, + { "Encapsulated Protocol", "n2n.ethertype", + FT_UINT16, BASE_HEX, + VALS(etype_vals), 0x0, + NULL, HFILL} + } + }; + + /* Setup protcol subtree array */ + static gint *ett[] = { + &ett_n2n + }; + + proto_n2n = proto_register_protocol ( + "N2N Protocol", /* name */ + "N2N", /* short name */ + "n2n" /* abbrev */ + ); + proto_register_field_array(proto_n2n, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +static void +dissect_n2n(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + gint offset = 0; + col_set_str(pinfo->cinfo, COL_PROTOCOL, "N2N"); + /* Clear out stuff in the info column */ + /* col_clear(pinfo->cinfo,COL_INFO); */ + + if(tree) { + proto_item *ti = NULL; + proto_item *n2n_tree = NULL; + + ti = proto_tree_add_item(tree, proto_n2n, tvb, 0, -1, FALSE); + n2n_tree = proto_item_add_subtree(ti, ett_n2n); + proto_tree_add_item(n2n_tree, hf_n2n_version, tvb, offset, 1, FALSE); + offset += 1; + proto_tree_add_item(n2n_tree, hf_n2n_ttl, tvb, offset, 1, FALSE); + offset += 1; + proto_tree_add_item(n2n_tree, hf_n2n_flag_supernode, tvb, offset, 2, FALSE); + proto_tree_add_item(n2n_tree, hf_n2n_pkttype, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(n2n_tree, hf_n2n_community, tvb, offset, 16, FALSE); + offset += 16; + proto_tree_add_item(n2n_tree, hf_n2n_transportid, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(n2n_tree, hf_n2n_dstmac, tvb, offset, 6, FALSE); + offset += 6; + proto_tree_add_item(n2n_tree, hf_n2n_srcmac, tvb, offset, 6, FALSE); + offset += 6; + proto_tree_add_item(n2n_tree, hf_n2n_ethertype, tvb, offset, 2, FALSE); + offset += 2; + } +} + +void +proto_reg_handoff_n2n(void) +{ + static dissector_handle_t n2n_handle; + + n2n_handle = create_dissector_handle(dissect_n2n, proto_n2n); + dissector_add_uint("udp.port", N2N_PORT, n2n_handle); +} diff --git a/bundles/n2n_meyerd/n2n_v2/wireshark/plugin.rc.in b/bundles/n2n_meyerd/n2n_v2/wireshark/plugin.rc.in new file mode 100644 index 00000000..568dc07b --- /dev/null +++ b/bundles/n2n_meyerd/n2n_v2/wireshark/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@ + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0 +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/bundles/n2n_ntop_v2/.gitignore b/bundles/n2n_ntop_v2/.gitignore new file mode 100644 index 00000000..950da593 --- /dev/null +++ b/bundles/n2n_ntop_v2/.gitignore @@ -0,0 +1,27 @@ +*.o +*.a +*.gz +configure +configure.ac +config.* +Makefile +autom4te.cache +edge +example_edge_embed_quick_edge_init +example_edge_embed +example_sn_embed +supernode +tools/n2n-benchmark +tools/n2n-decode +build +.idea +cmake-build-default +packages/debian/debian/changelog +packages/debian/debian/control +packages/debian/debian/files +packages/debian/debian/rules +packages/etc/systemd/system/edge-ntopng@.service +packages/etc/systemd/system/edge.service +packages/etc/systemd/system/edge@.service +packages/etc/systemd/system/supernode.service +*dSYM* diff --git a/bundles/n2n_ntop_v2/CHANGELOG.md b/bundles/n2n_ntop_v2/CHANGELOG.md new file mode 100644 index 00000000..3893fcc0 --- /dev/null +++ b/bundles/n2n_ntop_v2/CHANGELOG.md @@ -0,0 +1,89 @@ +# Changelog + +## n2n 2.8 (August 2020) + +This release brings significant new features to n2n's crypto world and offers +some compression opportunities. The added support for routing table manipulation +might increase comfort. Besides further honing existing features, this release +addresses some bugs. + +### New Features + +* Two lightweight stream ciphers: ChaCha20 (optional, through OpenSSL) & SPECK (integrated) +* Full Header Encryption (including packet checksumming as well as replay protection) +* A callback interface to better integrate n2n in third party software (you can still use it stand-alone) +* Enable the integrated LZO1x compression +* Add optional ZSTD compression (through zstdlib) +* Support for changing system routes at program start and end +* User and group id parameter for supernode +* Application of cryptography in n2n is seperately documented +* Add a new pseudo random number generator with higher periodicity seeded with more entropy if available + +### Improvements + +* Have AES and ChaCha20 use OpenSSL's `evp_*` interface to make better use of available hardware acceleration +* Fix invalid sendto when supernode name resolution fails +* Update to supernode's purge logic +* Extended management supernode's port output +* Fix read tap device failed when OS wakes up from sleep +* Free choice of supernode's management UDP port (for multiple supernodes on one machine) +* Additional trace messages to better indicate established connections and connection type +* Fix edge's register-to-supernode loop +* Remove redundant code +* Restructure the code in directories +* Clean-up platform-dependant code +* Compile fixes for Windows +* Fix build warnings +* …and many more under-the-hood fixes and tunings + +## n2n 2.6 (March 2020) + +The 2.6 release is mostly a maintenance release to address the issues +of 2.4 that has been the first release since a long time of silence. + +### New Features + +* AES encryption that features an overall speed bump (12x speed) and security with respect to Twofish used in the previous n2n version +* Add ability to specify a whitelist of allowed communities on the supernode +* Implement local peers discovery via multicast +* Full peer-to-peer topology support. +* Add support for multiple edge systemd services +* Add benchmark tool for the encryption throughput +* Implement packet stats for P2P vs supernode communication +* Automatically drop privileges to user n2n +* Add support for ARM64 build +* More options to control MTU, P2P connections, TOS and log verbosity +* Implement a wireshark dissector for the n2n protocol +* Implement n2n-decode utility to decode and dump traffic to PCAP + + +### Improvements +* Extensive Windows and OpenWRT support. +* Windows compilation fixes and instructions +* Instructions and makefile file to build n2n on OpenWRT +* MacOS compilation fixes and instructions +* Improve the connection stability and the chances to establish a P2P connection +* Stable and more resilient connection. +* Remove keyschedule support to simplify the encryption code +* Replace peers linked list with hash table for faster lookup in big networks +* Integrate the changes made in the meyerd fork of n2n +* Remove calls to system() in tuntap_linux and use netlink instead +* n2n version improvements + +## n2n 2.4 (August 2018) + +This is the first release after 2012 and thus it is focusing mainly +on making it work on current operating system versions, so that the +next release will be based on modern code. + +### New Features +* Added deb/rpm packages +* Added systemd configuration files +* Added ability to read configuration files instead of using only the CLI (needed for packaging) +* Added n2n Android app +* Implemented simple API to embed n2n in applications (in addition to use it stand-alone) + +### Improvements +* Major code cleanup +* Fixed compilation issues on MacOS +* Fixed Linux segmentation fault diff --git a/bundles/n2n_ntop_v2/CMakeLists.txt b/bundles/n2n_ntop_v2/CMakeLists.txt new file mode 100644 index 00000000..3156a8b1 --- /dev/null +++ b/bundles/n2n_ntop_v2/CMakeLists.txt @@ -0,0 +1,213 @@ +project(n2n) +cmake_minimum_required(VERSION 2.6) +include(CheckFunctionExists) +SET(CMAKE_VERBOSE_MAKEFILE ON) + +# N2n release information +set(N2N_VERSION "2.8.0") +set(N2N_OSNAME ${CMAKE_SYSTEM}) +execute_process( + COMMAND git --version + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_EXIST +) +if (GIT_EXIST) +execute_process( + COMMAND git rev-list --count HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_REV +) +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_ID +) +string(REGEX REPLACE "\n$" "" GIT_REV "${GIT_REV}") +string(REGEX REPLACE "\n$" "" GIT_ID "${GIT_ID}") +set(N2N_VERSION "${N2N_VERSION}.r${GIT_REV}.${GIT_ID}") +MESSAGE(STATUS "Build from git rev: ${N2N_VERSION}") +endif (GIT_EXIST) + +add_definitions(-DCMAKE_BUILD) +add_definitions(-DGIT_RELEASE="" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${N2N_OSNAME}") +add_definitions(-DN2N_VERSION="${N2N_VERSION}" -DN2N_OSNAME="${N2N_OSNAME}") + + +# Build information +OPTION(BUILD_SHARED_LIBS "BUILD Shared Library" OFF) + +# N2n specific params +OPTION(N2N_OPTION_AES "USE AES" ON) + +if(NOT DEFINED N2N_OPTION_AES) +set(N2N_OPTION_AES ON) +endif(NOT DEFINED N2N_OPTION_AES) + +if(N2N_OPTION_AES) + find_package(OpenSSL QUIET) + if(NOT OPENSSL_FOUND) + MESSAGE(WARNING "OpenSSL not found, AES disabled.") + set(N2N_OPTION_AES OFF) + else() + include_directories(${OPENSSL_INCLUDE_DIR}) + add_definitions(-DN2N_HAVE_AES) + endif(NOT OPENSSL_FOUND) +endif(N2N_OPTION_AES) + + +if(NOT DEFINED CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE None) +endif(NOT DEFINED CMAKE_BUILD_TYPE) +#set(CMAKE_BUILD_TYPE Debug) +#set(CMAKE_BUILD_TYPE Release) + +if (DEFINED UNIX) +# None +set(CMAKE_C_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") +set(CMAKE_CXX_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") +# Debug +set(CMAKE_C_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +# Release +set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") +endif(DEFINED UNIX) + +# Static target. +#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") + + +INCLUDE_DIRECTORIES(.) +INCLUDE_DIRECTORIES(include) +if(DEFINED WIN32) + INCLUDE_DIRECTORIES(win32) +# Customize include. +# INCLUDE_DIRECTORIES("D:/Program Files/MinGW/opt/include/" "D:/Program Files/MinGW/x86_64-w64-mingw32/include/") +# Customize library. +# LINK_DIRECTORIES("D:/Program Files/MinGW/opt/lib/" "D:/Program Files/MinGW/x86_64-w64-mingw32/lib/") +endif(DEFINED WIN32) + + +#aux_source_directory(./src N2N_DIR_SRCS) +#add_library(n2n STATIC ${N2N_DIR_SRCS}) +add_library(n2n STATIC + src/n2n.c + src/edge_utils.c + src/sn_utils.c + src/wire.c + src/minilzo.c + src/twofish.c + src/transform_null.c + src/transform_tf.c + src/transform_aes.c + src/transform_cc20.c + src/transform_speck.c + src/speck.c + src/random_numbers.c + src/pearson.c + src/header_encryption.c + src/tuntap_freebsd.c + src/tuntap_netbsd.c + src/tuntap_linux.c + src/tuntap_osx.c + ) + +if(DEFINED WIN32) + add_library(edge_utils_win32 src/edge_utils_win32.c) + add_subdirectory(win32) + target_link_libraries(n2n edge_utils_win32 n2n_win32 ) +endif(DEFINED WIN32) + +if(N2N_OPTION_AES) +# target_link_libraries(n2n crypto) + target_link_libraries(n2n ${OPENSSL_LIBRARIES}) +endif(N2N_OPTION_AES) + + +add_executable(edge src/edge.c) +target_link_libraries(edge n2n) + +add_executable(supernode src/sn.c) +target_link_libraries(supernode n2n) + +add_executable(example_edge_embed_quick_edge_init src/example_edge_embed_quick_edge_init.c) +target_link_libraries(example_edge_embed_quick_edge_init n2n) + +add_executable(example_edge_embed src/example_edge_embed.c) +target_link_libraries(example_edge_embed n2n) + +add_executable(example_sn_embed src/example_sn_embed.c) +target_link_libraries(example_sn_embed n2n) + +if(NOT DEFINED WIN32) + # Linux Capabilities + find_library(CAP_LIB cap) + if(CAP_LIB) + target_link_libraries(edge cap) + set(CMAKE_REQUIRED_LIBRARIES ${CAP_LIB}) + ADD_DEFINITIONS("-DHAVE_LIBCAP") + endif() +endif(NOT DEFINED WIN32) + +install(TARGETS edge supernode + RUNTIME DESTINATION sbin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + + +# Tools +add_executable(n2n-benchmark tools/benchmark.c) +target_link_libraries(n2n-benchmark n2n) + +find_library(PCAP_LIB pcap) +if(PCAP_LIB) + add_executable(n2n-decode tools/n2n_decode.c) + target_link_libraries(n2n-decode n2n pcap) + install(TARGETS n2n-decode RUNTIME DESTINATION bin) + + set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIB}) + check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE) + IF(HAVE_PCAP_IMMEDIATE_MODE) + ADD_DEFINITIONS("-DHAVE_PCAP_IMMEDIATE_MODE") + ENDIF(HAVE_PCAP_IMMEDIATE_MODE) +endif(PCAP_LIB) + +install(TARGETS n2n-benchmark RUNTIME DESTINATION bin) + +# Documentation +if(DEFINED UNIX) +add_dependencies(n2n doc) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/edge.8.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/edge.8 > ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DEPENDS ${PROJECT_SOURCE_DIR}/edge.8 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/supernode.1 > ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DEPENDS ${PROJECT_SOURCE_DIR}/supernode.1 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/n2n.7 > ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + DEPENDS ${PROJECT_SOURCE_DIR}/n2n.7 + ) + +add_custom_target(doc DEPENDS ${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + ) + +set_source_files_properties(${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + PROPERTIES GENERATED 1) + +install(FILES ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DESTINATION /usr/share/man8) +install(FILES ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DESTINATION /usr/share/man1) +install(FILES ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + DESTINATION /usr/share/man7) +endif(DEFINED UNIX) diff --git a/bundles/n2n_ntop_v2/COPYING b/bundles/n2n_ntop_v2/COPYING new file mode 100644 index 00000000..b33b35d0 --- /dev/null +++ b/bundles/n2n_ntop_v2/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + n2n Copyright (C) 2007-08 Luca Deri + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v2/INSTALL b/bundles/n2n_ntop_v2/INSTALL new file mode 100644 index 00000000..22000326 --- /dev/null +++ b/bundles/n2n_ntop_v2/INSTALL @@ -0,0 +1,50 @@ +INSTALL + +To build the programs: + +$ make + +To install the programs and man pages: + +$ make install + +or + +$ make PREFIX=/usr/local install + + +RPM Package +----------- + +These steps should work with RPM based Linux distributions since rpmbuild was +split from the rpm utility (c RedHat 9). + + +To build an RPM the easy way follow these steps. + +1. Build SRPM + +$ cd n2n +$ scripts/mk_SRPM.sh + +Look for where the src.rpm file was put ( "Wrote:" ). + +2. Build binary RPM from SRPM + +$ rpm -i path/to/n2n-.src.rpm +$ rpmbuild -bb n2n.spec + + +All this can be done as non-root user if you have a ~/.rpmmacros file with this +line in it: + +%_topdir /home/username/rpmtopdir + + +To build an RPM the hard way follow these steps. + +$ cp -a n2ndir n2n-2.0 +$ tar czf n2n-2.0.tar.gz n2n-2.0 +$ mv n2n-2.0.tar.gz /usr/src/redhat/SOURCES +$ cp n2ndir/n2n.spec /usr/src/redhat/SPECS +$ rpmbuild -bb n2n.spec diff --git a/bundles/n2n_ntop_v2/LICENSE b/bundles/n2n_ntop_v2/LICENSE new file mode 100644 index 00000000..9cecc1d4 --- /dev/null +++ b/bundles/n2n_ntop_v2/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v2/Makefile.in b/bundles/n2n_ntop_v2/Makefile.in new file mode 100644 index 00000000..60aaf193 --- /dev/null +++ b/bundles/n2n_ntop_v2/Makefile.in @@ -0,0 +1,144 @@ + +# NOTE: these are needed by the configure.in inside the packages folder +N2N_VERSION_SHORT=@N2N_VERSION_SHORT@ +GIT_COMMITS=@GIT_COMMITS@ + +######## + +CC=@CC@ + +#Ultrasparc64 users experiencing SIGBUS should try the following gcc options +#(thanks to Robert Gibbon) +PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs + +N2N_OBJS_OPT= +LIBS_EDGE_OPT=@N2N_LIBS@ +CFLAGS=@CFLAGS@ -I ./include +LDFLAGS=@LDFLAGS@ + +OPENSSL_CFLAGS=$(shell pkg-config openssl; echo $$?) +ifeq ($(OPENSSL_CFLAGS), 0) + CFLAGS+=$(shell pkg-config --cflags-only-I openssl) +endif + +CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) $(OPTIONS) $(PLATOPTS) + +INSTALL=install +MKDIR=mkdir -p +OS := $(shell uname -s) + +INSTALL_PROG=$(INSTALL) -m755 +INSTALL_DOC=$(INSTALL) -m644 + +# DESTDIR set in debian make system +PREFIX?=$(DESTDIR)/usr +#BINDIR=$(PREFIX)/bin +ifeq ($(OS),Darwin) +SBINDIR=$(PREFIX)/local/sbin +else +SBINDIR=$(PREFIX)/sbin +endif + +MANDIR?=$(PREFIX)/share/man +MAN1DIR=$(MANDIR)/man1 +MAN7DIR=$(MANDIR)/man7 +MAN8DIR=$(MANDIR)/man8 + +N2N_LIB=libn2n.a +N2N_OBJS=$(patsubst src/%.c, src/%.o, $(wildcard src/*.c)) +N2N_DEPS=$(wildcard include/*.h) $(wildcard src/*.c) Makefile $(N2N_LIB) + +LIBS_EDGE+=$(LIBS_EDGE_OPT) +LIBS_SN= + +#For OpenSolaris (Solaris too?) +ifeq ($(shell uname), SunOS) +LIBS_EDGE+=-lsocket -lnsl +LIBS_SN+=-lsocket -lnsl +endif + +APPS=edge +APPS+=supernode +APPS+=example_edge_embed_quick_edge_init +APPS+=example_edge_embed +APPS+=example_sn_embed + +DOCS=edge.8.gz supernode.1.gz n2n.7.gz + +.PHONY: steps build push all clean install tools +all: $(APPS) $(DOCS) tools + +tools: $(N2N_LIB) + $(MAKE) -C $@ + +edge: src/edge.c $(N2N_LIB) $(N2N_DEPS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ + +supernode: src/sn.c $(N2N_LIB) $(N2N_DEPS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_SN) -o $@ + +example_edge_embed_quick_edge_init: src/example_edge_embed_quick_edge_init.c $(N2N_DEPS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ + +example_sn_embed: src/example_sn_embed.c $(N2N_DEPS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ + +example_edge_embed: src/example_edge_embed.c $(N2N_DEPS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ + +%.gz : % + gzip -c $< > $@ + +$(N2N_LIB): $(N2N_OBJS) + ar rcs $(N2N_LIB) $(N2N_OBJS) +# $(RANLIB) $@ + +clean: + rm -rf $(N2N_OBJS) $(N2N_LIB) $(APPS) $(DOCS) test n2n-decode *.dSYM *~ + $(MAKE) -C tools clean + +install: edge supernode edge.8.gz supernode.1.gz n2n.7.gz + echo "MANDIR=$(MANDIR)" + $(MKDIR) $(SBINDIR) $(MAN1DIR) $(MAN7DIR) $(MAN8DIR) + $(INSTALL_PROG) supernode $(SBINDIR)/ + $(INSTALL_PROG) edge $(SBINDIR)/ + $(INSTALL_DOC) edge.8.gz $(MAN8DIR)/ + $(INSTALL_DOC) supernode.1.gz $(MAN1DIR)/ + $(INSTALL_DOC) n2n.7.gz $(MAN7DIR)/ + $(MAKE) -C tools install + +# Docker builder section +DOCKER_IMAGE_NAME=ntop/supernode +DOCKER_IMAGE_VERSION=$N2N_VERSION_SHORT +N2N_COMMIT_HASH=@GIT_REVISION@ + +default: steps + +steps: + if [ "$(TARGET_ARCHITECTURE)" = "arm32v7" ] || [ "$(TARGET_ARCHITECTURE)" = "" ]; then DOCKER_IMAGE_FILENAME="Dockerfile.arm32v7" DOCKER_IMAGE_TAGNAME=$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-arm32v7 make build; fi + if [ "$(TARGET_ARCHITECTURE)" = "x86_64" ] || [ "$(TARGET_ARCHITECTURE)" = "" ]; then DOCKER_IMAGE_FILENAME="Dockerfile.x86_64" DOCKER_IMAGE_TAGNAME=$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-x86_64 make build; fi + +build: + $(eval OS := $(shell uname -s)) + $(eval ARCHITECTURE := $(shell export DOCKER_IMAGE_TAGNAME="$(DOCKER_IMAGE_TAGNAME)"; echo $$DOCKER_IMAGE_TAGNAME | grep -oe -.*)) + + docker build --target builder --build-arg COMMIT_HASH=$(N2N_COMMIT_HASH) -t $(DOCKER_IMAGE_TAGNAME) -f image-platforms/$(DOCKER_IMAGE_FILENAME) . + + docker container create --name builder $(DOCKER_IMAGE_TAGNAME) + if [ ! -d "./build" ]; then mkdir ./build; fi + docker container cp builder:/usr/src/n2n/supernode ./build/supernode-$(OS)$(ARCHITECTURE) + docker container cp builder:/usr/src/n2n/edge ./build/edge-$(OS)$(ARCHITECTURE) + docker container rm -f builder + + docker build --build-arg COMMIT_HASH=$(N2N_COMMIT_HASH) -t $(DOCKER_IMAGE_TAGNAME) -f image-platforms/$(DOCKER_IMAGE_FILENAME) . + docker tag $(DOCKER_IMAGE_TAGNAME) $(DOCKER_IMAGE_NAME):latest$(ARCHITECTURE) + +push: + if [ ! "$(TARGET_ARCHITECTURE)" = "" ]; then \ + docker push $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-$(TARGET_ARCHITECTURE); \ + docker push $(DOCKER_IMAGE_NAME):latest-$(TARGET_ARCHITECTURE); \ + else \ + echo "Please pass TARGET_ARCHITECTURE, see README.md."; \ + fi + +# End Docker builder section diff --git a/bundles/n2n_ntop_v2/README.md b/bundles/n2n_ntop_v2/README.md new file mode 100644 index 00000000..04ce0992 --- /dev/null +++ b/bundles/n2n_ntop_v2/README.md @@ -0,0 +1,126 @@ +# n2n + +n2n is a light VPN software which makes it easy to create virtual networks bypassing intermediate firewalls. + +In order to start using n2n, two elements are required: + +- A _supernode_: it allows edge nodes to announce and discover other nodes. It must have a port publicly accessible on internet. +- _edge_ nodes: the nodes which will be a part of the virtual networks + +A virtual network shared between multiple edge nodes in n2n is called a _community_. A single supernode can relay multiple communities and a single computer can be part of multiple communities at the same time. An encryption key can be used by the edge nodes to encrypt the packets within their community. + +n2n tries to establish a direct peer-to-peer connection via udp between the edge nodes when possible. When this is not possible (usually due to special NAT devices), the supernode is also used to relay the packets. + +## Quick Setup + +Some Linux distributions already provide n2n as a package so a simple `sudo apt install n2n` will do the work. Alternatively, up-to-date packages for most distributions are available on [ntop repositories](http://packages.ntop.org/). + +On host1 run: + +```sh +$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777 +``` + +On host2 run: + +```sh +$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.2 -f -l supernode.ntop.org:7777 +``` + +Now the two hosts can ping each other. + +**IMPORTANT** It is strongly advised to choose a custom community name (`-c`) and a secret encryption key (`-k`) in order to prevent other users from connecting to your computer. For the privacy of your data sent and to reduce the server load of `supernode.ntop.org`, it is also suggested to set up a custom supernode as explained below. + +## Setting up a Custom Supernode + +You can create your own infrastructure by setting up a supernode on a public server (e.g. a VPS). You just need to open a single port (1234 in the example below) on your firewall (usually `iptables`). + +1. Install the n2n package +2. Edit `/etc/n2n/supernode.conf` and add the following: + ``` + -l=1234 + ``` +3. Start the supernode service with `sudo systemctl start supernode` +4. Optionally enable supernode start on boot: `sudo systemctl enable supernode` + +Now the supernode service should be up and running on port 1234. On your edge nodes you can now specify `-l your_supernode_ip:1234` to use it. All the edge nodes must use the same supernode. + +## Manual Compilation + +On linux, compilation from source is straight forward: + +```sh +./autogen.sh +./configure +make + +# optionally install +make install +``` + +Some parts of the code significantly benefit from compiler optimizations and platform features such as NEON, SSE and AVX. To enable, use `./configure CFLAGS="-O3 -march=native"` for configuration instead of `./configure`. + +For Windows, check out [Windows.md](doc/Windows.md) for compilation and running. +For MacOS, see [macOS.md](doc/macOS.md). + +## Running edge as a Service + +edge can also be run as a service instead of cli: + +1. Edit `/etc/n2n/edge.conf` with your custom options. See `/etc/n2n/edge.conf.sample`. +2. Start the service: `sudo systemctl start edge` +3. Optionally enable edge start on boot: `sudo systemctl enable edge` + +You can run multiple edge service instances by creating `/etc/n2n/edge-instance1.conf` and +starting it with `sudo systemctl start edge@instance1`. + +## Security Considerations + +When payload encryption is enabled (provide a key using `-k`), the supernode will not be able to decrypt +the traffic exchanged between two edge nodes but it will know that edge A is talking with edge B. + +The choice of encryption schemes that can be applied to payload has recently been enhanced. Please have +a look at [Crypto.md](doc/Crypto.md) for a quick comparison chart to help make a choice. n2n edge nodes use +Twofish encryption by default for compatibility reasons with existing versions. Other ciphers can be chosen +using the `-A_` option. + +A benchmark of the encryption methods is available when compiled from source with `tools/n2n-benchmark`. + +The header which contains some metadata like the virtual MAC address of the edge nodes, their IP address +and the community name optionally can be encrypted applying `-H` on the edges. + +## Routing the Traffic + +Reaching a remote network or tunneling all the internet traffic via n2n are two common tasks which require a proper routing setup. n2n supports routing needs providing options for packet forwarding (`-r`) including broadcasts (`-E`) as well as temporarily modifying the routing table (`-n`). Details can be found in the [Routing.md](doc/Routing.md) document. + +## IPv6 Support + +n2n can tunnel IPv6 traffic into the virtual network but does not support +IPv6 for edge-to-supernode communication yet. + +Have a look at [IPv6.md](https://github.com/ntop/n2n/blob/dev/doc/IPv6.md) for more information. + + + +## Contribution + +You can contribute to n2n in various ways: + +- Update an [open issue](https://github.com/ntop/n2n/issues) or create a new one with detailed information +- Propose new features +- Improve the documentation +- Provide pull requests with enhancements + +For details about the internals of n2n check out [Hacking guide](https://github.com/ntop/n2n/blob/dev/doc/HACKING). + +## Related Projects + +Here is a list of third-party projects connected to this repository. + +- N2N for Android: [hin2n](https://github.com/switch-iot/hin2n) +- Docker images: [Docker Hub](https://hub.docker.com/r/supermock/supernode/) +- Go bindings, management daemons and CLIs for n2n edges and supernodes, Docker, Kubernetes & Helm Charts: [pojntfx/gon2n](https://pojntfx.github.io/gon2n/) + +--- + +(C) 2007-2020 - ntop.org and contributors diff --git a/bundles/n2n_ntop_v2/autogen.sh b/bundles/n2n_ntop_v2/autogen.sh new file mode 100644 index 00000000..f786d152 --- /dev/null +++ b/bundles/n2n_ntop_v2/autogen.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# NOTE: update version in CMakeLists.txt after changing these +N2N_MAJOR="2" +N2N_MINOR="8" +N2N_PATCH="0" + +N2N_VERSION_SHORT="$N2N_MAJOR.$N2N_MINOR.$N2N_PATCH" + +cat configure.seed | sed \ + -e "s/@N2N_MAJOR@/$N2N_MAJOR/g" \ + -e "s/@N2N_MINOR@/$N2N_MINOR/g" \ + -e "s/@N2N_PATCH@/$N2N_PATCH/g" \ + -e "s/@N2N_VERSION_SHORT@/$N2N_VERSION_SHORT/g" \ + > configure.ac + +rm -f config.h config.h.in *~ Makefile configure #* + +echo "Wait please..." +autoreconf -if +./configure diff --git a/bundles/n2n_ntop_v2/community.list b/bundles/n2n_ntop_v2/community.list new file mode 100644 index 00000000..b2c249f4 --- /dev/null +++ b/bundles/n2n_ntop_v2/community.list @@ -0,0 +1,5 @@ +# +# List of allowed communities +# +mynetwork +netleo diff --git a/bundles/n2n_ntop_v2/configure.seed b/bundles/n2n_ntop_v2/configure.seed new file mode 100644 index 00000000..3b12a160 --- /dev/null +++ b/bundles/n2n_ntop_v2/configure.seed @@ -0,0 +1,113 @@ +odnl> Do not add anything above +AC_INIT([edge],@N2N_VERSION_SHORT@) +dnl> Do not add anything above + +N2N_VERSION_SHORT=${PACKAGE_VERSION} + +if test -d ".git"; then +# NOTE: keep in sync with the definitions for configure.in files under the packages folder +GIT_COMMITS=`git rev-list --count HEAD` +GIT_REVISION=`git rev-parse --short HEAD` +GIT_RELEASE="${N2N_VERSION_SHORT}.r${GIT_COMMITS}.${GIT_REVISION}" +else +GIT_RELEASE=${N2N_VERSION_SHORT} +fi + +N2N_LIBS= + +AC_PROG_CC +AC_CHECK_LIB([zstd], [ZSTD_compress]) + +if test "x$ac_cv_lib_zstd_ZSTD_compress" != xyes; then + AC_MSG_RESULT(Building n2n without ZSTD support) +else + AC_DEFINE([N2N_HAVE_ZSTD], [], [Have ZSTD support]) + N2N_LIBS="-lzstd ${N2N_LIBS}" +fi + +AC_CHECK_LIB([crypto], [AES_cbc_encrypt]) + +if test "x$ac_cv_lib_crypto_AES_cbc_encrypt" != xyes; then + AC_MSG_RESULT(Building n2n without AES support) +else + AC_DEFINE([N2N_HAVE_AES], [], [Have AES support]) + N2N_LIBS="-lcrypto ${N2N_LIBS}" +fi + +OLD_CFLAGS="${CFLAGS}" +OLD_LDFLAGS="${LDFLAGS}" + +CFLAGS="${CFLAGS} -I/usr/local/opt/openssl@1.1/include" +LDFLAGS="${LDFLAGS} -L/usr/local/opt/openssl@1.1/lib/" +AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_reset]) +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_reset" != xyes; then + CFLAGS="${OLD_CFLAGS}" + LDFLAGS="${OLD_LDFLAGS}" +else + AC_DEFINE([HAVE_OPENSSL_1_1], [], [OpenSSL 1.1 is present]) +fi + +AC_CHECK_LIB([pcap], [pcap_open_live], pcap=true) + +if test x$pcap != x; then + AC_DEFINE([N2N_HAVE_PCAP], [], [Have PCAP library]) + ADDITIONAL_TOOLS="$ADDITIONAL_TOOLS n2n-decode" +fi + +AC_CHECK_LIB([pcap], [pcap_set_immediate_mode], pcap_immediate_mode=true) + +if test x$pcap_immediate_mode != x; then + AC_DEFINE([HAVE_PCAP_IMMEDIATE_MODE], [], [Have pcap_immediate_mode]) +fi + +AC_CHECK_LIB([cap], [cap_get_proc], cap=true) +if test x$cap != x; then + LDFLAGS="${LDFLAGS} -lcap" + AC_DEFINE([HAVE_LIBCAP],[1],[Support for linux capabilities]) +fi + +MACHINE=`uname -m` +SYSTEM=`uname -s` + +if test $SYSTEM = "Linux"; then + if test -f /etc/debian_version; then + DEBIAN_VERSION=`cat /etc/debian_version` + OSNAME="Debian $DEBIAN_VERSION" + else + OSNAME=`./config.guess` + fi +else +dnl> wget -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' + OSNAME=`./config.guess` +fi +AC_DEFINE_UNQUOTED(PACKAGE_OSNAME, "${OSNAME}", [OS name]) +AC_DEFINE_UNQUOTED(GIT_RELEASE, "${GIT_RELEASE}", [GIT release]) + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + if test $MACHINE = "i686"; then + EXTN="i386" + fi +fi + +DATE=`date +"%Y-%m-%d"` + +AC_SUBST(CC) +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(N2N_MAJOR) +AC_SUBST(N2N_MINOR) +AC_SUBST(N2N_PATCH) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(GIT_REVISION) +AC_SUBST(GIT_RELEASE) +AC_SUBST(N2N_DEFINES) +AC_SUBST(N2N_LIBS) +AC_SUBST(ADDITIONAL_TOOLS) +AC_CONFIG_HEADERS(include/config.h) +AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES(tools/Makefile) + +AC_OUTPUT diff --git a/bundles/n2n_ntop_v2/contributors.txt b/bundles/n2n_ntop_v2/contributors.txt new file mode 100644 index 00000000..cdfbd516 --- /dev/null +++ b/bundles/n2n_ntop_v2/contributors.txt @@ -0,0 +1,10 @@ +Code contributions courtesy of: + * Richard Andrews + * Don Bindner + * Sylwester Sosnowski + * Wilfried "Wonka" Klaebe + * Lukasz Taczuk + * Alaric Snell-Pym + * Babak Farrokhi [FreeBSD port] + * Logan oos Even + diff --git a/bundles/n2n_ntop_v2/doc/Crypto.md b/bundles/n2n_ntop_v2/doc/Crypto.md new file mode 100644 index 00000000..547a9655 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/Crypto.md @@ -0,0 +1,202 @@ +# Cryptography in n2n + +## Payload + +### Overview + +Payload encryption currently comes in four different flavors using ciphers of different origins. Supported ciphers are enabled using the indicated command line option: + +- Twofish in CTS mode (`-A2`) +- AES in CBC mode (`-A3`) +- ChaCha20 (CTR) (`-A4`) +- SPECK in CTR mode (`-A5`) + +To renounce encryption, `-A1` enables the so called `null_transform` transmitting all payload data unencryptedly. + +The following chart might help to make a quick comparison and decide what cipher to use: + +| Cipher | Mode | Block Size | Key Size | IV length |Speed | Built-In | Origin | +| :---: | :---:| :---: | :---: | :---: |:---: | :---: | --- | +|Twofish | CTS | 128 bits | 256 bit | 32 bit | - | Y | Bruce Schneier | +|AES | CBC | 128 bits | 128, 192, 256 bit| 64 bit | O..+ | N | Joan Daemen, Vincent Rijmen, NSA-approved | +|ChaCha20| CTR | Stream | 256 bit | 128 bit | +..++| N | Daniel J. Bernstein | +|SPECK | CTR | Stream | 256 bit | 128 bit | ++ | Y | NSA | + +The two block ciphers Twofish and AES are used in CTS mode (Twofish) and CBC mode(AES). AES requires a padding which results in encrypted payload size modulo their blocksize. Sizewise, this could be considered as a disadvantage. On the other hand, stream ciphers need a longer initialization vector (IV) to be transmitted with the cipher. + +Note that AES and ChaCha20 are available only if n2n is compiled with openSSL support. n2n will work well without them offering the respectively reduced choice of remaining built-in ciphers (Twofish, SPECK). + +### Twofish + +This implementation prepends a 32 bit random value to the plain text. In the `src/transform_tf.c` file, it is called `nonce`. In CBC mode, this basically has the same effect as a respectively shorter IV. + +Twofish requires no padding as it employs a CBC/CTS scheme which can send out plaintext-length ciphertexts. The scheme however has a small flaw in handling messages shorter than one block, only low-level programmer might encounter this. + +Twofish is the slowest of the ciphers present. + +_We might try to find a faster implementation._ + +### AES + +AES uses the standard way of an IV but it does not neccessarily transmit the full IV along with the packets. The size of the transmitted part is adjustable by changing the `TRANSOP_AES_IV_SEED_SIZE` definition found in `src/transform_aes.c`. It defaults to 8 meaning that 8 bytes (of max 16) are transmitted. The remaining 8 bytes are fixed, key-derived material is used to fill up to full block size. A single AES-ECB encryption step is applied to these 16 bytes before they get used as regular IV for AES-CBCing the payload. + +Padding to the last block happens by filling `0x00`-bytes and indicating their number as the last byte of the block. This could lead to up to 16 extra bytes. + +AES relies on openSSL's `evp_*` interface which also offers hardware acceleration where available (SSE, AES-NI, …). It however is slower than the following stream ciphers because the CBC mode cannot compete with the optimized stream ciphers. + +_Perhaps, AES-CTR being a stream cipher could have competed with the stream ciphers._ + +_Another possible extension would be to bring CTS mode to AES in some future version, just to avoid unneccessary weight gains from padding. CTS mode works well starting with plain texts from one block plus. So, we might revert back to the Twofish-way of IV handling with a full block IV._ + +### ChaCha20 + +ChaCha20 was the first stream cipher supported by n2n. + +It also relies on openSSL's `evp_*` interface. It does not use the Poly1305 message tag from the same author though. Whole packet's checksum will be handled in the header (see below). + +The random full 128-bit IV is transmitted in plain. + +ChaCha20 usually performs faster than AES-CBC. + +### SPECK + +SPECK is recommended by the NSA for offical use in case AES implementation is not feasible due to system constraints (performance, size, …). The block cipher is used in CTR mode making it a stream cipher. The random full 128-bit IV is transmitted in plain. + +On Intel CPUs, SPECK performs even faster than openSSL's ChaCha20 as it takes advantage of SSE4 or AVX2 if available (compile using `-march=native`). On Raspberry's ARM CPU, it is second place behind ChaCha20 and before AES-CBC. + +### Random Numbers + +Throughout n2n, pseudo-random numbers are generated for several purposes, e.g. random MAC assignment and the IVs for use with the various ciphers. Regarding IVs, especially for using in the stream ciphers, the pseudo-random numbers shall be as collision-free as possible. n2n uses an implementation of XORSHIFT128+ which shows a periodicity of 2¹²â¸. + +Its initialization relies on seeding with a value as random as possible. Various sources are tapped including a syscall to Linux' `SYS_getrandom` as well as Intels hardware random number generators `RDRND` and `RDSEED`, if available (compile using `-march=native`). + +### Pearson Hashing + +For general purpose hashing, n2n employs Pearson hashing as it offers variable hash sizes and is said not to be too "collidy". However, this is not a cryptographically secure hashing function which by the way is not required here: The hashing is never applied in a way that the hash shall prove the knowledge of a secret without showing the secret. + +_Pearson hashing is tweakable by making your own permutation of the 256 byte table._ + +_Pearson hashing allows verification of parts of the hash only – just in case performance requirements would urge to do so._ + +## Header + +### Overview + +Packet's header consist of a COMMON section followed by a packet-type specific section, e.g. REGISTER, REGISTER_ACK, PACKET including the payload, REGISTER_SUPER, … + +The COMMON section is built as follows: + +``` +0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Version=2 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Community : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +In case of a PACKET-type, it is succeeded by the fields depicted below: + +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 : ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 ! Socket Flags (v=IPv4) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Destination IPv4 Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Transform ID ! Payload ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +44 ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+... +``` +### Encryption + +If enabled (`-H`), all fields but the payload (which is handled seperately as outlined above) get encrypted using SPECK in CTR mode. As packet headers need to be decryptable by the supernode and we do not want to add another key (to keep it a simple interface), the community name serves as key (keep it secret!) because it is already known to the supernode. The community name consists of up to 16 characters (well, 15 + `0x00`), so key size of 128 bit is a reasonable choice here. + +The scheme applied tries to maintain compatibility with current packet format and works as follows: + +- First line of 4 bytes (Version, TTL, Flags) goes to fifth line: +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! Version=2 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` +- To be able to identify a correctly decrpyted header later on, a magic number is stamped in fourth line starting at byte number 12. We use "n2n" string and add the header length to be able to stop header decryption right before an eventually following payload begins – in case of PACKET-type, header-length does not equal packet-length. + +- The rest of the community field, namely the first 12 bytes, is reframed towards a 96-bit IV for the header encryption. +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! IV ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ... IV ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... IV : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! 24-bit Magic Number, "n2n" = 0x6E326E ! Header Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! Version=2 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +- As we use a stream cipher, the IV should be a nonce. The IV plays an additional role sketched later, see the following sections on checksum and replay protection. For use in header encryption and decryption, four bytes reading ASCII "n2n!" are appended to the 96-bit IV hereby internally making it a full 128-bit IV. + +- To make a less predictable use of the key space – just think of the typically reset MSB of ASCII characters of community names – we actually use a hash of the community name as key. + +- Encryption starts at byte number 12 and ends at header's end. It does not comprise the payload which eventually has its own encryption scheme as chosen with the `-A_` options. + +Decryption checks all known communities (several in case of supernode, only one at edge) as keys. On success, the emerging magic number will reveal the correct community whose name will be copied back to the original fields allowing for regular packet handling. + +Thus, header encryption will only work with previously determined community names introduced to the supernode by `-c ` parameter. Also, it should be clear that header encryption is a per-community decision, i.e. all nodes and the supernode need to have it enabled. However, the supernode supports encrpyted and unencrypted communities in parallel, it determines their status online at arrival of the first packet. Use a fresh community name for encrypted communities; do not use a previously used one of former unecrpyted communities: their names were transmitted openly. + +### Checksum + +The whole packet including the eventually present payload is checksummed using a modified Person hashing. It might seem a little short compared to usual message tags of 96 up to 128 bit, especially when using a stream cipher which easily allows for bit-flips. So, the 16-bit checksum is filled up with 80 more bits to obtain a 96-bit pre-IV. This pre-IV gets encrypted using a single block-cipher step to get the pseudo-random looking IV. This way, the checksum resists targeted bit-flips (to header, payload, and IV) as any change to the whole 96-bit IV would render the header un-decryptable. + +The single block-cipher step employs SPECK because it is fast, always present as built-in and it offers a 96-bit version. The key is derived from the header key – a hash of the hash. + +The checksum gets verified by the edges and the supernode. + +### Replay Protection + +The aforementioned fill-up does not completely rely on random bits. A 52-bit time stamp displaying a microsecond-accuracy is encoded to the 96-bit pre-IV as well: + +``` + 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + +------------------------------------------------------------------------------------------------+ + ! 52-bit time stamp with microsecond-accuracy ! 28 pseudo-random bits !16-bit checksum! + +------------------------------------------------------------------------------------------------+ + +``` +Encrypting this pre-IV with a block cipher step will generate a pseudo-random looking IV which gets written to the packet and used for the header encryption. + +Due to the time-stamp encoded, the IV will more likely be unique, close to a real nonce. + +Upon receival, the time stamp as well as the checksum can be extracted from the IV by performing a 96-bit block-cipher decryption step. Verification of the time stamp happens in two steps: + +- The (remote) time stamp is checked against the local clock. It may not deviate more than plus/minus 16 seconds. So, edges and supernode need to keep a somewhat current time. This limit can be adjusted by changing the `TIME_STAMP_FRAME` definition. It is time-zone indifferent as UTC is used. + +- Valid (remote) time stamps get stored as "last valid time stamp" seen from each node (supernode and edges). So, a newly arriving packet's time stamp can be compared to the last valid one. It should be equal or higher. However, as UDP packets may overtake each other just by taking another path through the internet, they are allowed to be 160 millisecond earlier than the last valid one. This limit can be adjusted by changing the `TIME_STAMP_JITTER` definition. + +The way the IV is used for replay protection and for checksumming makes enabled header encryption a prerequisite for these features. diff --git a/bundles/n2n_ntop_v2/doc/HACKING b/bundles/n2n_ntop_v2/doc/HACKING new file mode 100644 index 00000000..8b04ed1d --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/HACKING @@ -0,0 +1,267 @@ +file: HACKING + +Last updated: 2010-01-01 09:55 UTC + +-------- +(C) 2008-2010 - Richard Andrews + +This program and document 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 3 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 see see + +-------- + + +This file describes the internals of n2n. Read this before starting to modify +the code. Because coding examples may be present in this document it is licensed +under the GPL rather than FDL. + + +SYMMETRIC NAT +------------- + +Symmetric NAT is a form of firewall NAT in which an UDP packets are only passed +back to an inside host socket when the return packets originate from the outside +socket to which the initiating UDP packets were sent. This means that when an +inside host sends UDP to some outside socket; other hosts cannot piggyback on +this opening in the firewall to send data to the inside host. + +For example, an asymmetric NAT would keep the mapping: + -> +and would redirect all the packets on external port ExtPort to the internal host +regardless of the remote IP. + +Whereas a symmetric NAT would keep the mapping: + -> +so only RemoteIP can send packets to the internal host. RemoteIP is the supernode +IP in case of n2n, to which the internal host has registered. + +In n2n, P2P can work monodirecitonally if only one of the two peers is behind a symmetric +NAT. For example, if A is behind symmetric NAT and B is behind asymmetric NAT + - A->B packets are P2P (will have the B public IP as destination) + - B->A packets must go through the supernode + +If both the peers are behind symmetric NAT, then no P2P communication is possible. + +ARP CACHE +--------- + +n2n makes use of the host operating system's own ARP cache. Each edge node +allocates a random MAC address to itself. This MAC is constant for the life of +the edge process. ARP packets are passed around as broadcast ethernet packets +over n2n and these packets cause the native ARP cache to be updated. + +Edge nodes send gratuitous ARP packets on startup. See GRATUITOUS ARP below. + + +REGISTRATION AND PEER-TO-PEER COMMUNICATION SETUP +------------------------------------------------- + +A and B are edge nodes with public sockets Apub and Bpub; and private network +addresses A and B respectively. S is the supernode. + +A sends {REGISTER,Amac} to S. S registers {Amac->Apub}. +B sends {REGISTER,Bmac} to S. S registers {Bmac->Bpub}. + +Now ping from A to B. + +A sends broadcast "arp who-has B" to S. S relays the packet to all known edge +nodes. B replies "B at Bmac" to supernode which forwards this to A. So now ping +A->B is known to be ping Amac(A)->Bmac(B). Note: gratuitous arp also requires +discussion. + +In response to receiving the arp reply, Apub sends {REGISTER,Amac} to Bpub. If +Bpub receives the request it sends back {REGISTER_ACK,Amac} and also sends its +own {REGISTER,Bmac} request. + +In response to receiving the "arp who-has", Bpub sends {REGISTER,Bmac} to Apub. + +Now the OS has received the arp reply and sends ICMP to Bmac(B) via the tunnel +on A. A looks up Bmac in the peers list and encapsulates the packet to Bpub or +the supernode if the MAC is not found. + +We assume that between two edge nodes, if Bpub receives a packet from Apub then +Apub can receive a packet from Bpub. This is the symmetric NAT case. Note: In +the symmetric NAT case, the public socket for a MAC address will be different +for direct contact when compared to information from the supernode. + +When two edge nodes are both behind symmetric NAT they cannot establish direct +communication. + +If A receives {REGISTER,Bmac} from B, A adds {Bmac->Bpub} to its peers list +knowing that Bmac is now reachable via that public socket. Similarly if B +receives {REGISTER,Amac} from A. + +The supernode never forwards REGISTER messages because the public socket seen by +the supervisor for some edge (eg. A) may be different to the socket seen by +another edge due to the actions of symmetric NAT (alocating a new public socket +for the new outbound UDP "connection"). + + +EDGE REGISTRATION DESIGN AMMENDMENTS (starting from 2008-04-10) +------------------------------------ + + * Send REGISTER on rx of PACKET or REGISTER only when dest_mac == device MAC +(do not send REGISTER on Rx of broadcast packets). + * After sending REGISTER add the new peer to pending_peers list; but + * Don't send REGISTER to a peer in pending_peers list + * Remove old entries from pending_peers at regular intervals + * On rx of REGISTER_ACK, move peer from pending_peers to known_peers for direct +comms and set last_seen=now + * On rx of any packet set last_seen=now in the known_peers entry (if it +exists); but do not add a new entry. + * If the public socket address for a known_peers entry changes, deleted it and +restart registration to the new peer. + * Peer sockets provided by the supernode are ignored unless no other entry +exists. Direct peer-to-peer sockets are always given more priority as the +supernode socket will not be usable for direct contact if the peer is behind +symmetric NAT. + + +The pending_peers list concept is to prevent massive registration traffic when +supernode relay is in force - this would occur if REGISTER was sent for every +incident packet sent via supernode. Periodic REGISTER attempts will still occur; +not for every received packet. In the case where the peer cannot be contacted +(eg. both peers behind symmetric NAT), then there will still be periodic +attempts. Suggest a pending timeout of about 60 sec. + +A peer is only considered operational for peer-to-peer sending when a +REGISTER_ACK is returned. Once operational the peer is kept operational while +any direct packet communications are occurring. REGISTER is not required to +keep the path open through any firewalls; just some activity in one direction. + +After an idle period; the peer should be deleted from the known_peers list. We +should not try to re-register when this time expires. If there is no data to +send then forget the peer. This helps scalability. + +If a peer wants to be remembered it can send gratuitous ARP traffic which will +keep its entry in the known_peers list of any peers which already have the +entry. + + + + +peer = find_by_src_mac( hdr, known_peers ); /* return NULL or entry */ + +if ( peer ) +{ + peer_last_seen = time(NULL); +} +else +{ + if ( ! is_broadcast( hdr ) ) /* ignore broadcasts */ + { + if ( IS_REGISTER_ACK( hdr ) ) + { + /* move from pending to known_peers */ + set_peer_operational( hdr ); + } + else + { + /* add to pending and send REGISTER - ignore if in pending. */ + try_send_register( hdr ) + } + } +} + + +(Notes): + + * In testing it was noted that if a symmetric NAT firewall shuts down the UDP +association but the known_peers registration is still active, then the peer +becomes unreachable until the known_peers registration is deleted. Suggest two +ways to mitigate this problem: + (a) make the known_peers purge timeout a config paramter; + (b) send packets direct and via supernode if the registration is older than + eg. 60 sec. + + +GRATUITOUS ARP +-------------- + +In addition to the ARP who-has mechanism noted above, two edge nodes can become +aware of one another by gratuitous ARP. A gratuitous ARP packet is a broadcast +packet sent by a node for no other purpose than to announce its presence and +identify its MAC and IP address. Gratuitous ARP packets are to keep ARP caches +up to date so contacting the host will be faster after an long idle time. + + +MAN PAGES +--------- + +Look at a non-installed man page like this (linux/UNIX): + +nroff -man edge.8 | less + + +PACKET message FORMAT +--------------------- + +All message encoding and decoding is contained in wire.c. The PACKET message is +of main concern as it is the most frequently transferred as it contains +encapsulated ethernet packets. + +Version 2 + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Version=2 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Community : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 : ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 ! Socket Flags (v=IPv4) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Destination IPv4 Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Transform ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 ! Payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +So each n2n PACKET has a 44 byte overhead. For a 1500 byte ethernet packet this +is roughly 3%. + +Socket flags provides support for IPv6. In this case the PACKET message ends as +follows: + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 ! Socket Flags (v=IPv6) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Destination IPv6 Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +52 ! Transform ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +56 ! Encapsulated ethernet payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +------- + +January 2010 - Richard Andrews diff --git a/bundles/n2n_ntop_v2/doc/IPv6.md b/bundles/n2n_ntop_v2/doc/IPv6.md new file mode 100644 index 00000000..b32b5e0e --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/IPv6.md @@ -0,0 +1,25 @@ +# IPv6 + +n2n supports the carriage of IPv6 packets within the n2n tunnel. N2n does not +yet use IPv6 for transport between edges and supernodes. + +To make IPv6 carriage work you need to manually add IPv6 addresses to the TAP +interfaces at each end. There is currently no way to specify an IPv6 address on +the edge command line. + +Eg. under linux: + +on hostA: +`[hostA] $ /sbin/ip -6 addr add fc00:abcd:1234::7/48 dev n2n0` + +on hostB: +`[hostB] $ /sbin/ip -6 addr add fc00​:abcd:​1234::6/48 dev n2n0` + +You may find it useful to make use of tunctl from the uml-utilities +package. Tunctl allow you to bring up a TAP interface and configure addressing +prior to starting edge. It also allows edge to be restarted without the +interface closing (which would normally affect routing tables). + +Once the IPv6 addresses are configured and edge started, IPv6 neighbor discovery +packets flow (get broadcast) and IPv6 entities self arrange. Test your IPv6 +setup with ping6 - the IPv6 ping command. diff --git a/bundles/n2n_ntop_v2/doc/MTU.md b/bundles/n2n_ntop_v2/doc/MTU.md new file mode 100644 index 00000000..05fb6fc3 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/MTU.md @@ -0,0 +1,54 @@ +# MTU + +The MTU of the VPN interface is set to a lower value (rather than the standard +1500 B value) to avoid excessive fragmentation on the datagram sent on internet. +This is required because n2n adds additional headers to the packets received from +the VPN interface. The size of the final frame sent through the internet interface +must have a size <= the internet interface MTU (usually 1500 B). + +As a fragmentation example, suppose that a 3000 B TCP segment should be sent through +the VPN. If the VPN interface MTU is set to 1500, the packet will be split into two +fragments of 1500 B each. However, n2n will add its headers to each fragment, so +each fragment becomes a 1540 B packet. The internet interface mtu, which is 1500 B, +will fragment each packet again in two further fragments (e.g. 1500 + 50 B), so a +total of 4 fragments will be sent over internet. On the other hand, if the VPN interface +MTU was set to 1460 that would result in only 3 fragments sent as the initial segment of +3000 would be split in 1460 + 1460 + 80 B and that would not be further fragmented. + +IP packet fragmentation in general is something to avoid, as described in +http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-87-3.pdf . When possible, +the fragmentation should be moved to the TCP layer by a proper MSS value. +This can be forced by mangling the packet MSS, which is called "MSS clamping" (currently not +implemented in n2n). See https://github.com/gsliepen/tinc/blob/228a03aaa707a5fcced9dd5148a4bdb7e5ef025b/src/route.c#L386 . + +The exact value to use as a clamp value, however, depends on the PMTU, which is the minimum +MTU of the path between two hosts. Knowing the PMTU is also useful for a sender in order to +avoid fragmentation at the IP level. Trying to find the biggest MTU is useful since it allows to +maximize bandwidth. + +## PMTU Discovery Failures + +Most operating systems try to periodically discover the PMTU by using a PMTU discovery algorithm. +This involves setting the DF (don't fragment) flag on the IP packets. When a large IP packet exceeds +the MTU of a router in the path, an "ICMP Fragmentation Needed" message should be received, which will +help the OS tune the size of the next IP packets. However, some routers do not report such ICMP message, +which results in packets being silently dropped. The `tracepath` tool can be used to detect the PMTU. + +The main problem when this situation occurs is that the actual PMTU is unknown, so an automatic +solution is not applicable. The user must manually specify a lower MTU for the VPN interface +in order to solve the issue. + +## n2n and MTU + +n2n should work by default in different environments. For this reason, the following solution +has been provided: + +- PMTU discovery is disabled when possible (via the IP_MTU_DISCOVER socket option). This avoid + silently dropping a oversize packet due to the DF flag, however it possibly increments fragmentation on the path. +- As examplained above, a lower MTU is set on the VPN interface, thus removing excessive fragmentation on + the sender. +- 1400 B is used instead of 1500 B as the reference value for the internet interface MTU. + This essentially avoids fragmentation when the PMTU is >= 1400 B. + +This is a conservative solution which should make n2n work by default. The user can manually +specify the MTU and re-enable PMTU discovery via the CLI options. diff --git a/bundles/n2n_ntop_v2/doc/Routing.md b/bundles/n2n_ntop_v2/doc/Routing.md new file mode 100644 index 00000000..8f278ea6 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/Routing.md @@ -0,0 +1,188 @@ +# IPv4 Routing (Linux) + +## General Remarks + +Reaching a remote network or tunneling all the internet traffic via n2n are two common tasks which require a proper routing setup. n2n supports routing needs providing options for packet forwarding including broadcasts as well as modifying the routing table. + +In this context, the `server` is the edge node which provides access to the remote network/internet, whereas the `client` is the connecting edge node. + +In order to enable routing, the `server` must be configured as follows: + +1. Add the `-r` option to the edge options to enable routing +2. Enable packet forwarding with `sudo sysctl -w net.ipv4.ip_forward=1` +3. Enable IP masquerading: `sudo iptables -t nat -A POSTROUTING -j MASQUERADE` + +On the client side, the easiest way to configure routing is via the `-n` option. For example: + +- In order to connect to the remote network `192.168.100.0/24`, use `-n 192.168.100.0/24:10.0.0.1` +- In order to tunnel all the internet traffic, use `-n 0.0.0.0/0:10.0.0.1` + +10.0.0.1 is the IP address of the gateway to use to route the specified network. It should correspond to the IP address of the `server` within n2n. Multiple `-n` options can be specified. + +As an alternative to the `-n` option, the `ip route` linux command can be manually used. See the [n2n_gateway.sh](doc/n2n_gateway.sh) script for an example. See also the follwing description of other use cases and in depth explanation. + +## Special Scenarios + +### Assumptions + +- There are two Local Area Networks, namely 10.11.12.0/24 (maybe at + **h**ome) and 192.168.1.0/24 (maybe in **o**ffice). +- These networks are connected to the internet via routers 10.11.12.1 + and 192.168.1.1, respectively. +- In each network, there is a computer running a successfully setup n2n + node: 10.11.12.5 (**h**ickory) and 192.168.1.6 (**o**scar). They are + connected to their networks through a device called _eth0_. Their n2n + devices shall be called _n2n0_, and their n2n IP addresses are + 10.99.99.50 (**h**ickory) and 10.99.99.60 (**o**scar) in the + 10.99.99.0/24 network. +- The _iptables_ are flushed. + +### Prerequisites + +- Both, **h**ickory and **o**scar have ip forwarding enabled: `echo 1 > /proc/sys/net/ipv4/ip_forward` or `sysctl -w net.ipv4.ip_forward=1`. To + make this setting persistent over reboot, a file containing the line + `net.ipv4.ip_forward=1` could be added in /etc/sysctl.d/ – your distro + may vary. +- To allow n2n to forward packets, both edge nodes need to be started + with `-r` option on their command line. All other regular network + interfaces usually already allow packet forwarding and thus do not need + any further configuration. + +### Reach Complete Office Network from n2n Node at Home + +- To make **h**ickory send all packets with office destination via + **o**scar, **h**ickory needs to be made aware of where to route this + packets to. On **h**ickory: `ip route add 192.168.1.0/24 via 10.99.99.60 dev n2n0 src 10.11.12.5`. +- **o**scar needs to know where to send packets to, too. So, on + **o**scar: `ip route add 10.11.12.5 via 10.99.99.50 dev n2n0 src 192.168.1.6`. + +**o**scar and **h**ickory should now be able to exchange packets by +using just their regular (non-n2n) IP addresses 10.11.12.5 and 192.168.1.6. +To make the complete office network aware of how packets or answers are +sent to **h**ickory, one more step is required: + +- Packets from any office computer to **h**ickory need to be directed to + **o**scar that – thanks to enabled IP forwarding and the routing rule – + already knows how to handle this kind of packets. + - To handle it in a one-stop-shop, the office router 192.168.1.1 can + be configured to direct those packets to **o**scar. Luckily, even most + modern small-office-and-home routers allow to add static routing rules + via a web interface. A rule like "All packets for host 10.11.12.5 (or + network 10.11.12.0/24) need to be sent to another router, namely + 192.168.1.5" will do. This is the **recommended** solution. + - However, a **less recommended** but working option would be to add + static routes to each single of those computers in the office network + that shall be able to connect to or be accessed by **h**ickory. On + those, e.g. **o**livia with IP address 192.168.1.123: `ip route add 10.11.12.5 via 192.168.1.5 dev eth0 src 192.168.1.123`. + - Alternatively, in case the office router does not allow to have + added own static routing rules, **o**scar needs to perform NAT for all + connections initiated from **h**ickory: + `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE` + `iptables -A FORWARD -i eth0 -o n2n0 -m state --state RELATED,ESTABLISHED -j ACCEPT` + `iptables -A FORWARD -i n2n0 -o eth0 -j ACCEPT` + There is a major drawback with this solution which thus is the **least + recommended**: Connections between **h**ickory and the office network + will only work if initiated by **h**ickory – not the other way 'round. + By the way, in case _iptables_ are messed up, they can be flushed by: + `iptables -F` + `iptables -X` + `iptables -t nat -F` + `iptables -t nat -X` + `iptables -t mangle -F` + `iptables -t mangle -X` + `iptables -t raw -F` + `iptables -t raw -X` + `iptables -t security -F` + `iptables -t security -X` + `iptables -P INPUT ACCEPT` + `iptables -P FORWARD ACCEPT` + `iptables -P OUTPUT ACCEPT` + +### Reach n2n Node in Office from Whole Home Network + +This is easy: + +- Just exchange home and office IP addresses and the computer names in + the instructions given above. + +### Reach Whole Home Network from Whole Office Network + +This is not too complicated either. Basically, follow the given example +above and apply the following changes: + +- The instructions used above need to be expanded from **h**ickory's IP + 10.11.12.5 to its full network 10.11.12.0/24 in the route commands on + **o**scar:, especially: `ip route add 10.11.12.0/24 via 10.99.99.50 dev n2n0 src 192.168.1.6`. +- In case of adding a static route to the office network router + 192.168.1.1, the home network 10.11.12.0/24 must be specified instead of + **h**ickory's more specific IP address 11.11.12.5. Same for the less + recommended static routes on other office computers. +- Packets from home network's computers to the office network need to be + sent through the n2n tunnel. The three alternatives given above can be + used just with exchanged office and home IP addresses. One needs to be + aware that NAT only (third alternative) on both sides will not allow any + connection, i.e. at least on one side static routes need to be added + either to the router (best option) or all those computers that shall be + able to connect to the other network. + +### Route All Internet Traffic from n2n Node at Home through Office Network + +This scenario could be considered a n2n-tunneled VPN connection which +also would work for travelling users on their laptop. All external +internet traffic will appear to originate from **o**scar and the office +network. + +- First, one of the setups described above needs to be in place, with + the following change: +- NAT on **o**scar (see the three _iptables_ commands above) must be + enabled. It will not work without because the office router 192.168.1.1 + usually denies forwarding to packets not originating from its own + network. It could be in addition to the eventually installed static + routes for 10.11.12.0/24 in the router 192.168.1.1 or on other office + computers – it will not interfere. However, **o**scar definitely needs + the route given above: `ip route add 10.11.12.5 via 10.99.99.50 dev n2n0 src 192.168.1.6`. +- To have **h**ickory's complete internet traffic going through the n2n + tunnel, its default route needs to be changed: + `ip route del default` + `ip route add default via 10.99.99.60 dev n2n0 src 10.11.12.5` + +- **h**ickory's home network should still be reachable as usually, + _eth0_ and the associated network 10.11.12.0/24 get their very own + route. If not, i.e. it was only covered by default route before, it + needs to be added: `ip route add 10.11.12.0/24 dev eth0 src 10.11.12.5`. +- Unfortunately (unless the supernode is on **h**ickory's local + network), n2n supernode becomes unreachable for **h**ickory. To fix it: + `ip route add via 10.11.12.1 dev eth0 src 10.11.12.5` + +The supernode's IP address needs to be known to have this work. However, +if the supernode's IP needs to be resolved from some domain name (FQDN), +e.g. in case of using dynamic domain name services, a DNS server needs +to remain reachable, too. Either the reachable home network router +10.11.12.1 is good enough for that (if it offers DNS) or another route +could to be added and **h**ickory's DNS settings might be set +accordingly, maybe to Google's 8.8.8.8. + +If [DNS leaks](https://en.wikipedia.org/wiki/DNS_leak) do not matter, +this setup is complete. + +### Preventing DNS Leaks + +Otherwise, there is more to it: Without changes, all future DNS queries +go through the home router 10.11.12.1 to the ISP's servers or directly +to Google (via the home router 10.11.12.1 along the configured route for +8.8.8.8 and not through the n2n tunnel) while the remaining traffic +ships through the n2n tunnel. + +To prevent such a DNS leak, the supernode's IP address must be +determined independently from **h**ickory's DNS configuration, e.g. by +digesting `dig +short mysupernode.myfavoritednsservice.com @8.8.8.8`'s +output in the n2n-edge's setup script for both, the edge node command +line as well as the static route mentioned above. Without further +additional work, dynamic address changes remain undetected. A static +route to 8.8.8.8 is still required. **h**ickory's regular DNS +configuration should query a different DNS server for its regular DNS +needs, e.g. 9.9.9.9 or 1.1.1.1 or maybe the office DNS server, maybe +192.168.1.1. This guarantees the regular DNS queries also to get sent +through the n2n tunnel. + +A test for DNS leaks can be found [here](https://www.dnsleaktest.com/). diff --git a/bundles/n2n_ntop_v2/doc/Windows.md b/bundles/n2n_ntop_v2/doc/Windows.md new file mode 100644 index 00000000..5edf60a9 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/Windows.md @@ -0,0 +1,73 @@ +# Build on Windows + +## Requirements + +In order to build on Windows the following tools should be installed: + +- Visual Studio. For a minimal install, the command line only build tools can be + downloaded and installed from https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2017 +- Cmake +- (optional) The OpenSSL library. Prebuild binaries can be downloaded from https://slproweb.com/products/Win32OpenSSL.html . + The full version is required (not the "Light" version). The Win32 version of it is usually required for a standard build. + + NOTE: in order to skip OpenSSL compilation, edit CMakeLists.txt and replace + + ```plaintext + OPTION(N2N_OPTION_AES "USE AES" ON) + with + OPTION(N2N_OPTION_AES "USE AES" OFF) + ``` + + NOTE: to static link OpenSSL, add the `-DOPENSSL_USE_STATIC_LIBS=true` option to the cmake command + +In order to run n2n: + +- The TAP drivers should be installed into the system. They can be installed from + http://build.openvpn.net/downloads/releases (search for "tap-windows") +- If OpenSSL has been linked dynamically, the corresponding .dll file should be available + into the target computer + +## Build (CLI) + +In order to build from the command line, open a terminal window and run the following commands: + +```batch +md build +cd build +cmake .. + +MSBuild edge.vcxproj /t:Build /p:Configuration=Release +MSBuild supernode.vcxproj /t:Build /p:Configuration=Release +``` + +NOTE: if cmake has problems finding the installed OpenSSL library, try to download the official cmake and invoke it with: +`C:\Program Files\CMake\bin\cmake` + +The compiled exe files should now be available under the Release directory. + +## Run + +The `edge.exe` program reads the `edge.conf` file located into the current directory if no option is provided. + +Here is an example `edge.conf` file: + +```plaintext +-c=mycommunity +-k=mysecretkey + +# supernode IP address +-l=1.2.3.4:5678 + +# edge IP address +-a=192.168.100.1 +``` + +The `supernode.exe` program reads the `supernode.conf` file located into the current directory if no option is provided. + +Here is an example `supernode.conf` file: + +```plaintext +-l=5678 +``` + +See `edge.exe --help` and `supernode.exe --help` for a list of supported options. diff --git a/bundles/n2n_ntop_v2/doc/macOS.md b/bundles/n2n_ntop_v2/doc/macOS.md new file mode 100644 index 00000000..f3c610e6 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/macOS.md @@ -0,0 +1,12 @@ +# n2n on macOS + +In order to use n2n on macOS, you first need to install support for TUN/TAP interfaces: + +```bash +brew tap homebrew/cask +brew cask install tuntap +``` + +If you are on a modern version of macOS (i.e. Catalina), the commands above will ask you to enable the TUN/TAP kernel extension in System Preferences → Security & Privacy → General. + +For more information refer to vendor documentation or the [Apple Technical Note](https://developer.apple.com/library/content/technotes/tn2459/_index.html). diff --git a/bundles/n2n_ntop_v2/doc/n2n_gateway.sh b/bundles/n2n_ntop_v2/doc/n2n_gateway.sh new file mode 100644 index 00000000..2bf4b843 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/n2n_gateway.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# +# This is a sample script to route all the host traffic towards a remote +# gateway, which is reacheable via the n2n virtual interface. +# +# This assumes the n2n connection is already been established and the +# VPN gateway can be pinged by this host. +# + +####################################################### +# CONFIG +####################################################### + +# The IP address of the gateway through the n2n interface +N2N_GATEWAY="192.168.100.1" + +# The IP address of the supernode as configured in n2n +N2N_SUPERNODE="1.2.3.4" + +# The n2n interface name +N2N_INTERFACE="n2n0" + +# The DNS server to use. Must be a public DNS or a DNS located on the +# N2N virtual network, otherwise DNS query information will be leaked +# outside the VPN. +DNS_SERVER="8.8.8.8" + +####################################################### +# END CONFIG +####################################################### + +if [[ $UID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if ! ip route get $N2N_GATEWAY | grep -q $N2N_INTERFACE ; then + echo "Cannot reach the gateway ($N2N_GATEWAY) via $N2N_INTERFACE. Is edge running?" + exit 1 +fi + +# Determine the current internet gateway +internet_gateway=`ip route get 8.8.8.8 | head -n1 | awk '{ print $3 }'` + +# Backup the DNS resolver configuration and use the specified server +cp /etc/resolv.conf /etc/resolv.conf.my_bak +echo "Using DNS server $DNS_SERVER" +echo "nameserver $DNS_SERVER" > /etc/resolv.conf + +# The public IP of the supernode must be reachable via the internet gateway +# Whereas all the other traffic will go through the new VPN gateway. +ip route add $N2N_SUPERNODE via $internet_gateway +ip route del default +echo "Forwarding traffic via $N2N_GATEWAY" +ip route add default via $N2N_GATEWAY + +function stopService { + echo "Deleting custom routes" + ip route del default + ip route del $N2N_SUPERNODE via $internet_gateway + + echo "Restoring original gateway $internet_gateway" + ip route add default via $internet_gateway + + echo "Restoring original DNS" + mv /etc/resolv.conf.my_bak /etc/resolv.conf + + exit 0 +} + +# setup signal handlers +trap "stopService" SIGHUP SIGINT SIGTERM + +# enter wait loop +echo "VPN is now up" +while :; do sleep 300; done diff --git a/bundles/n2n_ntop_v2/doc/new-features.md b/bundles/n2n_ntop_v2/doc/new-features.md new file mode 100644 index 00000000..b3e051cc --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/new-features.md @@ -0,0 +1,4 @@ +# New Features between 2.0.x and 2.1.x + +- Better ming Windows build support. +- Added `-E` flag to allow multicast ethernet traffic. diff --git a/bundles/n2n_ntop_v2/doc/rpm-packaging.md b/bundles/n2n_ntop_v2/doc/rpm-packaging.md new file mode 100644 index 00000000..b671a7f1 --- /dev/null +++ b/bundles/n2n_ntop_v2/doc/rpm-packaging.md @@ -0,0 +1,11 @@ +# RPM Packaging + +```bash +./autogen.sh +./configure +make + +cd packages/rpm +./configure +rpmbuild -bb ./n2n.spec +``` diff --git a/bundles/n2n_ntop_v2/edge.8 b/bundles/n2n_ntop_v2/edge.8 new file mode 100644 index 00000000..2e112c5a --- /dev/null +++ b/bundles/n2n_ntop_v2/edge.8 @@ -0,0 +1,234 @@ +.TH edge 8 "17 Mar 2010" "n2n-2.1" "SUPERUSER COMMANDS" +.SH NAME +edge \- n2n edge node daemon +.SH SYNOPSIS +.B edge +[\-d ] \-a \-c {\-k |\-K } +[\-s ] \-l [\-L ] +[\-p ] [\-u ] [\-g ] [-f] [\-m ] [\-r] [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Edge is the edge node daemon for n2n which +creates a TAP interface to expose the n2n virtual LAN. On startup n2n creates +the TAP interface and configures it then registers with the supernode so it can +begin to find other nodes in the community. +.PP +.SH OPTIONS +.TP +\-d +sets the TAP device name as seen in ifconfig. Only available on Linux. +.TP +\-a {|static:|dhcp:0.0.0.0} +sets the n2n virtual LAN IP address being claimed. This is a private IP +address. All IP addresses in an n2n community typical belong to the same /24 +network (ie. only the last octet of the IP addresses varies). If DHCP is used to +assign interface addresses then specify the address as +.B -a dhcp:0.0.0.0 +.TP +\-b +cause edge to perform hostname resolution for the supernode address each time +the supernode is periodically contacted. This can cause reliability problems +because all packet processing stops while the supernode address is resolved +which might take 15 seconds. +.TP +\-c +sets the n2n community name. All edges within the same community appear on the +same LAN (layer 2 network segment). Community name is 16 bytes in length. A name +smaller than this is padded with 0x00 bytes and a name longer than this is +truncated to take the first 16 bytes. +.TP +\-h +write usage then exit. +.TP +\-i +Supernode registration interval. It specifies the interval in seconds +between consecutive REGISTER_SUPER packets and it's used to keep NAT hole +open via the UDP NAT hole punching technique. This only works for asymmetric +NATs and allows for P2P communication. +.TP +\-k +sets the twofish encryption key from ASCII text (see also N2N_KEY in +ENVIRONMENT). All edges communicating must use the same key and community +name. If neither -k nor -K is used to specify a key source then edge uses +cleartext mode (no encryption). The -k and -K options are mutually exclusive. +.TP +\-K +Reads a key-schedule file and populates the internal transform +operations with the data found there. This mechanism allows keys to roll at +pre-determined times for a group of hosts. Accurate time synchronisation is not +required as older keys can be decoded for some time after expiry. If neither -k +nor -K is used to specify a key source then edge uses cleartext mode (no +encryption). The -k and -K options are mutually exclusive. +.TP +\-l : +sets the n2n supernode IP address and port to register to. Up to 2 supernodes +can be specified by two invocations of -l :. eg. +.B edge -l 12.34.56.78:7654 -l 98.76.54.32:7654 +. +.TP +\-p +binds edge to the given UDP port. Useful for keeping the same external socket +across restarts of edge. This allows peer edges which know the edge socket to +continue p2p operation without going back to the supernode. +.TP +\-t +binds the edge management system to the given UDP port. Default 5644. Use this +if you need to run multiple instance of edge; or something is bound to that +port. +.TP +\-u +causes the edge process to drop to the given user ID when privileges are no +longer required (UNIX). +.TP +\-g +causes the edge process to drop to the given group ID when privileges are no +longer required (UNIX). +.TP +\-f +disables daemon mode (UNIX) and causes edge to run in the foreground. +.TP +\-m +start the TAP interface with the given MAC address. This is highly recommended +as it means the same address will be used if edge stops and restarts. If this is +not done, the ARP caches of all peers will be wrong and packets will not flow to +this edge until the next ARP refresh. +.TP +\-M +set the MTU of the edge interface in bytes. MTU is the largest packet fragment +size allowed to be moved throught the interface. The default is 1400. +.TP +\-s +set the netmask of edge interface in IPv4 dotted decimal notation. The default +is 255.255.255.0 (ie. /24). +.TP +\-r +enable IP packet forwarding/routing through the n2n virtual LAN. Without this +option, IP packets arriving over n2n are dropped if not for the -a (or +DHCP assigned) IP address of the edge interface. +.TP +\-E +accept packets destined for multicast ethernet MAC addresses. These addresses +are used in multicast ethernet and IPv6 neighbour discovery. If this option is +not present these multicast packets are discarded as most users do not need or +understand them. +.TP +\-L +set the TTL for the hole punching packet. This is an advanced flag to make +sure that the registration packet is dropped immediately when it goes out of +local nat so that it will not trigger some firewall behavior on target peer. +Actually, the registration packet is only expected to make local nat UDP hole +and is not expected to reach the target peer, see +https://tools.ietf.org/html/rfc5389. To achieve this, the flag should be set as +nat level + 1. For example, if we have 2 layer nat in local, we should set -L 3. +Usually we know exactly how much nat layers in local. +If we are not sure how much nat layers in local, we can use traceroute on +Linux to check. The following example shows a local single layer nat because on +second jump it shows a public ip address. In this case it should set -L 2. + +$ /usr/sbin/traceroute -w1 8.8.8.8 +traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets + 1 192.168.3.1 (192.168.3.1) 0.464 ms 0.587 ms 0.719 ms + 2 112.65.17.217 (112.65.17.217) 5.269 ms 7.031 ms 8.666 ms + +But this method does not always work due to various local network device policy. +.TP +\-v +more verbose logging (may be specified several times for more verbosity). +.SH ENVIRONMENT +.TP +.B N2N_KEY +set the encryption key so it is not visible on the command line +.SH EXAMPLES +.TP +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-p 50001 \-l 123.121.120.119:7654 + +Start edge with TAP device n2n0 on community "mynetwork" with community +supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to +50001. Use "encryptme" as the single permanent shared encryption key. Assign MAC +address DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 +after the TAP device is successfull configured. +.PP +Add the -f option to stop edge running as a daemon. +.PP +Somewhere else setup another edge with similar parameters, eg. + +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP +Now you can ping from 192.168.254.5 to 192.168.254.7. +.PP +The MAC address (-m ) and virtual IP address (-a ) must be different +on all edges in the same community. + +.SH KEY SCHEDULE FILES +(See +.B n2n_v2(7) +for more details). + +The -K option reads a key schedule file. + +.B edge \-d n2n0 \-c mynetwork \-K /path/to/file \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP + +The key schedule file consists of line, one per key in the schedule. The purpose +of key schedules is to encourage regular changing of the encryption keys used by +a community. The file structure also allows for full binary keys to be specified +as compared to the ASCII keys allowed by the single key injection. Each key line +consists of the following: + +.B + + and are ASCII decimal values of the UNIX times during which the +key is valid. is the index of the transform that applies +to. is some text which is parsed by the transform module to derive the +key for that line. + +Supported values are: +.TP +2 = TwoFish + has the form _. eg. + +.B 1252327945 1252328305 2 602_3d7c7769b34b2a4812f8c0e9d87ce9 + +This specifies security association number 602 and a 16-octet key of numeric +value 0x3d7c7769b34b2a4812f8c0e9d87ce9. is a 32-bit unsigned integer which +is used to identify the encryption key to the receiver. The SA number is sent +unencrypted so the receiver may find the correct key from the key +schedule. is up to 16 octets although shorter keys are allowed. + +.TP +3 = AES-CBC + has the form _. Same rules as TwoFish. + +.SH CLEARTEXT MODE +If neither +.B -k +nor +.B -K +is specified then edge uses cleartext mode. In cleartext mode there is no +transform of the packet data it is simply encrypted. This is useful for +debugging n2n as packet contents can be seen clearly. + +To prevent accidental exposure of data, edge only enters cleartext mode when no +keying parameters are specified. In the case where keying parameters are +specified but no valid keys can be determined, edge exits with an error at +startup. If all keys become invalid while running, edge continues to encode +using the last key that was valid. + +.SH MANAGEMENT INTERFACE +Edge provides a very simple management system on UDP port 5644. Send a newline +to receive a status output. Send 'reload' to cause re-read of the +keyfile. Send 'stop' to cause edge to exit cleanly. + +.SH EXIT STATUS +edge is a daemon and any exit is an error. +.SH AUTHORS +.TP +Richard Andrews +andrews (at) ntop.org - n2n-1 maintainer and main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - original author of n2n +.TP +Don Bindner +(--) - significant contributions to n2n-1 +.SH SEE ALSO +ifconfig(8) supernode(1) tunctl(8) n2n_v2(7) diff --git a/bundles/n2n_ntop_v2/include/edge_utils_win32.h b/bundles/n2n_ntop_v2/include/edge_utils_win32.h new file mode 100644 index 00000000..c4efc742 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/edge_utils_win32.h @@ -0,0 +1,44 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _EDGE_UTILS_WIN32_H_ +#define _EDGE_UTILS_WIN32_H_ + +#ifdef WIN32 + +#define WIN32_LEAN_AND_MEAN + +#include +#include + + +/* Multicast peers discovery disabled due to https://github.com/ntop/n2n/issues/65 */ +#define SKIP_MULTICAST_PEERS_DISCOVERY + +struct tunread_arg { + n2n_edge_t *eee; + int *keep_running; +}; + +extern HANDLE startTunReadThread(struct tunread_arg *arg); + + +#endif /* WIN32 */ + +#endif /* _EDGE_UTILS_WIN32_H_ */ + diff --git a/bundles/n2n_ntop_v2/include/header_encryption.h b/bundles/n2n_ntop_v2/include/header_encryption.h new file mode 100644 index 00000000..9ed7eafe --- /dev/null +++ b/bundles/n2n_ntop_v2/include/header_encryption.h @@ -0,0 +1,32 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len, + char * community_name, he_context_t * ctx, + he_context_t * ctx_iv, + uint64_t * stamp, uint16_t * checksum); + +int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx, + he_context_t * ctx_iv, + uint64_t stamp, uint16_t checksum); + + +void packet_header_setup_key (const char * community_name, he_context_t ** ctx, + he_context_t ** ctx_iv); + diff --git a/bundles/n2n_ntop_v2/include/lzoconf.h b/bundles/n2n_ntop_v2/include/lzoconf.h new file mode 100644 index 00000000..cc437f1e --- /dev/null +++ b/bundles/n2n_ntop_v2/include/lzoconf.h @@ -0,0 +1,417 @@ +/* lzoconf.h -- configuration for the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED + +#define LZO_VERSION 0x2030 +#define LZO_VERSION_STRING "2.03" +#define LZO_VERSION_DATE "Apr 30 2008" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +#if !defined(LZO_UINT32_C) +# if (UINT_MAX < LZO_0xffffffffL) +# define LZO_UINT32_C(c) c ## UL +# else +# define LZO_UINT32_C(c) ((c) + 0U) +# endif +#endif + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint should match size_t */ +#if !defined(LZO_UINT_MAX) +# if defined(LZO_ABI_LLP64) /* WIN64 */ +# if defined(LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# else + typedef unsigned long long lzo_uint; + typedef long long lzo_int; +# endif +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* Integral types with 32 bits or more. */ +#if !defined(LZO_UINT32_MAX) +# if (UINT_MAX >= LZO_0xffffffffL) + typedef unsigned int lzo_uint32; + typedef int lzo_int32; +# define LZO_UINT32_MAX UINT_MAX +# define LZO_INT32_MAX INT_MAX +# define LZO_INT32_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint32; + typedef long lzo_int32; +# define LZO_UINT32_MAX ULONG_MAX +# define LZO_INT32_MAX LONG_MAX +# define LZO_INT32_MIN LONG_MIN +# else +# error "lzo_uint32" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32. */ +#if (LZO_UINT_MAX >= LZO_UINT32_MAX) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32 +#endif + +/* Memory model that allows to access memory at offsets of lzo_uint. */ +#if !defined(__LZO_MMODEL) +# if (LZO_UINT_MAX <= UINT_MAX) +# define __LZO_MMODEL +# elif defined(LZO_HAVE_MM_HUGE_PTR) +# define __LZO_MMODEL_HUGE 1 +# define __LZO_MMODEL __huge +# else +# define __LZO_MMODEL +# endif +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_uint32p lzo_uint32 __LZO_MMODEL * +#define lzo_int32p lzo_int32 __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * +/* deprecated - use `lzo_bytep' instead of `lzo_byte *' */ +#define lzo_byte unsigned char __LZO_MMODEL + +typedef int lzo_bool; + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) +lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); +LZO_EXTERN(lzo_voidp) +lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32) +lzo_adler32(lzo_uint32 _adler, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(lzo_uint32) +lzo_crc32(lzo_uint32 _c, const lzo_bytep _buf, lzo_uint _len); +LZO_EXTERN(const lzo_uint32p) +lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; +typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; +typedef union { void *vp; lzo_bytep bp; lzo_uint32 u32; long l; } lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of `size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); +#define LZO_PTR_ALIGN_UP(_ptr,_size) \ + ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility with LZO v1.xx +************************************************************************/ + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL +#define __LZO_DMODEL +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_ntop_v2/include/lzodefs.h b/bundles/n2n_ntop_v2/include/lzodefs.h new file mode 100644 index 00000000..18056372 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/lzodefs.h @@ -0,0 +1,1807 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif /* already included */ + +/* vim:set ts=4 et: */ diff --git a/bundles/n2n_ntop_v2/include/minilzo.h b/bundles/n2n_ntop_v2/include/minilzo.h new file mode 100644 index 00000000..0aff50e4 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/minilzo.h @@ -0,0 +1,106 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H + +#define MINILZO_VERSION 0x2030 + +#ifdef __LZOCONF_H +# error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/bundles/n2n_ntop_v2/include/n2n.h b/bundles/n2n_ntop_v2/include/n2n.h new file mode 100644 index 00000000..78ab5d5a --- /dev/null +++ b/bundles/n2n_ntop_v2/include/n2n.h @@ -0,0 +1,485 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _N2N_H_ +#define _N2N_H_ + +/* + tunctl -t tun0 + tunctl -t tun1 + ifconfig tun0 1.2.3.4 up + ifconfig tun1 1.2.3.5 up + ./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello + ./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello + + + tunctl -u UID -t tunX +*/ + + +/* #define N2N_CAN_NAME_IFACE */ + +/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */ +#ifdef WIN32 +#include "win32/n2n_win32.h" + +#ifndef CMAKE_BUILD +#include "config.h" /* Visual C++ */ +#else +#include "win32/winconfig.h" +#endif +#define N2N_CAN_NAME_IFACE 1 +#undef N2N_HAVE_DAEMON +#undef N2N_HAVE_SETUID +#else +#ifndef CMAKE_BUILD +#include "config.h" +#endif +#endif + + + +#define PACKAGE_BUILDDATE (__DATE__ " " __TIME__) + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#ifndef _MSC_VER +#include +#endif /* #ifndef _MSC_VER */ + +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include + +#ifdef __linux__ +#define N2N_CAN_NAME_IFACE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define GRND_NONBLOCK 1 +#endif /* #ifdef __linux__ */ + +#ifdef __FreeBSD__ +#include +#endif /* #ifdef __FreeBSD__ */ + +#include +#include + +#if defined (__RDRND__) || defined (__RDSEED__) +#include +#endif + +#define ETH_ADDR_LEN 6 + +struct ether_hdr +{ + uint8_t dhost[ETH_ADDR_LEN]; + uint8_t shost[ETH_ADDR_LEN]; + uint16_t type; /* higher layer protocol encapsulated */ +} __attribute__ ((__packed__)); + +typedef struct ether_hdr ether_hdr_t; + +#ifdef HAVE_LIBZSTD +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef N2N_HAVE_AES +#include +#include +#endif + + +#define closesocket(a) close(a) +#endif /* #ifndef WIN32 */ + +#include "minilzo.h" +#include "n2n_define.h" +#include +#include +#include +#include "uthash.h" +#include "lzoconf.h" + +#ifdef WIN32 +#include "win32/wintap.h" +#include +#else +#include +#endif /* #ifdef WIN32 */ + +#include "n2n_wire.h" +#include "n2n_transforms.h" +#include "random_numbers.h" +#include "pearson.h" +#include "portable_endian.h" +#include "speck.h" + +#ifdef WIN32 +#define N2N_IFNAMSIZ 64 +#else +#define N2N_IFNAMSIZ 16 /* 15 chars * NULL */ +#endif + +#ifndef WIN32 +typedef struct tuntap_dev { + int fd; + int if_idx; + uint8_t mac_addr[6]; + uint32_t ip_addr, device_mask; + uint16_t mtu; + char dev_name[N2N_IFNAMSIZ]; +} tuntap_dev; + +#define SOCKET int +#endif /* #ifndef WIN32 */ + +/** Uncomment this to enable the MTU check, then try to ssh to generate a fragmented packet. */ +/** NOTE: see doc/MTU.md for an explanation on the 1400 value */ +//#define MTU_ASSERT_VALUE 1400 + +/** Common type used to hold stringified IP addresses. */ +typedef char ipstr_t[32]; + +/** Common type used to hold stringified MAC addresses. */ +#define N2N_MACSTR_SIZE 32 +typedef char macstr_t[N2N_MACSTR_SIZE]; + +struct peer_info { + n2n_mac_t mac_addr; + n2n_sock_t sock; + int timeout; + time_t last_seen; + time_t last_p2p; + time_t last_sent_query; + uint64_t last_valid_time_stamp; + + UT_hash_handle hh; /* makes this structure hashable */ +}; + +typedef struct speck_context_t he_context_t; +typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; + +typedef struct n2n_route { + in_addr_t net_addr; + int net_bitlen; + in_addr_t gateway; +} n2n_route_t; + +typedef struct n2n_edge n2n_edge_t; + +/* *************************************************** */ + +typedef enum { + N2N_ACCEPT = 0, + N2N_DROP = 1 +} n2n_verdict; + +/* *************************************************** */ + +/* Callbacks allow external programs to attach functions in response to + * N2N events. */ +typedef struct n2n_edge_callbacks { + /* The supernode registration has been updated */ + void (*sn_registration_updated)(n2n_edge_t *eee, time_t now, const n2n_sock_t *sn); + + /* A packet has been received from a peer. N2N_DROP can be returned to + * drop the packet. The packet payload can be modified. This only allows + * the packet size to be reduced */ + n2n_verdict (*packet_from_peer)(n2n_edge_t *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t *payload_size); + + /* A packet has been received from the TAP interface. N2N_DROP can be + * returned to drop the packet. The packet payload can be modified. + * This only allows the packet size to be reduced */ + n2n_verdict (*packet_from_tap)(n2n_edge_t *eee, uint8_t *payload, uint16_t *payload_size); + + /* Called whenever the IP address of the TAP interface changes. */ + void (*ip_address_changed)(n2n_edge_t *eee, uint32_t old_ip, uint32_t new_ip); + + /* Called periodically in the main loop. */ + void (*main_loop_period)(n2n_edge_t *eee, time_t now); +} n2n_edge_callbacks_t; + +/* ***************************************************** */ + +typedef struct n2n_tuntap_priv_config { + char tuntap_dev_name[N2N_IFNAMSIZ]; + char ip_mode[N2N_IF_MODE_SIZE]; + char ip_addr[N2N_NETMASK_STR_SIZE]; + char netmask[N2N_NETMASK_STR_SIZE]; + char device_mac[N2N_MACNAMSIZ]; + int mtu; + uint8_t got_s; + uint8_t daemon; +#ifndef WIN32 + uid_t userid; + gid_t groupid; +#endif +} n2n_tuntap_priv_config_t; + +/* *************************************************** */ + +typedef struct n2n_edge_conf { + n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES]; + n2n_route_t *routes; /**< Networks to route through n2n */ + n2n_community_t community_name; /**< The community. 16 full octets. */ + uint8_t header_encryption; /**< Header encryption indicator. */ + he_context_t *header_encryption_ctx; /**< Header encryption cipher context. */ + he_context_t *header_iv_ctx; /**< Header IV ecnryption cipher context, REMOVE as soon as seperte fileds for checksum and replay protection available */ + n2n_transform_t transop_id; /**< The transop to use. */ + uint16_t compression; /**< Compress outgoing data packets before encryption */ + uint16_t num_routes; /**< Number of routes in routes */ + uint8_t dyn_ip_mode; /**< Interface IP address is dynamically allocated, eg. DHCP. */ + uint8_t allow_routing; /**< Accept packet no to interface address. */ + uint8_t drop_multicast; /**< Multicast ethernet addresses. */ + uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */ + uint8_t allow_p2p; /**< Allow P2P connection */ + uint8_t sn_num; /**< Number of supernode addresses defined. */ + uint8_t tos; /** TOS for sent packets */ + char *encrypt_key; + int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */ + int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */ + int local_port; + int mgmt_port; +} n2n_edge_conf_t; + +struct n2n_edge_stats { + uint32_t tx_p2p; + uint32_t rx_p2p; + uint32_t tx_sup; + uint32_t rx_sup; + uint32_t tx_sup_broadcast; + uint32_t rx_sup_broadcast; +}; + +struct n2n_edge { + n2n_edge_conf_t conf; + + /* Status */ + uint8_t sn_idx; /**< Currently active supernode. */ + uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */ + size_t sup_attempts; /**< Number of remaining attempts to this supernode. */ + tuntap_dev device; /**< All about the TUNTAP device */ + n2n_trans_op_t transop; /**< The transop to use when encoding */ + n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */ + n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */ + n2n_edge_callbacks_t cb; /**< API callbacks */ + void *user_data; /**< Can hold user data */ + uint64_t sn_last_valid_time_stamp;/*< last valid time stamp from supernode */ + + /* Sockets */ + n2n_sock_t supernode; + int udp_sock; + int udp_mgmt_sock; /**< socket for status info. */ + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */ + int udp_multicast_sock; /**< socket for local multicast registrations. */ + int multicast_joined; /**< 1 if the group has been joined.*/ +#endif + + /* Peers */ + struct peer_info * known_peers; /**< Edges we are connected to. */ + struct peer_info * pending_peers; /**< Edges we have tried to register with. */ + + /* Timers */ + time_t last_register_req; /**< Check if time to re-register with super*/ + time_t last_p2p; /**< Last time p2p traffic was received. */ + time_t last_sup; /**< Last time a packet arrived from supernode. */ + time_t start_time; /**< For calculating uptime */ + + /* Statistics */ + struct n2n_edge_stats stats; + /* Tuntap config */ + n2n_tuntap_priv_config_t tuntap_priv_conf; +}; + +typedef struct sn_stats +{ + size_t errors; /* Number of errors encountered. */ + size_t reg_super; /* Number of REGISTER_SUPER requests received. */ + size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ + size_t fwd; /* Number of messages forwarded. */ + size_t broadcast; /* Number of messages broadcast to a community. */ + time_t last_fwd; /* Time when last message was forwarded. */ + time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ +} sn_stats_t; + +struct sn_community +{ + char community[N2N_COMMUNITY_SIZE]; + uint8_t header_encryption; /* Header encryption indicator. */ + he_context_t *header_encryption_ctx; /* Header encryption cipher context. */ + he_context_t *header_iv_ctx; /* Header IV ecnryption cipher context, REMOVE as soon as seperate fields for checksum and replay protection available */ + struct peer_info *edges; /* Link list of registered edges. */ + int64_t number_enc_packets; /* Number of encrypted packets handled so far, required for sorting from time to time */ + + UT_hash_handle hh; /* makes this structure hashable */ +}; + +typedef struct n2n_sn +{ + time_t start_time; /* Used to measure uptime. */ + sn_stats_t stats; + int daemon; /* If non-zero then daemonise. */ + uint16_t lport; /* Local UDP port to bind to. */ + uint16_t mport; /* Management UDP port to bind to. */ + int sock; /* Main socket for UDP traffic with edges. */ + int mgmt_sock; /* management socket. */ +#ifndef WIN32 + uid_t userid; + gid_t groupid; +#endif + int lock_communities; /* If true, only loaded communities can be used. */ + struct sn_community *communities; +} n2n_sn_t; + +/* ************************************** */ + +#include "header_encryption.h" +#include "twofish.h" + +#ifndef TRACE_ERROR +#define TRACE_ERROR 0, __FILE__, __LINE__ +#define TRACE_WARNING 1, __FILE__, __LINE__ +#define TRACE_NORMAL 2, __FILE__, __LINE__ +#define TRACE_INFO 3, __FILE__, __LINE__ +#define TRACE_DEBUG 4, __FILE__, __LINE__ +#endif + +/* ************************************** */ + +/* Transop Init Functions */ +int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +int n2n_transop_twofish_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +#ifdef N2N_HAVE_AES +int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +#endif +#ifdef HAVE_OPENSSL_1_1 +int n2n_transop_cc20_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +#endif +int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); + +/* Log */ +void setTraceLevel(int level); +void setUseSyslog(int use_syslog); +void setTraceFile(FILE *f); +int getTraceLevel(); +void closeTraceFile(); +void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); + +/* Tuntap API */ +int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, + char *device_mask, const char * device_mac, int mtu); +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); +void tuntap_close(struct tuntap_dev *tuntap); +void tuntap_get_address(struct tuntap_dev *tuntap); + +/* Utils */ +char* intoa(uint32_t addr, char* buf, uint16_t buf_len); +char* macaddr_str(macstr_t buf, const n2n_mac_t mac); +int str2mac( uint8_t * outmac /* 6 bytes */, const char * s ); +uint8_t is_multi_broadcast(const uint8_t * dest_mac); +char* msg_type2str(uint16_t msg_type); +void hexdump(const uint8_t * buf, size_t len); +void print_n2n_version(); +int is_empty_ip_address(const n2n_sock_t * sock); +void print_edge_stats(const n2n_edge_t *eee); + +/* Sockets */ +char* sock_to_cstr( n2n_sock_str_t out, + const n2n_sock_t * sock ); +SOCKET open_socket(int local_port, int bind_any); +int sock_equal( const n2n_sock_t * a, + const n2n_sock_t * b ); + +/* Header encryption */ +uint64_t time_stamp(void); +uint64_t initial_time_stamp (void); +int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp); + +/* Operations on peer_info lists. */ +size_t purge_peer_list( struct peer_info ** peer_list, + time_t purge_before ); +size_t clear_peer_list( struct peer_info ** peer_list ); +size_t purge_expired_registrations( struct peer_info ** peer_list, time_t* p_last_purge ); + +/* Edge conf */ +void edge_init_conf_defaults(n2n_edge_conf_t *conf); +int edge_verify_conf(const n2n_edge_conf_t *conf); +int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port); +const n2n_edge_conf_t* edge_get_conf(const n2n_edge_t *eee); +void edge_term_conf(n2n_edge_conf_t *conf); + +/* Public functions */ +n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv); +void edge_term(n2n_edge_t *eee); +void edge_set_callbacks(n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks); +void edge_set_userdata(n2n_edge_t *eee, void *user_data); +void* edge_get_userdata(n2n_edge_t *eee); +void edge_send_packet2net(n2n_edge_t *eee, uint8_t *tap_pkt, size_t len); +void edge_read_from_tap(n2n_edge_t *eee); +int edge_get_n2n_socket(n2n_edge_t *eee); +int edge_get_management_socket(n2n_edge_t *eee); +int run_edge_loop(n2n_edge_t *eee, int *keep_running); +int quick_edge_init(char *device_name, char *community_name, + char *encrypt_key, char *device_mac, + char *local_ip_address, + char *supernode_ip_address_port, + int *keep_on_running); +int sn_init(n2n_sn_t *sss); +void sn_term(n2n_sn_t *sss); +int run_sn_loop(n2n_sn_t *sss, int *keep_running); +const char* compression_str(uint8_t cmpr); +const char* transop_str(enum n2n_transform tr); + +#endif /* _N2N_H_ */ diff --git a/bundles/n2n_ntop_v2/include/n2n_define.h b/bundles/n2n_ntop_v2/include/n2n_define.h new file mode 100644 index 00000000..4d3c48b6 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/n2n_define.h @@ -0,0 +1,114 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* N2N packet header indicators. */ +#define MSG_TYPE_REGISTER 1 +#define MSG_TYPE_DEREGISTER 2 +#define MSG_TYPE_PACKET 3 +#define MSG_TYPE_REGISTER_ACK 4 +#define MSG_TYPE_REGISTER_SUPER 5 +#define MSG_TYPE_REGISTER_SUPER_ACK 6 +#define MSG_TYPE_REGISTER_SUPER_NAK 7 +#define MSG_TYPE_FEDERATION 8 +#define MSG_TYPE_PEER_INFO 9 +#define MSG_TYPE_QUERY_PEER 10 +#define MSG_TYPE_MAX_TYPE 10 + +#define SOCKET_TIMEOUT_INTERVAL_SECS 10 +#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */ + +#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ +#define TRANSOP_TICK_INTERVAL (10) /* sec */ + +#define PURGE_REGISTRATION_FREQUENCY 30 +#define REGISTRATION_TIMEOUT 60 + +#define SORT_COMMUNITIES_INTERVAL 90 /* sec. until supernode sorts communities' hash list again */ + +#define ETH_FRAMESIZE 14 +#define IP4_SRCOFFSET 12 +#define IP4_DSTOFFSET 16 +#define IP4_MIN_SIZE 20 +#define UDP_SIZE 8 + +/* parameters for replay protection */ +#define TIME_STAMP_FRAME 0x0000001000000000LL /* clocks of different computers are allowed +/- 16 seconds to be off */ +#define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another + * set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */ + +/* parameter for random number generation */ +#define RND_RETRIES 1000 /* syscall and inquiring random number from hardware generators might fail, so we will retry */ + +/* N2N compression indicators. */ +/* Compression is disabled by default for outgoing packets if no cli + * option is given. All edges are built with decompression support so + * they are able to understand each other (this applies to lzo only). */ +#define N2N_COMPRESSION_ID_NONE 0 /* default, see edge_init_conf_defaults(...) in edge_utils.c */ +#define N2N_COMPRESSION_ID_LZO 1 /* set if '-z1' or '-z' cli option is present, see setOption(...) in edge.c */ +#ifdef N2N_HAVE_ZSTD +#define N2N_COMPRESSION_ID_ZSTD 2 /* set if '-z2' cli option is present, available only if compiled with zstd lib */ +#define ZSTD_COMPRESSION_LEVEL 7 /* 1 (faster) ... 22 (more compression) */ +#endif +// with the next major packet structure update, make '0' = invalid, and '1' = no compression +// '2' = LZO, '3' = ZSTD, ... REVISIT then (also: change all occurences in source). + +#define N2N_COMPRESSION_ID_BITLEN 3 /* number of bits used for encoding compression id in the uppermost + bits of transform_id; will be obsolete as soon as compression gets + its own field in the packet. REVISIT then. */ + +/* Header encryption indicators */ +#define HEADER_ENCRYPTION_UNKNOWN 0 +#define HEADER_ENCRYPTION_NONE 1 +#define HEADER_ENCRYPTION_ENABLED 2 + +#define DEFAULT_MTU 1290 + +#define HASH_ADD_PEER(head,add) \ + HASH_ADD(hh,head,mac_addr,sizeof(n2n_mac_t),add) +#define HASH_FIND_PEER(head,mac,out) \ + HASH_FIND(hh,head,mac,sizeof(n2n_mac_t),out) +#define N2N_EDGE_SN_HOST_SIZE 48 +#define N2N_EDGE_NUM_SUPERNODES 2 +#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ +#define N2N_PATHNAME_MAXLEN 256 +#define N2N_EDGE_MGMT_PORT 5644 +#define N2N_SN_MGMT_PORT 5645 + +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ +#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ +#define N2N_IF_MODE_SIZE 16 /* static | dhcp */ + +#define N2N_SN_LPORT_DEFAULT 7654 +#define N2N_SN_PKTBUF_SIZE 2048 + + +/* ************************************** */ + +#define SUPERNODE_IP "127.0.0.1" +#define SUPERNODE_PORT 1234 + +/* ************************************** */ + +#ifndef max +#define max(a, b) ((a < b) ? b : a) +#endif + +#ifndef min +#define min(a, b) ((a > b) ? b : a) +#endif + diff --git a/bundles/n2n_ntop_v2/include/n2n_transforms.h b/bundles/n2n_ntop_v2/include/n2n_transforms.h new file mode 100644 index 00000000..589e36bb --- /dev/null +++ b/bundles/n2n_ntop_v2/include/n2n_transforms.h @@ -0,0 +1,68 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#if !defined(N2N_TRANSFORMS_H_) +#define N2N_TRANSFORMS_H_ + +#include +#include "n2n_wire.h" + +#define N2N_TRANSFORM_ID_USER_START 64 +#define N2N_TRANSFORM_ID_MAX 65535 + +typedef enum n2n_transform { + N2N_TRANSFORM_ID_INVAL = 0, + N2N_TRANSFORM_ID_NULL = 1, + N2N_TRANSFORM_ID_TWOFISH = 2, + N2N_TRANSFORM_ID_AESCBC = 3, + N2N_TRANSFORM_ID_CHACHA20 = 4, + N2N_TRANSFORM_ID_SPECK = 5, +} n2n_transform_t; + +struct n2n_trans_op; + +typedef int (*n2n_transdeinit_f)( struct n2n_trans_op * arg ); +typedef void (*n2n_transtick_f)( struct n2n_trans_op * arg, time_t now ); +typedef int (*n2n_transform_f)( struct n2n_trans_op * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const n2n_mac_t peer_mac); + +/** Holds the info associated with a data transform plugin. + * + * When a packet arrives the transform ID is extracted. This defines the code + * to use to decode the packet content. The transform code then decodes the + * packet and consults its internal key lookup. + */ +typedef struct n2n_trans_op { + void * priv; /* opaque data. Key schedule goes here. */ + uint8_t no_encryption; /* 1 if this transop does not perform encryption */ + n2n_transform_t transform_id; + size_t tx_cnt; + size_t rx_cnt; + + n2n_transdeinit_f deinit; /* destructor function */ + n2n_transtick_f tick; /* periodic maintenance */ + n2n_transform_f fwd; /* encode a payload */ + n2n_transform_f rev; /* decode a payload */ +} n2n_trans_op_t; + +#endif /* #if !defined(N2N_TRANSFORMS_H_) */ + diff --git a/bundles/n2n_ntop_v2/include/n2n_wire.h b/bundles/n2n_ntop_v2/include/n2n_wire.h new file mode 100644 index 00000000..7cd0e41e --- /dev/null +++ b/bundles/n2n_ntop_v2/include/n2n_wire.h @@ -0,0 +1,338 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#if !defined( N2N_WIRE_H_ ) +#define N2N_WIRE_H_ + +#include + +#if defined(WIN32) +#include "win32/n2n_win32.h" + +#if defined(__MINGW32__) +#include +#endif /* #ifdef __MINGW32__ */ + +#else /* #if defined(WIN32) */ +#include +#include +#include /* AF_INET and AF_INET6 */ +#endif /* #if defined(WIN32) */ + +#define N2N_PKT_VERSION 2 +#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */ +#define N2N_COMMUNITY_SIZE 16 +#define N2N_MAC_SIZE 6 +#define N2N_COOKIE_SIZE 4 +#define N2N_PKT_BUF_SIZE 2048 +#define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ + +#define N2N_MULTICAST_PORT 1968 +#define N2N_MULTICAST_GROUP "224.0.0.68" + +typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; +typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; +typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE]; + +typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ + +typedef enum n2n_pc +{ + n2n_ping=0, /* Not used */ + n2n_register=1, /* Register edge to edge */ + n2n_deregister=2, /* Deregister this edge */ + n2n_packet=3, /* PACKET data content */ + n2n_register_ack=4, /* ACK of a registration from edge to edge */ + n2n_register_super=5, /* Register edge to supernode */ + n2n_register_super_ack=6, /* ACK from supernode to edge */ + n2n_register_super_nak=7, /* NAK from supernode to edge - registration refused */ + n2n_federation=8, /* Not used by edge */ + n2n_peer_info=9, /* Send info on a peer from sn to edge */ + n2n_query_peer=10 /* ask supernode for info on a peer */ +} n2n_pc_t; + +#define N2N_FLAGS_OPTIONS 0x0080 +#define N2N_FLAGS_SOCKET 0x0040 +#define N2N_FLAGS_FROM_SUPERNODE 0x0020 + +/* The bits in flag that are the packet type */ +#define N2N_FLAGS_TYPE_MASK 0x001f /* 0 - 31 */ +#define N2N_FLAGS_BITS_MASK 0xffe0 + +#define IPV4_SIZE 4 +#define IPV6_SIZE 16 + + +#define N2N_AUTH_TOKEN_SIZE 32 /* bytes */ + + +#define N2N_EUNKNOWN -1 +#define N2N_ENOTIMPL -2 +#define N2N_EINVAL -3 +#define N2N_ENOSPACE -4 + +typedef struct n2n_sock +{ + uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ + uint16_t port; /* host order */ + union + { + uint8_t v6[IPV6_SIZE]; /* byte sequence */ + uint8_t v4[IPV4_SIZE]; /* byte sequence */ + } addr; +} n2n_sock_t; + +typedef struct n2n_auth +{ + uint16_t scheme; /* What kind of auth */ + uint16_t toksize; /* Size of auth token */ + uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */ +} n2n_auth_t; + +typedef struct n2n_common +{ + /* NOTE: wire representation is different! */ + /* int version; */ + + uint8_t ttl; + uint8_t pc; + uint16_t flags; + n2n_community_t community; +} n2n_common_t; + +typedef struct n2n_REGISTER +{ + n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */ + n2n_mac_t srcMac; /* MAC of registering party */ + n2n_mac_t dstMac; /* MAC of target edge */ + n2n_sock_t sock; /* REVISIT: unused? */ +} n2n_REGISTER_t; + +typedef struct n2n_REGISTER_ACK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER */ + n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */ + n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */ + n2n_sock_t sock; /* Supernode's view of edge socket (IP Addr, port) */ +} n2n_REGISTER_ACK_t; + +typedef struct n2n_PACKET +{ + n2n_mac_t srcMac; + n2n_mac_t dstMac; + n2n_sock_t sock; + uint16_t transform; + uint16_t compression; +} n2n_PACKET_t; + +/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */ +typedef struct n2n_REGISTER_SUPER +{ + n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */ + n2n_mac_t edgeMac; /* MAC to register with edge sending socket */ + n2n_auth_t auth; /* Authentication scheme and tokens */ +} n2n_REGISTER_SUPER_t; + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +typedef struct n2n_REGISTER_SUPER_ACK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ + n2n_mac_t edgeMac; /* MAC registered to edge sending socket */ + uint16_t lifetime; /* How long the registration will live */ + n2n_sock_t sock; /* Sending sockets associated with edgeMac */ + + /* The packet format provides additional supernode definitions here. + * uint8_t count, then for each count there is one + * n2n_sock_t. + */ + uint8_t num_sn; /* Number of supernodes that were send + * even if we cannot store them all. If + * non-zero then sn_bak is valid. */ + n2n_sock_t sn_bak; /* Socket of the first backup supernode */ + +} n2n_REGISTER_SUPER_ACK_t; + + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +typedef struct n2n_REGISTER_SUPER_NAK +{ + n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ +} n2n_REGISTER_SUPER_NAK_t; + +typedef struct n2n_PEER_INFO +{ + uint16_t aflags; + n2n_mac_t mac; + n2n_sock_t sock; +} n2n_PEER_INFO_t; + +typedef struct n2n_QUERY_PEER +{ + n2n_mac_t srcMac; + n2n_mac_t targetMac; +} n2n_QUERY_PEER_t; + +typedef struct n2n_buf n2n_buf_t; + +int encode_uint8( uint8_t * base, + size_t * idx, + const uint8_t v ); + +int decode_uint8( uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_uint16( uint8_t * base, + size_t * idx, + const uint16_t v ); + +int decode_uint16( uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_uint32( uint8_t * base, + size_t * idx, + const uint32_t v ); + +int decode_uint32( uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_buf( uint8_t * base, + size_t * idx, + const void * p, + size_t s); + +int decode_buf( uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_mac( uint8_t * base, + size_t * idx, + const n2n_mac_t m ); + +int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passing a n2n_mac_t */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_common( uint8_t * base, + size_t * idx, + const n2n_common_t * common ); + +int decode_common( n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_sock( uint8_t * base, + size_t * idx, + const n2n_sock_t * sock ); + +int decode_sock( n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_t * reg ); + +int decode_REGISTER( n2n_REGISTER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_SUPER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_t * reg ); + +int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_ACK_t * reg ); + +int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_REGISTER_SUPER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * cmn, + const n2n_REGISTER_SUPER_ACK_t * reg ); + +int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int fill_sockaddr( struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock ); + +int encode_PACKET( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt ); + +int decode_PACKET( n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_PEER_INFO( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PEER_INFO_t * pkt ); + +int decode_PEER_INFO( n2n_PEER_INFO_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +int encode_QUERY_PEER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * pkt ); + +int decode_QUERY_PEER( n2n_QUERY_PEER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ); + +#endif /* #if !defined( N2N_WIRE_H_ ) */ diff --git a/bundles/n2n_ntop_v2/include/pearson.h b/bundles/n2n_ntop_v2/include/pearson.h new file mode 100644 index 00000000..24e51fe5 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/pearson.h @@ -0,0 +1,25 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len); + +void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len); + +uint16_t pearson_hash_16 (const uint8_t *in, size_t len); + +void pearson_hash_init(); diff --git a/bundles/n2n_ntop_v2/include/portable_endian.h b/bundles/n2n_ntop_v2/include/portable_endian.h new file mode 100644 index 00000000..9c46ffe5 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/portable_endian.h @@ -0,0 +1,226 @@ +// taken from +// https://raw.githubusercontent.com/pyca/bcrypt/master/src/_csrc/portable_endian.h +// as of June 11, 2020 + +// "License": Public Domain +// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. +// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to +// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it +// an example on how to get the endian conversion functions on different platforms. + +#ifndef PORTABLE_ENDIAN_H__ +#define PORTABLE_ENDIAN_H__ + +#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) + +# define __WINDOWS__ + +#endif + +#if defined(__linux__) || defined(__CYGWIN__) +/* Define necessary macros for the header to expose all fields. */ +# if !defined(_BSD_SOURCE) +# define _BSD_SOURCE +# endif +# if !defined(__USE_BSD) +# define __USE_BSD +# endif +# if !defined(_DEFAULT_SOURCE) +# define _DEFAULT_SOURCE +# endif +# include +# include +/* See http://linux.die.net/man/3/endian */ +# if defined(htobe16) && defined(htole16) && defined(be16toh) && defined(le16toh) && defined(htobe32) && defined(htole32) && defined(be32toh) && defined(htole32) && defined(htobe64) && defined(htole64) && defined(htobe64) && defined(be64toh) && defined(htole64) && defined(le64toh) +/* Do nothing. The macros we need already exist. */ +# elif !defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9))) +# include +# if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) +# define htobe16(x) htons(x) +# define htole16(x) (x) +# define be16toh(x) ntohs(x) +# define le16toh(x) (x) + +# define htobe32(x) htonl(x) +# define htole32(x) (x) +# define be32toh(x) ntohl(x) +# define le32toh(x) (x) + +# define htobe64(x) (((uint64_t)htonl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htonl(((uint32_t)(x)))) << 32)) +# define htole64(x) (x) +# define be64toh(x) (((uint64_t)ntohl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)ntohl(((uint32_t)(x)))) << 32)) +# define le64toh(x) (x) +# elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) +# define htobe16(x) (x) +# define htole16(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) +# define be16toh(x) (x) +# define le16toh(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) + +# define htobe32(x) (x) +# define htole32(x) (((uint32_t)htole16(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)htole16(((uint16_t)(x)))) << 16)) +# define be32toh(x) (x) +# define le32toh(x) (((uint32_t)le16toh(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)le16toh(((uint16_t)(x)))) << 16)) + +# define htobe64(x) (x) +# define htole64(x) (((uint64_t)htole32(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htole32(((uint32_t)(x)))) << 32)) +# define be64toh(x) (x) +# define le64toh(x) (((uint64_t)le32toh(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)le32toh(((uint32_t)(x)))) << 32)) +# else +# error Byte Order not supported or not defined. +# endif +# endif + +#elif defined(__APPLE__) + +# include + +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htole16(x) OSSwapHostToLittleInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) + +# define htobe32(x) OSSwapHostToBigInt32(x) +# define htole32(x) OSSwapHostToLittleInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) + +# define htobe64(x) OSSwapHostToBigInt64(x) +# define htole64(x) OSSwapHostToLittleInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#elif defined(__OpenBSD__) + +# include + +#elif defined(__HAIKU__) + +# include + +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) + +# include + +# if !defined(be16toh) + # define be16toh(x) betoh16(x) + # define le16toh(x) letoh16(x) +# endif + +# if !defined(be32toh) + # define be32toh(x) betoh32(x) + # define le32toh(x) letoh32(x) +# endif + +# if !defined(be64toh) + # define be64toh(x) betoh64(x) + # define le64toh(x) letoh64(x) +# endif + +#elif defined(__WINDOWS__) + +# if BYTE_ORDER == LITTLE_ENDIAN + +# define htobe16(x) _byteswap_ushort(x) +# define htole16(x) (x) +# define be16toh(x) _byteswap_ushort(x) +# define le16toh(x) (x) + +# define htobe32(x) _byteswap_ulong(x) +# define htole32(x) (x) +# define be32toh(x) _byteswap_ulong(x) +# define le32toh(x) (x) + +# define htobe64(x) _byteswap_uint64(x) +# define be64toh(x) _byteswap_uint64(x) +# define htole64(x) (x) +# define le64toh(x) (x) + +# elif BYTE_ORDER == BIG_ENDIAN + + /* that would be xbox 360 */ +# define htobe16(x) (x) +# define htole16(x) __builtin_bswap16(x) +# define be16toh(x) (x) +# define le16toh(x) __builtin_bswap16(x) + +# define htobe32(x) (x) +# define htole32(x) __builtin_bswap32(x) +# define be32toh(x) (x) +# define le32toh(x) __builtin_bswap32(x) + +# define htobe64(x) (x) +# define htole64(x) __builtin_bswap64(x) +# define be64toh(x) (x) +# define le64toh(x) __builtin_bswap64(x) + +# else + +# error byte order not supported + +# endif + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#elif defined(__sun) + +# include + +# define htobe16(x) BE_16(x) +# define htole16(x) LE_16(x) +# define be16toh(x) BE_16(x) +# define le16toh(x) LE_16(x) + +# define htobe32(x) BE_32(x) +# define htole32(x) LE_32(x) +# define be32toh(x) BE_32(x) +# define le32toh(x) LE_32(x) + +# define htobe64(x) BE_64(x) +# define htole64(x) LE_64(x) +# define be64toh(x) BE_64(x) +# define le64toh(x) LE_64(x) + +#elif defined _AIX /* AIX is always big endian */ +# define be64toh(x) (x) +# define be32toh(x) (x) +# define be16toh(x) (x) +# define le32toh(x) \ + ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000) >> 8) | \ + (((x) & 0xff000000) >> 24)) +# define le64toh(x) \ + ((((x) & 0x00000000000000ffL) << 56) | \ + (((x) & 0x000000000000ff00L) << 40) | \ + (((x) & 0x0000000000ff0000L) << 24) | \ + (((x) & 0x00000000ff000000L) << 8) | \ + (((x) & 0x000000ff00000000L) >> 8) | \ + (((x) & 0x0000ff0000000000L) >> 24) | \ + (((x) & 0x00ff000000000000L) >> 40) | \ + (((x) & 0xff00000000000000L) >> 56)) +# ifndef htobe64 +# define htobe64(x) be64toh(x) +# endif +# ifndef htobe32 +# define htobe32(x) be32toh(x) +# endif +# ifndef htobe16 +# define htobe16(x) be16toh(x) +# endif + + +#else + +# error platform not supported + +#endif + +#endif diff --git a/bundles/n2n_ntop_v2/include/random_numbers.h b/bundles/n2n_ntop_v2/include/random_numbers.h new file mode 100644 index 00000000..62711634 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/random_numbers.h @@ -0,0 +1,38 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* The WIN32 code is still untested and thus commented + #if defined (WIN32) + #include + #endif +*/ + +struct rn_generator_state_t { + uint64_t a, b; +}; + +struct splitmix64_state_t { + uint64_t s; +}; + + +int n2n_srand (uint64_t seed); + +uint64_t n2n_rand (); + +uint64_t n2n_seed (); diff --git a/bundles/n2n_ntop_v2/include/speck.h b/bundles/n2n_ntop_v2/include/speck.h new file mode 100644 index 00000000..4179e74a --- /dev/null +++ b/bundles/n2n_ntop_v2/include/speck.h @@ -0,0 +1,80 @@ +// cipher SPECK -- 128 bit block size -- 256 bit key size +// taken from (and modified: removed pure crypto-stream generation and seperated key expansion) +// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/ + + +#ifndef SPECK_H +#define SPECK_H + +#include +#define u32 uint32_t +#define u64 uint64_t + +#if defined (__AVX2__) + +#define SPECK_ALIGNED_CTX 32 +#include +#define u256 __m256i +typedef struct { + u256 rk[34]; + u64 key[34]; +} speck_context_t; + +#elif defined (__SSE4_2__) + +#define SPECK_ALIGNED_CTX 16 +#define SPECK_CTX_BYVAL 1 +#include +#define u128 __m128i +typedef struct { + u128 rk[34]; + u64 key[34]; +} speck_context_t; + +#elif defined (__ARM_NEON) + +#include +#define u128 uint64x2_t +typedef struct { + u128 rk[34]; + u64 key[34]; +} speck_context_t; + +#else + +typedef struct { + u64 key[34]; +} speck_context_t; + +#endif + + +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, +#if defined (SPECK_CTX_BYVAL) + speck_context_t ctx); +#else +speck_context_t *ctx); +#endif + + +int speck_expand_key (const unsigned char *k, speck_context_t *ctx); + + +int speck_he (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx); + + +int speck_expand_key_he (const unsigned char *k, speck_context_t *ctx); + + +int speck_he_iv_encrypt (unsigned char *inout, speck_context_t *ctx); + + +int speck_he_iv_decrypt (unsigned char *inout, speck_context_t *ctx); + + +int speck_expand_key_he_iv (const unsigned char *k, speck_context_t *ctx); + + +#endif diff --git a/bundles/n2n_ntop_v2/include/twofish.h b/bundles/n2n_ntop_v2/include/twofish.h new file mode 100644 index 00000000..9682a05e --- /dev/null +++ b/bundles/n2n_ntop_v2/include/twofish.h @@ -0,0 +1,285 @@ +/* $Id: twofish.h,v 2.0 2002/08/11 22:32:25 fknobbe Exp $ + * + * + * Copyright (C) 1997-2000 The Cryptix Foundation Limited. + * Copyright (C) 2000 Farm9. + * Copyright (C) 2001 Frank Knobbe. + * All rights reserved. + * + * For Cryptix code: + * Use, modification, copying and distribution of this software is subject + * the terms and conditions of the Cryptix General Licence. You should have + * received a copy of the Cryptix General Licence along with this library; + * if not, you can download a copy from http://www.cryptix.org/ . + * + * For Farm9: + * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and + * ciphertext stealing technique, added AsciiTwofish class for easy encryption + * decryption of text strings + * + * Frank Knobbe : + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_HEADER__ +#define __TWOFISH_LIBRARY_HEADER__ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE !FALSE +#endif +#ifndef bool +#define bool int +#endif + +#ifdef WIN32 +#include "win32/n2n_win32.h" +#endif + +#ifndef _MSC_VER +/* Not shipped with Visual Studio (as stated by the stdint.h wikipedia page) */ +#include /* defines uintN_t types */ +#endif + +#ifdef __sun__ /* Should be HAVE_SYS_TYPES */ +/* The following are redefinitions if sys/types.h has been included too.*/ +typedef uint32_t uint32_t; +typedef uint8_t uint8_t; +#endif /* #ifdef __sun__ */ + +/* Constants */ + +#define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */ +#define TwoFish_DEFAULT_PW_LEN 32 +#define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */ + +enum +{ TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */ + /* User 256, other key sizes have not been tested. */ + /* (But should work. I substitutes as much as */ + /* I could with this define.) */ + TwoFish_ROUNDS = 16, + TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */ + TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */ + TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS, + TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8, + TwoFish_SK_BUMP = 0x01010101, + TwoFish_SK_ROTL = 9, + TwoFish_P_00 = 1, + TwoFish_P_01 = 0, + TwoFish_P_02 = 0, + TwoFish_P_03 = TwoFish_P_01 ^ 1, + TwoFish_P_04 = 1, + TwoFish_P_10 = 0, + TwoFish_P_11 = 0, + TwoFish_P_12 = 1, + TwoFish_P_13 = TwoFish_P_11 ^ 1, + TwoFish_P_14 = 0, + TwoFish_P_20 = 1, + TwoFish_P_21 = 1, + TwoFish_P_22 = 0, + TwoFish_P_23 = TwoFish_P_21 ^ 1, + TwoFish_P_24 = 0, + TwoFish_P_30 = 0, + TwoFish_P_31 = 1, + TwoFish_P_32 = 1, + TwoFish_P_33 = TwoFish_P_31 ^ 1, + TwoFish_P_34 = 1, + TwoFish_GF256_FDBK = 0x169, + TwoFish_GF256_FDBK_2 = 0x169 / 2, + TwoFish_GF256_FDBK_4 = 0x169 / 4, + TwoFish_RS_GF_FDBK = 0x14D, /* field generator */ + TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */ +}; + + +/* Global data structure for callers */ + +typedef struct +{ + uint32_t sBox[4 * 256]; /* Key dependent S-box */ + uint32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */ + uint8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */ + uint8_t *output; /* Pointer to output buffer */ + uint8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */ + uint8_t qBlockCrypt[TwoFish_BLOCK_SIZE]; + uint8_t prevCipher[TwoFish_BLOCK_SIZE]; + struct /* Header for crypt functions. Has to be at least one block long. */ + { uint32_t salt; /* Random salt in first block (will salt the rest through CBC) */ + uint8_t length[4]; /* The amount of data following the header */ + uint8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */ + } header; + bool qBlockDefined; + bool dontflush; +} TWOFISH; + +/**** Public Functions ****/ + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ +TWOFISH *TwoFishInit(const uint8_t *userkey, uint32_t keysize ); + + +/* TwoFish Destroy + * + * Nothing else but a free... + * + * Input: Pointer to the TwoFish structure. + * + */ +void TwoFishDestroy(TWOFISH *tfdata); + + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer as required. + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ +void *TwoFishAlloc(uint32_t len,bool binhex,bool decrypt,TWOFISH *tfdata); + + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishFree(TWOFISH *tfdata); + + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ +void TwoFishSetOutput(uint8_t *outp,TWOFISH *tfdata); + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +uint32_t TwoFishEncryptRaw(uint8_t *in,uint8_t *out,uint32_t len,TWOFISH *tfdata); + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +uint32_t TwoFishDecryptRaw(uint8_t *in,uint8_t *out,uint32_t len,TWOFISH *tfdata); + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ +uint32_t TwoFishEncrypt(uint8_t *in,uint8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ +uint32_t TwoFishDecrypt(uint8_t *in,uint8_t **out,signed long len,bool binhex,TWOFISH *tfdata); + + +/**** Private Functions ****/ + +uint8_t TwoFish__b(uint32_t x,int n); +void _TwoFish_BinHex(uint8_t *buf,uint32_t len,bool bintohex); +uint32_t _TwoFish_CryptRawCBC(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_CryptRaw16(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_CryptRaw(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata); +void _TwoFish_PrecomputeMDSmatrix(void); +void _TwoFish_MakeSubKeys(TWOFISH *tfdata); +void _TwoFish_qBlockPush(uint8_t *p,uint8_t *c,TWOFISH *tfdata); +void _TwoFish_qBlockPop(uint8_t *p,uint8_t *c,TWOFISH *tfdata); +void _TwoFish_ResetCBC(TWOFISH *tfdata); +void _TwoFish_FlushOutput(uint8_t *b,uint32_t len,TWOFISH *tfdata); +void _TwoFish_BlockCrypt(uint8_t *in,uint8_t *out,uint32_t size,int decrypt,TWOFISH *tfdata); +void _TwoFish_BlockCrypt16(uint8_t *in,uint8_t *out,bool decrypt,TWOFISH *tfdata); +uint32_t _TwoFish_RS_MDS_Encode(uint32_t k0,uint32_t k1); +uint32_t _TwoFish_F32(uint32_t k64Cnt,uint32_t x,uint32_t *k32); +uint32_t _TwoFish_Fe320(uint32_t *lsBox,uint32_t x); +uint32_t _TwoFish_Fe323(uint32_t *lsBox,uint32_t x); +uint32_t _TwoFish_Fe32(uint32_t *lsBox,uint32_t x,uint32_t R); + + +#endif diff --git a/bundles/n2n_ntop_v2/include/uthash.h b/bundles/n2n_ntop_v2/include/uthash.h new file mode 100644 index 00000000..a790ea59 --- /dev/null +++ b/bundles/n2n_ntop_v2/include/uthash.h @@ -0,0 +1,1230 @@ +/* +Copyright (c) 2003-2018, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.1.0 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifdef uthash_memcmp +/* This warning will not catch programs that define uthash_memcmp AFTER including uthash.h. */ +#warning "uthash_memcmp is deprecated; please use HASH_KEYCMP instead" +#else +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifndef HASH_KEYCMP +#define HASH_KEYCMP(a,b,n) uthash_memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +#ifndef HASH_NONFATAL_OOM +#define HASH_NONFATAL_OOM 0 +#endif + +#if HASH_NONFATAL_OOM +/* malloc failures can be recovered from */ + +#ifndef uthash_nonfatal_oom +#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) +#define IF_HASH_NONFATAL_OOM(x) x + +#else +/* malloc failures result in lost memory, hash tables are unusable */ + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") +#define IF_HASH_NONFATAL_OOM(x) + +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ + unsigned _hd_bkt; \ + HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + (head)->hh.tbl->buckets[_hd_bkt].count++; \ + _hd_hh_item->hh_next = NULL; \ + _hd_hh_item->hh_prev = NULL; \ +} while (0) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl,oomed) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ + } \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl,oomed) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head,oomed) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ + if (!(head)->hh.tbl->buckets) { \ + HASH_RECORD_OOM(oomed); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } else { \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + uthash_free((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } \ + ) \ + } \ + } \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#if HASH_NONFATAL_OOM + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + if (!(oomed)) { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + if (oomed) { \ + HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ + HASH_DELETE_HH(hh, head, &(add)->hh); \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } else { \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + } \ + } else { \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } \ +} while (0) + +#else + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ +} while (0) + +#endif + + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ +} while (0) + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ +do { \ + unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ + HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ +} while (0) +#define HASH_ADD_STR(head,strfield,add) \ +do { \ + unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ +} while (0) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ +do { \ + unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ +} while (0) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch ((keylen) & 3U) { \ + case 0: break; \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + HASH_DEL_IN_BKT(head,addhh); \ + } \ + ) \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ + _he_newbkt->expand_mult++; \ + } \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ + } \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + uthash_nonfatal_oom(_elt); \ + (dst) = NULL; \ + continue; \ + } \ + ) \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ + (dst)->hh_dst.tbl->num_items++; \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ + HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ + _dst_hh->tbl = NULL; \ + uthash_nonfatal_oom(_elt); \ + continue; \ + } \ + ) \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/bundles/n2n_ntop_v2/legacy/README.md b/bundles/n2n_ntop_v2/legacy/README.md new file mode 100644 index 00000000..174c1146 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/README.md @@ -0,0 +1,33 @@ +# Removed Features + +This folder contains a list N2N legacy features which have been dropped due to +maintainance cost versus effective use and benefits. + +Multiple Transops +----------------- + +N2N used to initialize all the available transops and use the "tick" function of +the transops to decide which transop to use before sending a packet. This however +has the following problems: + +- It only works with the keyfile, whereas with normal encryption we inizialize and + keep structures that we don't need. +- It is unfeasable as an edge node is required to implement all the transops in order + to properly talk with other edge nodes (via keyfile). +- It rises the complexity of the code. +- It is not clear which transop will be used. +- Mixing multiple encyptions together is not necessarily a good idea to improve security + as a vulnerability in at least one encryption method will leak some information. + +Keyfile and Key Rotation +------------------------ + +The keyfile mechanism allowed N2N users to specify a keyfile to be used to periodically +rotate keys and encryption methods. However, it has the following problems: + +- This feature is obscure for most of the users and poorly documented. +- It is tightly integrated in the core whereas it is used by only a few people (if any). + +In conclusion the main problem is the complexity that it adds to the code. In a possible +future rework this could be integrated as an extention (e.g. a specific trasop) without +rising the core complexity. diff --git a/bundles/n2n_ntop_v2/legacy/edge_keyschedule.c b/bundles/n2n_ntop_v2/legacy/edge_keyschedule.c new file mode 100644 index 00000000..5e3af35d --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/edge_keyschedule.c @@ -0,0 +1,103 @@ +typedef struct n2n_tostat { + uint8_t can_tx; /* Does this transop have a valid SA for encoding. */ + n2n_cipherspec_t tx_spec; /* If can_tx, the spec used to encode. */ +} n2n_tostat_t; + +typedef uint32_t n2n_sa_t; /* security association number */ +typedef int (*n2n_transaddspec_f)( struct n2n_trans_op * arg, + const n2n_cipherspec_t * cspec ); + +typedef n2n_tostat_t (*n2n_transtick_f)( struct n2n_trans_op * arg, + time_t now ); + +/** Read in a key-schedule file, parse the lines and pass each line to the + * appropriate trans_op for parsing of key-data and adding key-schedule + * entries. The lookup table of time->trans_op is constructed such that + * encoding can be passed to the correct trans_op. The trans_op internal table + * will then determine the best SA for that trans_op from the key schedule to + * use for encoding. */ + +static int edge_init_keyschedule(n2n_edge_t *eee) { +#define N2N_NUM_CIPHERSPECS 32 + + int retval = -1; + ssize_t numSpecs=0; + n2n_cipherspec_t specs[N2N_NUM_CIPHERSPECS]; + size_t i; + time_t now = time(NULL); + + numSpecs = n2n_read_keyfile(specs, N2N_NUM_CIPHERSPECS, eee->conf.keyschedule); + + if(numSpecs > 0) + { + traceEvent(TRACE_NORMAL, "keyfile = %s read -> %d specs.\n", optarg, (signed int)numSpecs); + + for (i=0; i < (size_t)numSpecs; ++i) + { + n2n_transform_t idx = (n2n_transform_t) specs[i].t; + if(idx != eee->transop.transform_id) { + traceEvent(TRACE_ERROR, "changing transop in keyschedule is not supported"); + retval = -1; + } + + if(eee->transop.addspec != NULL) + retval = eee->transop.addspec(&eee->transop, &(specs[i])); + + if (0 != retval) + { + traceEvent(TRACE_ERROR, "keyschedule failed to add spec[%u] to transop[%d].\n", + (unsigned int)i, idx); + + return retval; + } + } + + n2n_tick_transop(eee, now); + } + else + traceEvent(TRACE_ERROR, "Failed to process '%s'", eee->conf.keyschedule); + + return retval; +} + +#if 0 + if(recvlen >= 6) + { + if(0 == memcmp(udp_buf, "reload", 6)) + { + if(strlen(eee->conf.keyschedule) > 0) + { + if(edge_init_keyschedule(eee) == 0) + { + msg_len=0; + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> OK\n"); + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); + } + return; + } + } + } +#endif + +#if 0 + case'K': + { + if(conf->encrypt_key) { + traceEvent(TRACE_ERROR, "Error: -K and -k options are mutually exclusive"); + exit(1); + } else { + strncpy(conf->keyschedule, optargument, N2N_PATHNAME_MAXLEN-1); + /* strncpy does not add NULL if the source has no NULL. */ + conf->keyschedule[N2N_PATHNAME_MAXLEN-1] = 0; + + traceEvent(TRACE_NORMAL, "keyfile = '%s'\n", conf->keyschedule); + } + break; + } +#endif + +#if 0 + printf("-K | Specify a key schedule file to load. Not with -k.\n"); +#endif diff --git a/bundles/n2n_ntop_v2/legacy/gen_keyfile.py b/bundles/n2n_ntop_v2/legacy/gen_keyfile.py new file mode 100644 index 00000000..b6dc3e67 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/gen_keyfile.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +# (c) 2009 Richard Andrews + +# Program to generate a n2n_edge key schedule file for twofish keys +# Each key line consists of the following element +# +# +# where , are UNIX time_t values of key valid period +# is the transform ID (=2 for twofish) +# is twofish-specific data as follows +# _ + +import os +import sys +import time +import random + +NUM_KEYS=30 +KEY_LIFE=300 +KEY_LEN=16 + +now=time.time() +start_sa=random.randint( 0, 0xffffffff ) + +random.seed(now) # note now is a floating point time value + +def rand_key(): + key=str() + for i in range(0,KEY_LEN): + key += "%02x"%( random.randint( 0, 255) ) + + return key + +for i in range(0,NUM_KEYS): + from_time = now + (KEY_LIFE * (i-1) ) + until_time = now + (KEY_LIFE * (i+1) ) + key = rand_key() + sa_idx = start_sa + i + transform_id = random.randint( 2, 3 ) + + sys.stdout.write("%d %d %d %d_%s\n"%(from_time, until_time, transform_id,sa_idx, key) ) + + diff --git a/bundles/n2n_ntop_v2/legacy/n2n_keyfile.c b/bundles/n2n_ntop_v2/legacy/n2n_keyfile.c new file mode 100644 index 00000000..eda6c834 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/n2n_keyfile.c @@ -0,0 +1,216 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_keyfile.h" +#include +#include +#include +#include + + +#ifdef WIN32 +char *strsep( char **ppsz_string, const char *psz_delimiters ) +{ + char *p; + char *psz_string = *ppsz_string; + if( !psz_string ) + return NULL; + + p = strpbrk( psz_string, psz_delimiters ); + if( !p ) + { + *ppsz_string = NULL; + return psz_string; + } + *p++ = '\0'; + + *ppsz_string = p; + return psz_string; +} +#endif + + +/* Parse hex nibbles in ascii until a non-nibble character is found. Nibble + * characters are 0-9, a-f and A-F. + * + * Return number of bytes parsed into keyBuf or a negative error code. + */ +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyLen, + const char * textKey, + size_t textLen) +{ + ssize_t retval=0; + uint8_t * pout=keyBuf; + size_t octet=0; + const char * textEnd; + const char * pbeg; + + textEnd = textKey+textLen; + pbeg=textKey; + + while ( ( pbeg + 1 < textEnd ) && ( retval < (ssize_t)keyLen ) ) + { + if ( 1 != sscanf( pbeg, "%02x", (unsigned int*)&octet ) ) + { + retval=-1; + break; + } + + *pout = (octet & 0xff); + ++pout; + ++retval; + pbeg += 2; + } + + return retval; +} + + +static int parseKeyLine( n2n_cipherspec_t * spec, + const char * linein ) +{ + /* parameters are separated by whitespace */ + char line[N2N_KEYFILE_LINESIZE]; + char * lp=line; + const char * token; + strncpy( line, linein, N2N_KEYFILE_LINESIZE ); + + memset( spec, 0, sizeof( n2n_cipherspec_t ) ); + + /* decode valid_from time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_from = atol(token); + + /* decode valid_until time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_until = atol(token); + + /* decode the transform number */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->t = atoi(token); + + /* The reset if opaque key data */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + strncpy( (char *)spec->opaque, token, N2N_MAX_KEYSIZE ); + spec->opaque_size=strlen( (char *)spec->opaque); + + return 0; + +error: + return -1; +} + + +#define SEP "/" + + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ) +{ + if ( k->valid_until < k->valid_from ) { goto bad; } + if ( k->valid_from > now ) { goto bad; } + if ( k->valid_until < now ) { goto bad; } + + return 0; + +bad: + return -1; +} + +/* Read key control file and return the number of specs stored or a negative + * error code. + * + * As the specs are read in the from and until time values are compared to + * present time. Only those keys which are valid are stored. + */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ) /* path to control file */ +{ + /* Each line contains one cipherspec. */ + + int retval=0; + FILE * fp=NULL; + size_t idx=0; + time_t now = time(NULL); + + traceEvent( TRACE_DEBUG, "Reading '%s'\n", ctrlfile_path ); + + fp = fopen( ctrlfile_path, "r" ); + if ( fp ) + { + /* Read the file a line a time with fgets. */ + char line[N2N_KEYFILE_LINESIZE]; + size_t lineNum=0; + + while ( idx < numspecs ) + { + n2n_cipherspec_t * k = &(specs[idx]); + fgets( line, N2N_KEYFILE_LINESIZE, fp ); + ++lineNum; + + if ( strlen(line) > 1 ) + { + if ( 0 == parseKeyLine( k, line ) ) + { + if ( k->valid_until > now ) + { + traceEvent( TRACE_INFO, " --> [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + ++retval; + ++idx; + } + else + { + traceEvent( TRACE_INFO, " --X [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + } + } + else + { + traceEvent( TRACE_WARNING, "Failed to decode line %u\n", lineNum ); + } + } + + if ( feof(fp) ) + { + break; + } + + line[0]=0; /* this line has been consumed */ + } + + fclose( fp); + fp=NULL; + } + else + { + traceEvent( TRACE_ERROR, "Failed to open '%s'\n", ctrlfile_path ); + retval = -1; + } + + return retval; +} diff --git a/bundles/n2n_ntop_v2/legacy/n2n_keyfile.h b/bundles/n2n_ntop_v2/legacy/n2n_keyfile.h new file mode 100644 index 00000000..05cdf606 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/n2n_keyfile.h @@ -0,0 +1,117 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/** Key files + * + * Edge implements a very simple interface for getting instructions about + * rolling keys. + * + * Key definitions are written as individual files in /.key. The + * format of each key is a single line of hex nibbles as follows: + * + * 0102030405060708090a0b0c0d0e0f + * + * Any external key exchange mechanism can receive the key data write it into + * the keyfiles. + * + * To control which keys are active at what times the key control file is + * used. This is a single file which is periodically reread. It contains key + * definitions in chronological order with one line per key definition as + * follows: + * + * + * + * edge reads the key control file periodically to get updates in policy. edge + * holds a number of keys in memory. Data can be decoded if it was encoded by + * any of the keys still in memory. By having at least 2 keys in memory it + * allows for clock skew and transmission delay when encoder and decoder roll + * keys at slightly different times. The amount of overlap in the valid time + * ranges provides the tolerance to timing skews in the system. + * + * The keys have the same level of secrecy as any other user file. Existing + * UNIX permission systems can be used to provide access controls. + * + */ + +/** How Edge Uses The Key Schedule + * + * Edge provides state space for a number of transform algorithms. Each + * transform uses its state space to store the SA information for its keys as + * found in the key file. When a packet is received the transform ID is in + * plain text. The packets is then sent to that transform for decoding. Each + * transform can store its SA numbers differently (or not at all). The + * transform code then finds the SA number, then finds the cipher (with key) in + * the state space and uses this to decode the packet. + * + * To support this, as edge reads each key line, it passes it to the + * appropriate transform to parse the line and store the SA information in its + * state space. + * + * When encoding a packet, edge has several transforms and potentially valid + * SAs to choose from. To keep track of which one to use for encoding edge does + * its own book-keeping as each key line is passed to the transform code: it + * stores a lookup of valid_from -> transform. When encoding a packet it then + * just calls the transform with the best valid_from in the table. The + * transform's own state space has all the SAs for its keys and the best of + * those is chosen. + */ + +#if !defined( N2N_KEYFILE_H_ ) +#define N2N_KEYFILE_H_ + + +#include "n2n_wire.h" +#include + +#define N2N_MAX_KEYSIZE 256 /* bytes */ +#define N2N_MAX_NUM_CIPHERSPECS 8 +#define N2N_KEYPATH_SIZE 256 +#define N2N_KEYFILE_LINESIZE 256 + +/** This structure stores an encryption cipher spec. */ +struct n2n_cipherspec +{ + n2n_transform_t t; /* N2N_TRANSFORM_ID_xxx for this spec. */ + time_t valid_from; /* Start using the key at this time. */ + time_t valid_until; /* Key is valid if time < valid_until. */ + uint16_t opaque_size; /* Size in bytes of key. */ + uint8_t opaque[N2N_MAX_KEYSIZE];/* Key matter. */ +}; + +typedef struct n2n_cipherspec n2n_cipherspec_t; + + +static const char * const DELIMITERS=" \t\n\r"; + + +/** @return number of cipherspec items filled. */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ); /* path to control file */ + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ); + +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyMax, + const char * textKey, + size_t textLen ); + +/*----------------------------------------------------------------------------*/ + +#endif /* #if !defined( N2N_KEYFILE_H_ ) */ diff --git a/bundles/n2n_ntop_v2/legacy/transform_aes.c b/bundles/n2n_ntop_v2/legacy/transform_aes.c new file mode 100644 index 00000000..7b198ff4 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/transform_aes.c @@ -0,0 +1,730 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" + +#if defined(N2N_HAVE_AES) + +#include "openssl/aes.h" +#include "openssl/sha.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_AES_NUM_SA 32 /* space for SAa */ + +#define N2N_AES_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_AES_IVEC_SIZE 32 /* Enough space for biggest AES ivec */ + +#define AES256_KEY_BYTES (256/8) +#define AES192_KEY_BYTES (192/8) +#define AES128_KEY_BYTES (128/8) + +typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE]; + +struct sa_aes +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + AES_KEY enc_key; /* tx key */ + AES_KEY dec_key; /* tx key */ + AES_KEY iv_enc_key; /* key used to encrypt the IV */ + uint8_t iv_ext_val[AES128_KEY_BYTES]; /* key used to extend the random IV seed to full block size */ +}; + +typedef struct sa_aes sa_aes_t; + + +/** Aes transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for aes + * consists of the SA number and key material. + * + */ +struct transop_aes +{ + ssize_t tx_sa; + size_t num_sa; + sa_aes_t sa[N2N_AES_NUM_SA]; + u_int8_t psk_mode; +}; + +typedef struct transop_aes transop_aes_t; + +static ssize_t aes_find_sa( const transop_aes_t * priv, const n2n_sa_t req_id ); +static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size, size_t sa_num); + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t aes_choose_tx_sa( transop_aes_t * priv, const u_int8_t * peer_mac ) { + return priv->tx_sa; /* set in tick */ +} + +static ssize_t aes_choose_rx_sa( transop_aes_t * priv, const u_int8_t * peer_mac, ssize_t sa_rx) { + if(!priv->psk_mode) + return aes_find_sa(priv, sa_rx); + else + /* NOTE the sa_rx of the packet is ignored in this case */ + return 0; +} + +/* AES plaintext preamble */ +#define TRANSOP_AES_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_AES_SA_SIZE 4 +#define TRANSOP_AES_IV_SEED_SIZE 8 +#define TRANSOP_AES_PREAMBLE_SIZE (TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE + TRANSOP_AES_IV_SEED_SIZE) + +/* AES ciphertext preamble */ +#define TRANSOP_AES_NONCE_SIZE 4 + +/* Return the best acceptable AES key size (in bytes) given an input keysize. + * + * The value returned will be one of AES128_KEY_BYTES, AES192_KEY_BYTES or + * AES256_KEY_BYTES. + */ +static size_t aes_best_keysize(size_t numBytes) +{ + if (numBytes >= AES256_KEY_BYTES ) + { + return AES256_KEY_BYTES; + } + else if (numBytes >= AES192_KEY_BYTES) + { + return AES192_KEY_BYTES; + } + else + { + return AES128_KEY_BYTES; + } +} + +static void set_aes_cbc_iv(sa_aes_t *sa, n2n_aes_ivec_t ivec, uint64_t iv_seed) { + uint8_t iv_full[AES_BLOCK_SIZE]; + + /* Extend the seed to full block size via the fixed ext value */ + memcpy(iv_full, sa->iv_ext_val, sizeof(iv_seed)); // note: only 64bits used of 128 available + memcpy(iv_full + sizeof(iv_seed), &iv_seed, sizeof(iv_seed)); + + /* Encrypt the IV with secret key to make it unpredictable. + * As discussed in https://github.com/ntop/n2n/issues/72, it's important to + * have an unpredictable IV since the initial part of the packet plaintext + * can be easily reconstructed from plaintext headers and used by an attacker + * to perform differential analysis. + */ + AES_ecb_encrypt(iv_full, ivec, &sa->iv_enc_key, AES_ENCRYPT); +} + +/** The aes packet format consists of: + * + * - a 8-bit aes encoding version in clear text + * - a 32-bit SA number in clear text + * - a 64-bit random IV seed + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|II|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len2=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE] = {0}; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_AES_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_AES_NONCE_SIZE + TRANSOP_AES_PREAMBLE_SIZE) <= out_len ) + { + int len=-1; + size_t idx=0; + sa_aes_t * sa; + size_t tx_sa_num = 0; + uint64_t iv_seed = 0; + uint8_t padding = 0; + n2n_aes_ivec_t enc_ivec = {0}; + + /* The transmit sa is periodically updated */ + tx_sa_num = aes_choose_tx_sa( priv, peer_mac ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_aes %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the aes format version. */ + encode_uint8( outbuf, &idx, N2N_AES_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* Generate and encode the IV seed. + * Using two calls to rand() because RAND_MAX is usually < 64bit + * (e.g. linux) and sometimes < 32bit (e.g. Windows). + */ + ((uint32_t*)&iv_seed)[0] = rand(); + ((uint32_t*)&iv_seed)[1] = rand(); + encode_buf(outbuf, &idx, &iv_seed, sizeof(iv_seed)); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = in_len + TRANSOP_AES_NONCE_SIZE; + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_AES_NONCE_SIZE, inbuf, in_len ); + + /* Need at least one encrypted byte at the end for the padding. */ + len2 = ( (len / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; /* Round up to next whole AES adding at least one byte. */ + padding = (len2-len); + assembly[len2 - 1] = padding; + traceEvent( TRACE_DEBUG, "padding = %u, seed = %016lx", padding, iv_seed ); + + set_aes_cbc_iv(sa, enc_ivec, iv_seed); + + AES_cbc_encrypt( assembly, /* source */ + outbuf + TRANSOP_AES_PREAMBLE_SIZE, /* dest */ + len2, /* enc size */ + &(sa->enc_key), enc_ivec, AES_ENCRYPT ); + + len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_aes outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_aes inbuf too big to encrypt." ); + } + + return len2; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t aes_find_sa( const transop_aes_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_aes_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/* See transop_encode_aes for packet format */ +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=0; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - TRANSOP_AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_AES_PREAMBLE_SIZE + TRANSOP_AES_NONCE_SIZE) ) /* Has at least version, SA, iv seed and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t aes_enc_ver=0; + uint64_t iv_seed=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &aes_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_AES_TRANSFORM_VERSION == aes_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = aes_choose_rx_sa(priv, peer_mac, sa_rx); + + if ( sa_idx >= 0 ) + { + sa_aes_t * sa = &(priv->sa[sa_idx]); + + /* Get the IV seed */ + decode_buf((uint8_t *)&iv_seed, sizeof(iv_seed), inbuf, &rem, &idx); + + traceEvent( TRACE_DEBUG, "decode_aes %lu with SA %lu and seed %016lx", in_len, sa->sa_id, iv_seed ); + + len = (in_len - TRANSOP_AES_PREAMBLE_SIZE); + + if ( 0 == (len % AES_BLOCK_SIZE ) ) + { + uint8_t padding; + n2n_aes_ivec_t dec_ivec = {0}; + + set_aes_cbc_iv(sa, dec_ivec, iv_seed); + + AES_cbc_encrypt( (inbuf + TRANSOP_AES_PREAMBLE_SIZE), + assembly, /* destination */ + len, + &(sa->dec_key), + dec_ivec, AES_DECRYPT ); + + /* last byte is how much was padding: max value should be + * AES_BLOCKSIZE-1 */ + padding = assembly[ len-1 ] & 0xff; + + if ( len >= (padding + TRANSOP_AES_NONCE_SIZE)) + { + /* strictly speaking for this to be an ethernet packet + * it is going to need to be even bigger; but this is + * enough to prevent segfaults. */ + traceEvent( TRACE_DEBUG, "padding = %u", padding ); + len -= padding; + + len -= TRANSOP_AES_NONCE_SIZE; /* size of ethernet packet */ + + /* Step over 4-byte random nonce value */ + memcpy( outbuf, + assembly + TRANSOP_AES_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_WARNING, "UDP payload decryption failed." ); + } + } + else + { + traceEvent( TRACE_WARNING, "Encrypted length %d is not a multiple of AES_BLOCK_SIZE (%d)", len, AES_BLOCK_SIZE ); + len = 0; + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes unsupported aes version %u.", aes_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_aes inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +struct sha512_keybuf { + uint8_t enc_dec_key[AES256_KEY_BYTES]; /* The key to use for AES CBC encryption/decryption */ + uint8_t iv_enc_key[AES128_KEY_BYTES]; /* The key to use to encrypt the IV with AES ECB */ + uint8_t iv_ext_val[AES128_KEY_BYTES]; /* A value to extend the IV seed */ +}; /* size: SHA512_DIGEST_LENGTH */ + +/* NOTE: the caller should adjust priv->num_sa accordingly */ +static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size, size_t sa_num) { + sa_aes_t * sa = &(priv->sa[sa_num]); + size_t aes_keysize_bytes; + size_t aes_keysize_bits; + struct sha512_keybuf keybuf; + + /* Clear out any old possibly longer key matter. */ + memset( &(sa->enc_key), 0, sizeof(sa->enc_key) ); + memset( &(sa->dec_key), 0, sizeof(sa->dec_key) ); + memset( &(sa->iv_enc_key), 0, sizeof(sa->iv_enc_key) ); + memset( &(sa->iv_ext_val), 0, sizeof(sa->iv_ext_val) ); + + /* We still use aes_best_keysize (even not necessary since we hash the key + * into the 256bits enc_dec_key) to let the users choose the degree of encryption. + * Long keys will pick AES192 or AES256 with more robust but expensive encryption. + */ + aes_keysize_bytes = aes_best_keysize(key_size); + aes_keysize_bits = 8 * aes_keysize_bytes; + + /* Hash the main key to generate subkeys */ + SHA512(key, key_size, (u_char*)&keybuf); + + /* setup of enc_key/dec_key, used for the CBC encryption */ + AES_set_encrypt_key(keybuf.enc_dec_key, aes_keysize_bits, &(sa->enc_key)); + AES_set_decrypt_key(keybuf.enc_dec_key, aes_keysize_bits, &(sa->dec_key)); + + /* setup of iv_enc_key and iv_ext_val, used for generating the CBC IV */ + AES_set_encrypt_key(keybuf.iv_enc_key, sizeof(keybuf.iv_enc_key) * 8, &(sa->iv_enc_key)); + memcpy(sa->iv_ext_val, keybuf.iv_ext_val, sizeof(keybuf.iv_ext_val)); + + traceEvent( TRACE_DEBUG, "transop_addspec_aes sa_id=%u, %u bits key=%s.\n", + priv->sa[sa_num].sa_id, aes_keysize_bits, key); + + return(0); +} + +/* + * priv: pointer to transform state + * keybuf: buffer holding the key + * pstat: length of keybuf + */ +static void add_aes_key(transop_aes_t *priv, uint8_t *keybuf, ssize_t pstat) { + setup_aes_key(priv, keybuf, pstat, priv->num_sa); + ++(priv->num_sa); +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_AES_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; + const char * sep = index( op, '_' ); + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + memset( keybuf, 0, N2N_MAX_KEYSIZE ); + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + add_aes_key(priv, keybuf, pstat); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_aes tick num_sa=%u now=%lu", priv->num_sa, now ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_aes choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_aes tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_aes no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_AESCBC; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + +static n2n_tostat_t transop_tick_aes_psk(n2n_trans_op_t * arg, time_t now) { + transop_aes_t * priv = (transop_aes_t *)arg->priv; + n2n_tostat_t r; + + memset(&r, 0, sizeof(r)); + + // Always tx + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_AESCBC; + r.tx_spec = priv->sa[priv->tx_sa].spec; + + return r; +} + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) calloc(1, sizeof(transop_aes_t)); + + if ( NULL != priv ) + { + size_t i; + sa_aes_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + priv->psk_mode = 0; + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + memset( &(sa->enc_key), 0, sizeof(sa->enc_key) ); + memset( &(sa->dec_key), 0, sizeof(sa->dec_key) ); + memset( &(sa->iv_enc_key), 0, sizeof(sa->iv_enc_key) ); + memset( &(sa->iv_ext_val), 0, sizeof(sa->iv_ext_val) ); + } + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + +/* Setup AES in pre-shared key mode */ +int transop_aes_setup_psk(n2n_trans_op_t *ttt, + n2n_sa_t sa_num, + uint8_t *encrypt_pwd, + uint32_t encrypt_pwd_len) { + int retval = 1; + transop_aes_t *priv = (transop_aes_t *)ttt->priv; + + if(ttt->priv) { + /* Replace the tick function with the PSK version of it */ + ttt->tick = transop_tick_aes_psk; + priv->psk_mode = 1; + priv->num_sa=0; + priv->tx_sa=0; + + /* Setup the key to use for encryption/decryption */ + add_aes_key(priv, encrypt_pwd, encrypt_pwd_len); + + retval = 0; + } else + traceEvent(TRACE_ERROR, "AES priv is not allocated"); + + return retval; +} + +#else /* #if defined(N2N_HAVE_AES) */ + +struct transop_aes +{ + ssize_t tx_sa; +}; + +typedef struct transop_aes transop_aes_t; + + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + + if ( priv ) + { + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + traceEvent( TRACE_DEBUG, "transop_addspec_aes AES not built into edge.\n"); + + return -1; +} + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + return r; +} + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) malloc( sizeof(transop_aes_t) ); + + if ( NULL != priv ) + { + /* install the private structure. */ + ttt->priv = priv; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + + +int transop_aes_setup_psk(n2n_trans_op_t *ttt, + n2n_sa_t sa_num, + uint8_t *encrypt_pwd, + uint32_t encrypt_pwd_len) { + return 0; +} + +#endif /* #if defined(N2N_HAVE_AES) */ + diff --git a/bundles/n2n_ntop_v2/legacy/transform_tf.c b/bundles/n2n_ntop_v2/legacy/transform_tf.c new file mode 100644 index 00000000..6b4d6060 --- /dev/null +++ b/bundles/n2n_ntop_v2/legacy/transform_tf.c @@ -0,0 +1,467 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" +#include "twofish.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_TWOFISH_NUM_SA 32 /* space for SAa */ + +#define N2N_TWOFISH_TRANSFORM_VERSION 1 /* version of the transform encoding */ + +struct sa_twofish +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + TWOFISH * enc_tf; /* tx state */ + TWOFISH * dec_tf; /* rx state */ +}; + +typedef struct sa_twofish sa_twofish_t; + + +/** Twofish transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for twofish + * consists of the SA number and key material. + * + */ +struct transop_tf +{ + ssize_t tx_sa; + size_t num_sa; + sa_twofish_t sa[N2N_TWOFISH_NUM_SA]; +}; + +typedef struct transop_tf transop_tf_t; + +static int transop_deinit_twofish( n2n_trans_op_t * arg ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + TwoFishDestroy(sa->enc_tf); /* deallocate TWOFISH */ + sa->enc_tf=NULL; + + TwoFishDestroy(sa->dec_tf); /* deallocate TWOFISH */ + sa->dec_tf=NULL; + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t tf_choose_tx_sa( transop_tf_t * priv ) +{ + return priv->tx_sa; /* set in tick */ +} + +#define TRANSOP_TF_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_TF_NONCE_SIZE 4 +#define TRANSOP_TF_SA_SIZE 4 + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) + { + size_t idx=0; + sa_twofish_t * sa; + size_t tx_sa_num = 0; + + /* The transmit sa is periodically updated */ + tx_sa_num = tf_choose_tx_sa( priv ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_twofish %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the twofish format version. */ + encode_uint8( outbuf, &idx, N2N_TWOFISH_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len ); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = TwoFishEncryptRaw( assembly, /* source */ + outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE, + in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */ + sa->enc_tf); + if ( len > 0 ) + { + len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish encryption failed." ); + } + + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." ); + } + + return len; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t twofish_find_sa( const transop_tf_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_twofish_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_decode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=0; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_NONCE_SIZE) ) /* Has at least version, SA and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t tf_enc_ver=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &tf_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_TWOFISH_TRANSFORM_VERSION == tf_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = twofish_find_sa(priv, sa_rx); + if ( sa_idx >= 0 ) + { + sa_twofish_t * sa = &(priv->sa[sa_idx]); + + traceEvent( TRACE_DEBUG, "decode_twofish %lu with SA %lu.", in_len, sa_rx, sa->sa_id ); + + len = TwoFishDecryptRaw( (void *)(inbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE), + assembly, /* destination */ + (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)), + sa->dec_tf); + + if ( len > 0 ) + { + /* Step over 4-byte random nonce value */ + len -= TRANSOP_TF_NONCE_SIZE; /* size of ethernet packet */ + + memcpy( outbuf, + assembly + TRANSOP_TF_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish decryption failed." ); + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish unsupported twofish version %u.", tf_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +static int transop_addspec_twofish( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_TWOFISH_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; +#ifdef __ANDROID_NDK__ + const char *sep = strchr(op, '_'); +#else + const char * sep = index( op, '_' ); +#endif // __ANDROID_NDK__ + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + priv->sa[priv->num_sa].enc_tf = TwoFishInit( keybuf, pstat); + priv->sa[priv->num_sa].dec_tf = TwoFishInit( keybuf, pstat); + + traceEvent( TRACE_DEBUG, "transop_addspec_twofish sa_id=%u data=%s.\n", + priv->sa[priv->num_sa].sa_id, sep+1); + + ++(priv->num_sa); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_twofish( n2n_trans_op_t * arg, time_t now ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_tf tick num_sa=%u", priv->num_sa ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_tf choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_tf tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_tf no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_TWOFISH; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + +int transop_twofish_setup_psk( n2n_trans_op_t * ttt, + n2n_sa_t sa_num, + uint8_t * encrypt_pwd, + uint32_t encrypt_pwd_len ) +{ + int retval = 1; + transop_tf_t * priv = (transop_tf_t *)ttt->priv; + + if(priv) { + sa_twofish_t *sa; + + priv->num_sa=1; /* There is one SA in the array. */ + priv->tx_sa=0; + sa = &(priv->sa[priv->tx_sa]); + sa->sa_id=sa_num; + sa->spec.valid_until = 0x7fffffff; + + /* This is a preshared key setup. Both Tx and Rx are using the same security association. */ + + sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + + if ( (sa->enc_tf) && (sa->dec_tf) ) + retval = 0; + else + traceEvent( TRACE_ERROR, "transop_twofish_setup_psk" ); + } else + traceEvent( TRACE_ERROR, "twofish priv is not allocated" ); + + return retval; +} + +int transop_twofish_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_tf_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_twofish( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); + + if ( NULL != priv ) { + size_t i; + sa_twofish_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + ttt->addspec = transop_addspec_twofish; + ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_twofish; + ttt->fwd = transop_encode_twofish; + ttt->rev = transop_decode_twofish; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + sa->enc_tf=NULL; + sa->dec_tf=NULL; + } + + retval = 0; + } else { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); + } + + return retval; +} diff --git a/bundles/n2n_ntop_v2/n2n.7 b/bundles/n2n_ntop_v2/n2n.7 new file mode 100644 index 00000000..092f2d3a --- /dev/null +++ b/bundles/n2n_ntop_v2/n2n.7 @@ -0,0 +1,156 @@ +.TH "n2n_v2" 7 "Sep 21, 2009" "revision 3909" "Background" +.SH NAME +N2n Version 2 \- version 2 of the n2n decentralised peer-to-peer network overlay +VPN. +.SH DESCRIPTION +N2n is a peer-to-peer network overlay or VPN system that provides layer 2 over +layer 3 encapsulation with data transform capabilities such as encryption and +compression. This guide discusses the differences of version 2 or n2n from +version 1. +.SH PROTOCOLS +N2n-2 uses a different set of messages to communicate with edges and +supernodes. The n2n-2 messages are not compatible with n2n-1. There is no +backward compatibility for n2n-1. +.SH ENCRYPTION +N2n-2 offers a new way of handling encryption compared to n2n-1. N2n-1 provided +facility for a single community password with no expiration. In n2n-2 this +method is preserved but a new mechanism has been added using a key schedule +file. +.TP +Key Schedule +A key schedule file lists a number of keys with the period for which each is +valid along with the encryption type identifier and the actual key value. This +allows the user to define up to 32 keys in advance with a pre-set time at which +they keys will change. The key schedule file can be reloaded while the edge is +running to allow new keys to be loaded and unused keys expunged. +.TP +Timing Requirements When a key rolls over to the next in the schedule, the new +key is used for all transmitted packets; however any packets received using an +older key can still be decoded as the keys from the key schedule are still +known. As a result edges do not need to have accurate time synchronisation. The +accuracy of required synchronisation depends to a large degree on the key +schedule. Rapid key roll-overs requires more accurate time synchronisation. +.P +N2n-2 provides the following encryption ciphers; more can be added as required: +.TP +.B (1) NULL +Data is encapsulated unchanged. Useful for testing and high-performance, low +sensitivity applications. +.TP +.B (2) TF +Twofish AES candidate. +.P +The following additional ciphers are specified but not yet implemented: +.TP +.B (3) AES-CBC +AES in CBC mode with 256-bit key. +.TP +.B (4) LZO +LZO compression of data (no encryption). +.TP +.B (5) TF-LZO +TF cipher with LZO compression of data prior to encryption. +.TP +.B (6) AES-CBC-LZO +AES-CBC ciper with LZO compression of data prior to encryption. + +.SH EXTENSIBILITY +N2n-2 decouples the data transform system from the core of the edge +operation. This allows for easier addition of new data transform +operations. N2n-2 reserves 64 standard transform identifiers (such as TwoFish +encryption) but allocates transform identifiers 64 - 65536 for user-defined +transforms. This allows anyone to add to n2n new private transforms without +breaking compatibility with the standard offering. + +.SH MULTIPLE SUPERNODES +N2n-2 introduces the capability of multiple supernodes to be used by an +edge. N2n-2 offers supernode in several flavours: +.TP +Stand-alone supernode + +This is the same concept as from n2n-1. Supernode is a small efficient C program +which operates in isolation. +.TP +Federated supernodes + +This is a cluster of supernodes which share information. Edges registered to any +of the cooperating supernodes can relay packets through the supernode federation +and switch supernodes if required. Supernodes can send PACKET or REGISTER +messages to other supernodes to try and find the destination edge. + +.P +The n2n-2 edge implementation allows multiple supernodes to be specified on the +command line. Edges monitor the current supernode for responses to +REGISTER_SUPER messages. If 3 responses are missed then the edge starts looking +for a new supernode. It cycles through the list of supernodes specified until it +finds a working one. + +.SH EFFICIENCY +The n2n-2 message formats have been made more efficient. The amount of data +overhead has been reduced by ensuring the messages contain only the data fields +required. Some optional fields do not consume data if they are not present. + +.SH DAEMON OPERATION +The supernode and edge use daemon mode of operation by default. This sense is +inverted from n2n-1 where they ran in the foreground by default. They can be +made to run in the foreground so tools such a DJB's daemontools can work with +them. See the +.B -f +option + +.SH MANAGEMENT CONSOLE +Edge and supernode in n2n-2 provide a UDP-based management console. Both listen +on the localhost address 127.0.0.1. Commands can be sent to the programs by +sending to the UDP socket. Responses are returned to the socket from which +commands were issued. This only works from the computer on which the programs +are running. Statistics can be retrieved and commands issued. The netcat utility +is all that is required; but more sophisticated tools could be built on the +interface. + +.SH SUPERNODE AUTHENTICATION +.B (To be implemented) +Space has been reserved in the supernode registration messages for an +authentication mechanism. + +.SH MESSAGE SUMMARY +The following message types work within n2n-2. +.TP +REGISTER_SUPER +Sent from an edge to its local supernode to register its MAC with the community. +.TP +REGISTER_SUPER_ACK +Sent from a supernode to an edge to confirm registration. This also carries the +definition of the edge socket as seen at the supernode so NAT can be detected +and described. +.TP +REGISTER_SUPER_NAK +Supernode refusing to register an edge. +.TP +PACKET +Encapsulated ethernet packets sent between edges. Supernodes forward or +broadcast these and edges send them direct in peer-to-peer mode. +.TP +REGISTER +A peer-to-peer mode registration request from one edge to another. Supernodes +forward these to facilitate NAT crossing introductions. +.TP +REGISTER_ACK +Complete peer-to-peer mode setup between two edges. These messages need to +travel direct between edges. +.TP +FEDERATION +Federated supernodes exchanging community information. + +.SH OTHER DIFFERENCES +.TP +HTTP Tunneling +This experimental feature (-t option in n2n_v1) of n2n_v1 has been removed +entirely from n2n_v2. +.SH AUTHORS +.TP +Richard Andrews andrews (at) ntop.org - main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - code inherited from n2n-1 +.SH SEE ALSO +ifconfig(8) edge(8) supernode(1) diff --git a/bundles/n2n_ntop_v2/packages/centos b/bundles/n2n_ntop_v2/packages/centos new file mode 100644 index 00000000..7c88ef3c --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/centos @@ -0,0 +1 @@ +rpm \ No newline at end of file diff --git a/bundles/n2n_ntop_v2/packages/debian/Makefile.in b/bundles/n2n_ntop_v2/packages/debian/Makefile.in new file mode 100644 index 00000000..68467aa8 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/Makefile.in @@ -0,0 +1,38 @@ +# +# Change it according to your setup +# +N2N_HOME=$(PWD)/../.. +N2N_BUILD=${N2N_HOME}/packages/debian/n2n + +all: clean pkg + +pkg: + cd ../..; make; cd - + if test -e "${N2N_BUILD}"; then /bin/rm -fr ${N2N_BUILD}; fi + mkdir -p ${N2N_BUILD}/usr/sbin ${N2N_BUILD}/usr/share/man/man1 ${N2N_BUILD}/usr/share/man/man7 ${N2N_BUILD}/usr/share/man/man8 + install -m755 ../../supernode ${N2N_BUILD}/usr/sbin/ + install -m755 ../../edge ${N2N_BUILD}/usr/sbin/ + install -m644 ../../edge.8.gz ${N2N_BUILD}/usr/share/man/man8/ + install -m644 ../../supernode.1.gz ${N2N_BUILD}/usr/share/man/man1/ + install -m644 ../../n2n.7.gz ${N2N_BUILD}/usr/share/man/man7/ + @/bin/rm -f ../n2n*.deb + dpkg-buildpackage -rfakeroot -d -us -uc + dpkg-sig --sign builder -k D1EB60BE ../n2n_*deb + @\rm -f ../n2n_*dsc ../n2n_*.gz ../n2n_*changes + @/bin/mv ../n2n_*deb . + @echo + @echo "Package built." + @/bin/ls n2n_*deb + @echo "-------------------------------" + -dpkg -I n2n_*deb + -dpkg --contents n2n_*deb + @echo "-------------------------------" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + rm -rf *~ *deb diff --git a/bundles/n2n_ntop_v2/packages/debian/README b/bundles/n2n_ntop_v2/packages/debian/README new file mode 100644 index 00000000..915a7c15 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/README @@ -0,0 +1,21 @@ +Prerequisites +------------- +apt-get install debhelper fakeroot dpkg-sig + +EdgeOS +------ +We need to replace BusyBox-implemented commands using full-fledged commands by doing +(see http://community.ubnt.com/t5/EdgeMAX/ubnt-debian-package-conflict/m-p/421325) + +curl -O http://ftp.us.debian.org/debian/pool/main/c/coreutils/coreutils_8.5-1_mips.deb +dpkg -i --force-all coreutils_8.5-1_mips.deb + +curl -O http://ftp.us.debian.org/debian/pool/main/t/tar/tar_1.23-3_mips.deb +dpkg -i --force-all tar_1.23-3_mips.deb + +wget http://ftp.us.debian.org/debian/pool/main/f/findutils/findutils_4.4.2-4_mips.deb +dpkg -i --force-all findutils_4.4.2-4_mips.deb + +wget http://ftp.us.debian.org/debian/pool/main/g/gzip/gzip_1.5-1.1_mips.deb +dpkg -i --force-all gzip_1.5-1.1_mips.deb + diff --git a/bundles/n2n_ntop_v2/packages/debian/configure.in b/bundles/n2n_ntop_v2/packages/debian/configure.in new file mode 100644 index 00000000..fe86b74a --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/configure.in @@ -0,0 +1,50 @@ +AC_INIT([Makefile.in], 1.0) + +# NOTE: this file is not actually used. You need to edit configure as well! +N2N_VERSION_SHORT=`grep N2N_VERSION_SHORT ../../Makefile | head -1| cut -d "=" -f 2` +GIT_COMMITS=`grep GIT_COMMITS ../../Makefile | head -1| cut -d "=" -f 2` + +MACHINE=`uname -m` +SHORT_MACHINE=`uname -m | cut -b1-3` + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + if test $SHORT_MACHINE = "aar"; then + EXTN="arm64" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "arm"; then + EXTN="armhf" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "mip"; then + EXTN="mips" + EXTRA_DEPS="" + else + EXTN="i386" + fi + fi + fi +fi + +APP=n2n +DATE=`date -R` + +AC_SUBST(APP) +AC_SUBST(MACHINE) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(EXTN) +AC_SUBST(DATE) + +AC_CONFIG_FILES(debian/changelog) +AC_CONFIG_FILES(debian/files) +AC_CONFIG_FILES(debian/control) +AC_CONFIG_FILES(debian/rules) +AC_CONFIG_FILES(../etc/systemd/system/edge.service) +AC_CONFIG_FILES(../etc/systemd/system/edge@.service) +AC_CONFIG_FILES(../etc/systemd/system/edge-ntopng@.service) +AC_CONFIG_FILES(../etc/systemd/system/supernode.service) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/COPYRIGHT b/bundles/n2n_ntop_v2/packages/debian/debian/COPYRIGHT new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/COPYRIGHT @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/README b/bundles/n2n_ntop_v2/packages/debian/debian/README new file mode 100644 index 00000000..8d88f8df --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/README @@ -0,0 +1,2 @@ +This directory contains the files needed to build the package +named 'n2n' for the Debian GNU/Linux distribution. diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/changelog.in b/bundles/n2n_ntop_v2/packages/debian/debian/changelog.in new file mode 100644 index 00000000..6d4e3dc2 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/changelog.in @@ -0,0 +1,4 @@ +@APP@ (@N2N_VERSION_SHORT@-@GIT_COMMITS@) table; urgency=high + * Last packaged version + + -- Luca Deri @DATE@ diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/compat b/bundles/n2n_ntop_v2/packages/debian/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/compat @@ -0,0 +1 @@ +9 diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/conffiles b/bundles/n2n_ntop_v2/packages/debian/debian/conffiles new file mode 100644 index 00000000..d467c8b7 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/conffiles @@ -0,0 +1,2 @@ +/etc/n2n/edge.conf.sample +/etc/n2n/supernode.conf.sample diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/control.in b/bundles/n2n_ntop_v2/packages/debian/debian/control.in new file mode 100644 index 00000000..77e2fe92 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/control.in @@ -0,0 +1,25 @@ +Source: n2n +Section: net +Priority: extra +Maintainer: Luca Deri +Standards-Version: @N2N_VERSION_SHORT@ +Build-Depends: + +Package: n2n +Architecture: @EXTN@ +Suggests: uml-utilities +Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: n2n (<< 2.1.0-1) +Replaces: n2n (<< 2.1.0-1) +Description: a layer-two peer-to-peer virtual private network (VPN) + n2n is a layer-two peer-to-peer virtual private network (VPN) which allows + users to exploit features typical of P2P applications at network instead of + application level. This means that users can gain native IP visibility (e.g. + two PCs belonging to the same n2n network can ping each other) and be + reachable with the same network IP address regardless of the network where + they currently belong. In a nutshell, as OpenVPN moved SSL from application + (e.g. used to implement the https protocol) to network protocol, n2n moves + P2P from application to network level. + . + Edge is the edge node daemon for n2n which creates a TAP interface to expose + the n2n virtual LAN. diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/dirs b/bundles/n2n_ntop_v2/packages/debian/debian/dirs new file mode 100644 index 00000000..8a9632d0 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/dirs @@ -0,0 +1,3 @@ +usr/sbin +etc/systemd +etc/init.d diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/docs b/bundles/n2n_ntop_v2/packages/debian/debian/docs new file mode 100644 index 00000000..e845566c --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/docs @@ -0,0 +1 @@ +README diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/files.in b/bundles/n2n_ntop_v2/packages/debian/debian/files.in new file mode 100644 index 00000000..6128dce3 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/files.in @@ -0,0 +1 @@ +n2n_@N2N_VERSION_SHORT@_@EXTN@.deb free optional diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/n2n.debhelper.log b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.debhelper.log new file mode 100644 index 00000000..439b7b43 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.debhelper.log @@ -0,0 +1,13 @@ +dh_installdirs +dh_installdirs +dh_installinit +dh_installdebconf +dh_installman +dh_strip +dh_compress +dh_fixperms +dh_installdeb +dh_link +dh_gencontrol +dh_md5sums +dh_builddeb diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/n2n.postrm.debhelper b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.postrm.debhelper new file mode 100644 index 00000000..500916c2 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.postrm.debhelper @@ -0,0 +1,6 @@ +# Automatically added by dh_installdebconf/11.1.6ubuntu2 +if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then + . /usr/share/debconf/confmodule + db_purge +fi +# End automatically added section diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/n2n.substvars b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.substvars new file mode 100644 index 00000000..a5957235 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/n2n.substvars @@ -0,0 +1,2 @@ +misc:Depends=debconf (>= 0.5) | debconf-2.0 +misc:Pre-Depends= diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/postinst b/bundles/n2n_ntop_v2/packages/debian/debian/postinst new file mode 100644 index 00000000..5de13e21 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/postinst @@ -0,0 +1,56 @@ +#!/bin/sh -e + +case "$1" in + configure) + # continue below + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + exit 0 + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +umask 022 + +if ! grep -q n2n /etc/group; then + echo 'Creating n2n group' + /usr/sbin/groupadd -r n2n +fi + +if ! /usr/bin/id -u n2n > /dev/null 2>&1; then + echo "Creating n2n user..." + /usr/sbin/useradd -M -N -g n2n -r -s /bin/false n2n +fi + +echo "Rebuilding ld cache..." +/sbin/ldconfig + +if [ -f /.dockerenv ]; then exit 0; fi + +# Start service after upgrade/install +systemctl daemon-reload +systemctl reset-failed + +# Enable edge +if systemctl -q is-active edge; then + # only restart edge if it's already running + echo "Restarting n2n edge..." + deb-systemd-invoke restart edge +fi + +# Restart specific services if already running +deb-systemd-invoke restart 'edge@*.service' 'edge-ntopng@*.service' + +# Enable supernode +if systemctl -q is-active supernode; then + # only restart supernode if it's already running + echo "Restarting n2n supernode..." + deb-systemd-invoke restart supernode +fi + +exit 0 diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/postrm b/bundles/n2n_ntop_v2/packages/debian/debian/postrm new file mode 100644 index 00000000..ef799a3a --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/postrm @@ -0,0 +1,11 @@ +#!/bin/sh -e + +set -e + +#case "$1" in +# purge|remove) +# +# ;; +#esac + +exit 0 diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/preinst b/bundles/n2n_ntop_v2/packages/debian/debian/preinst new file mode 100644 index 00000000..4e7a80dc --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/preinst @@ -0,0 +1,31 @@ +#! /bin/sh +# preinst script for n2n +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' + +case "$1" in + install|upgrade) + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + + +exit 0 diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/prerm b/bundles/n2n_ntop_v2/packages/debian/debian/prerm new file mode 100644 index 00000000..9e4e53d7 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/prerm @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +if [ -f /.dockerenv ]; then exit 0; fi + +. /usr/share/debconf/confmodule + +if [ "$1" = "remove" ]; then + deb-systemd-invoke stop edge.service 'edge@*.service' 'edge-ntopng@*.service' + deb-systemd-invoke disable edge.service 'edge@*.service' 'edge-ntopng@*.service' + deb-systemd-invoke stop supernode.service + deb-systemd-invoke disable supernode.service + systemctl daemon-reload + systemctl reset-failed +fi + +exit 0 diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/rules.in b/bundles/n2n_ntop_v2/packages/debian/debian/rules.in new file mode 100644 index 00000000..8fcc3434 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/rules.in @@ -0,0 +1,59 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +# export DH_VERBOSE=1 + +# +# debian/compat +# We should use at least compatibility version 5 +# but this requires the whole building process +# to be remade and this is something we leave +# to when we will have more time +# http://www.tin.org/bin/man.cgi?section=7&topic=debhelper +# + +package=@APP@ + +build: build-stamp +build-stamp: + dh_testdir + +clean: + dh_testdir + dh_testroot + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + dh_installinit + dh_installdebconf + dh_installman + dh_strip + dh_compress + dh_fixperms + dh_installdeb + cp -r n2n debian + cp -r ../etc debian/n2n + find debian/n2n -name "*.in" -exec /bin/rm {} ';' + find debian/n2n -name "*~" -exec /bin/rm {} ';' + dh_link + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/bundles/n2n_ntop_v2/packages/debian/debian/templates b/bundles/n2n_ntop_v2/packages/debian/debian/templates new file mode 100644 index 00000000..4f354077 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/debian/debian/templates @@ -0,0 +1,7 @@ +Template: n2n/license_expired_continue_installation +Type: boolean +Default: true +Description: Do you want to continue with the installation? + License found is not valid for the new package that is going to be installed. + . + Renew the maintenance to get a valid license for the new package or cancel the installation to continue using the current package. diff --git a/bundles/n2n_ntop_v2/packages/etc/n2n/edge.conf.sample b/bundles/n2n_ntop_v2/packages/etc/n2n/edge.conf.sample new file mode 100644 index 00000000..74d50a8f --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/n2n/edge.conf.sample @@ -0,0 +1,41 @@ +# +# The configuration file is similar to the command line, with one option per line. An equal +# sign '=' should be used between key and value. Example: -c=mynetwork or --community=mynetwork +# This file contains a basic configuration example, please refer to the help (-h) for the full +# list of available options. +# +# -d|--tun-device +# Specifies the name of the TUN interface. +# +-d=n2n0 +# +# -c|--community +# Specifies the n2n community name the edge belongs to. +# +-c=mynetwork +# +# -k +# Sets the encryption key (ASCII). The environment variable N2N_KEY= can also be used. +# +-k=mypassword +# +# -m +# Specified the MAC address for the TAP interface (random otherwise). +# +# -m=DE:AD:BE:EF:99:99 +# +# -a +# Sets the interface address. For DHCP use '-r -a dhcp:0.0.0.0'. +# +-a=1.2.3.4 +# +# -p +# Sets the local UDP port to a fixed port. +# +-p=50001 +# +# -l|--supernode-list +# Specifies the supernode IP and port. +# +-l=7.8.9.0:7777 +# diff --git a/bundles/n2n_ntop_v2/packages/etc/n2n/supernode.conf.sample b/bundles/n2n_ntop_v2/packages/etc/n2n/supernode.conf.sample new file mode 100644 index 00000000..9ad22815 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/n2n/supernode.conf.sample @@ -0,0 +1,14 @@ +# +# The configuration file is similar to the command line, with one option per line. An equal +# sign '=' should be used between key and value. Example: -l=7777 or --local-port=7777 +# This file contains a basic configuration example, please refer to the help (-h) for the full +# list of available options. +# +# -l|--local-port +# Sets the UDP listening port. +# +# -l=7777 +# +# Specify in supernodes.list the list of allowed communities +# +# -c=supernodes.list diff --git a/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge-ntopng@.service.in b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge-ntopng@.service.in new file mode 100644 index 00000000..5299d227 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge-ntopng@.service.in @@ -0,0 +1,16 @@ +[Unit] +Description=n2n edge process, on %I +After=network-online.target syslog.target +Wants=network-online.target +BindsTo=ntopng.service + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge-%i.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=ntopng.service +Alias= diff --git a/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge.service.in b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge.service.in new file mode 100644 index 00000000..32f0d79d --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge.service.in @@ -0,0 +1,15 @@ +[Unit] +Description=n2n edge process +After=network-online.target syslog.target nfw.target +Wants=network-online.target + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge@.service.in b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge@.service.in new file mode 100644 index 00000000..d9123452 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/systemd/system/edge@.service.in @@ -0,0 +1,15 @@ +[Unit] +Description=n2n edge process, on %I +After=network-online.target syslog.target nfw.target +Wants=network-online.target + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge-%i.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v2/packages/etc/systemd/system/supernode.service.in b/bundles/n2n_ntop_v2/packages/etc/systemd/system/supernode.service.in new file mode 100644 index 00000000..73e3d758 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/etc/systemd/system/supernode.service.in @@ -0,0 +1,16 @@ +[Unit] +Description=n2n supernode process +After=network-online.target syslog.target +Wants=network-online.target + +[Service] +Type=simple +User=n2n +Group=n2n +ExecStart=/usr/sbin/supernode /etc/n2n/supernode.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v2/packages/openwrt/README.md b/bundles/n2n_ntop_v2/packages/openwrt/README.md new file mode 100644 index 00000000..44b229fe --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/openwrt/README.md @@ -0,0 +1,39 @@ +## Prerequisites + +This instructions explain how to build an OpenWRT .ipk package for n2n. + +Before going on, it is required to have a working cross-compiling build +environment for the OpenWRT version installed into your device. This usually +comes down to the following steps: + +1. Download and extract the SDK toolchain for your device. The toolchain + must match the *exact* OpenWRT version installed in your device. Toolchain + for official OpenWRT images can be downloaded from https://downloads.openwrt.org + +2. Build the toolchain: run `make menuconfig`, save the configuration, then + run `make` to build the cross compiling tools + +3. Download the feeds with `./scripts/feeds update -a` + +## Compilation + +From the OpenWRT build directory: + +``` +git clone https://github.com/ntop/n2n n2n +cp -r n2n/packages/openwrt package/n2n +make menuconfig # select Network -> VPN -> n2n-edge and n2n-supernode +make package/n2n/compile V=s +``` + +If everything went fine, two ipk will be generated, one for the n2n-edge +and the other for n2n-supernode. They can be found with `find . -name "n2n*.ipk"`, +copied to the target device, and installed with `opkg install`. + +## Configuration + +The edge node can be started with `/etc/init.d/edge start`. +Its configuration file is `/etc/n2n/edge.conf`. + +The supernode can be started with `/etc/init.d/supernode start`. +Its configuration file is `/etc/n2n/supernode.conf`. diff --git a/bundles/n2n_ntop_v2/packages/rpm/Makefile.in b/bundles/n2n_ntop_v2/packages/rpm/Makefile.in new file mode 100644 index 00000000..d7d677a2 --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/rpm/Makefile.in @@ -0,0 +1,26 @@ +# +# Change it according to your setup +# +N2N_HOME=$(PWD)/../.. +N2N_BUILD=${N2N_HOME}/packages/debian/n2n +PLATFORM=@MACHINE@ +RPM_PKG=n2n-@N2N_VERSION_SHORT@-@GIT_COMMITS@.$(PLATFORM).rpm + +all: clean pkg + +pkg: + rpmbuild -bb ./n2n.spec + @@RPM_SIGN_CMD@ $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG) + @echo "" + @echo "Package contents:" + @rpm -qpl $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG) + @echo "The package is now available in $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG)" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + rm -rf *~ *rpm diff --git a/bundles/n2n_ntop_v2/packages/rpm/configure.in b/bundles/n2n_ntop_v2/packages/rpm/configure.in new file mode 100644 index 00000000..cce9205b --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/rpm/configure.in @@ -0,0 +1,58 @@ +AC_INIT([Makefile.in], 1.0) + +# NOTE: this file is not actually used. You need to edit configure as well! +N2N_VERSION_SHORT=`grep N2N_VERSION_SHORT ../../Makefile | head -1| cut -d "=" -f 2` +GIT_COMMITS=`grep GIT_COMMITS ../../Makefile | head -1| cut -d "=" -f 2` + +MACHINE=`uname -m` +SHORT_MACHINE=`uname -m | cut -b1-3` + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + if test $SHORT_MACHINE = "aar"; then + EXTN="arm64" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "arm"; then + EXTN="armhf" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "mip"; then + EXTN="mips" + EXTRA_DEPS="" + else + EXTN="i386" + fi + fi + fi +fi + +APP=n2n +DATE=`date -R` + +CENTOS_RELEASE=`cat /etc/centos-release | cut -d ' ' -f 3|cut -d '.' -f 1` +if test $CENTOS_RELEASE = "release"; then + CENTOS_RELEASE=`cat /etc/centos-release | cut -d ' ' -f 4|cut -d '.' -f 1` +fi + +RPM_SIGN_CMD="rpm --addsign" +if test "$CENTOS_RELEASE" -ne 8; then + RPM_SIGN_CMD="./rpm-sign.exp" +fi + +AC_SUBST(APP) +AC_SUBST(MACHINE) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(EXTN) +AC_SUBST(DATE) +AC_SUBST(RPM_SIGN_CMD) + +AC_CONFIG_FILES(n2n.spec) +AC_CONFIG_FILES(../etc/systemd/system/edge.service) +AC_CONFIG_FILES(../etc/systemd/system/edge@.service) +AC_CONFIG_FILES(../etc/systemd/system/edge-ntopng@.service) +AC_CONFIG_FILES(../etc/systemd/system/supernode.service) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/bundles/n2n_ntop_v2/packages/rpm/n2n.spec.in b/bundles/n2n_ntop_v2/packages/rpm/n2n.spec.in new file mode 100644 index 00000000..301a205c --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/rpm/n2n.spec.in @@ -0,0 +1,98 @@ +Summary: n2n peer-to-peer VPN +Name: n2n +Version: @N2N_VERSION_SHORT@ +Release: @GIT_COMMITS@ +License: GPL +Group: Networking/Utilities +URL: http://www.ntop.org/ +Source: n2n-%{version}.tgz +Packager: Luca Deri +# Temporary location where the RPM will be built +BuildRoot: %{_tmppath}/%{name}-%{version}-root +#Requires: ntopng + +%description +n2n peer-to-peer VPN + +%prep + +%build + +mkdir -p $RPM_BUILD_ROOT/usr/sbin $RPM_BUILD_ROOT/usr/share/man/man1 $RPM_BUILD_ROOT/usr/share/man/man7 $RPM_BUILD_ROOT/usr/share/man/man8 +mkdir -p $RPM_BUILD_ROOT/etc/n2n +mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system/ +cp $HOME/n2n/edge $RPM_BUILD_ROOT/usr/sbin +cp $HOME/n2n/supernode $RPM_BUILD_ROOT/usr/sbin +cp $HOME/n2n/n2n.7.gz $RPM_BUILD_ROOT/usr/share/man/man7 +cp $HOME/n2n/supernode.1.gz $RPM_BUILD_ROOT/usr/share/man/man1 +cp $HOME/n2n/edge.8.gz $RPM_BUILD_ROOT/usr/share/man/man8 +cp $HOME/n2n/packages/etc/systemd/system/*.service $RPM_BUILD_ROOT/usr/lib/systemd/system/ +cp $HOME/n2n/packages/etc/n2n/*.conf.sample $RPM_BUILD_ROOT/etc/n2n + +find $RPM_BUILD_ROOT -name ".git" | xargs /bin/rm -rf +find $RPM_BUILD_ROOT -name ".svn" | xargs /bin/rm -rf +find $RPM_BUILD_ROOT -name "*~" | xargs /bin/rm -f +# +DST=$RPM_BUILD_ROOT/usr/n2n +SRC=$RPM_BUILD_DIR/%{name}-%{version} +#mkdir -p $DST/conf +# Clean out our build directory +%clean +rm -fr $RPM_BUILD_ROOT + +%files +/usr/sbin/edge +/usr/sbin/supernode +/usr/share/man/man7/n2n.7.gz +/usr/share/man/man1/supernode.1.gz +/usr/share/man/man8/edge.8.gz +/usr/lib/systemd/system/edge.service +/usr/lib/systemd/system/edge@.service +/usr/lib/systemd/system/edge-ntopng@.service +/usr/lib/systemd/system/supernode.service +%config(noreplace) /etc/n2n/supernode.conf.sample +%config(noreplace) /etc/n2n/edge.conf.sample + +# Set the default attributes of all of the files specified to have an +# owner and group of root and to inherit the permissions of the file +# itself. +%defattr(-, root, root) + +%changelog +* Fri Aug 17 2018 Luca Deri 1.0 +- Current package version + +# Execution order: +# install: pre -> (copy) -> post +# upgrade: pre -> (copy) -> post -> preun (old) -> (delete old) -> postun (old) +# un-install: preun -> (delete) -> postun + +%pre + +if ! grep -q n2n /etc/group; then + echo 'Creating n2n group' + /usr/sbin/groupadd -r n2n +fi + +if ! /usr/bin/id -u n2n > /dev/null 2>&1; then + echo 'Creating n2n user' + /usr/sbin/useradd -M -N -g n2n -r -s /bin/false n2n +fi + +%post +if [ ! -f /.dockerenv ]; then + /bin/systemctl daemon-reload + # NOTE: do not enable any services during first installation +fi + +%preun +if [ ! -f /.dockerenv ]; then + # possibly remove the installed services + %systemd_preun supernode.service edge.service 'edge-ntopng@*.service' 'edge@*.service' +fi + +%postun +if [ ! -f /.dockerenv ]; then + # possibly restart the running services + %systemd_postun_with_restart supernode.service edge.service 'edge-ntopng@*.service' 'edge@*.service' +fi diff --git a/bundles/n2n_ntop_v2/packages/rpm/rpm-sign.exp b/bundles/n2n_ntop_v2/packages/rpm/rpm-sign.exp new file mode 100644 index 00000000..7a0f88af --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/rpm/rpm-sign.exp @@ -0,0 +1,10 @@ +#!/usr/bin/expect -f + +### rpm-sign.exp -- Sign RPMs by sending the passphrase. + +spawn rpm --addsign {*}$argv + expect -exact "Enter pass phrase: " + send -- "\r" + expect eof + +## end of rpm-sign.exp diff --git a/bundles/n2n_ntop_v2/packages/ubuntu b/bundles/n2n_ntop_v2/packages/ubuntu new file mode 100644 index 00000000..b2f7fd3e --- /dev/null +++ b/bundles/n2n_ntop_v2/packages/ubuntu @@ -0,0 +1 @@ +debian \ No newline at end of file diff --git a/bundles/n2n_ntop_v2/src/edge.c b/bundles/n2n_ntop_v2/src/edge.c new file mode 100644 index 00000000..5681df84 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/edge.c @@ -0,0 +1,972 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +/* *************************************************** */ + +/** maximum length of command line arguments */ +#define MAX_CMDLINE_BUFFER_LENGTH 4096 + +/** maximum length of a line in the configuration file */ +#define MAX_CONFFILE_LINE_LENGTH 1024 + +/* ***************************************************** */ + +#ifdef HAVE_LIBCAP + +#include +#include + +static cap_value_t cap_values[] = { + //CAP_NET_RAW, /* Use RAW and PACKET sockets */ + CAP_NET_ADMIN /* Needed to performs routes cleanup at exit */ +}; + +int num_cap = sizeof(cap_values)/sizeof(cap_value_t); +#endif + +/* ***************************************************** */ + +/** Find the address and IP mode for the tuntap device. + * + * s is one of these forms: + * + * := | A.B.C.D + * + * | static: | dhcp: + * + * If the mode is present (colon required) then fill ip_mode with that value + * otherwise do not change ip_mode. Fill ip_mode with everything after the + * colon if it is present; or s if colon is not present. + * + * ip_add and ip_mode are NULL terminated if modified. + * + * return 0 on success and -1 on error + */ +static int scan_address(char * ip_addr, size_t addr_size, + char * ip_mode, size_t mode_size, + const char * s) { + int retval = -1; + char * p; + + if((NULL == s) || (NULL == ip_addr)) + { + return -1; + } + + memset(ip_addr, 0, addr_size); + + p = strpbrk(s, ":"); + + if(p) + { + /* colon is present */ + if(ip_mode) + { + size_t end=0; + + memset(ip_mode, 0, mode_size); + end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */ + strncpy(ip_mode, s, end); + strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */ + retval = 0; + } + } + else + { + /* colon is not present */ + strncpy(ip_addr, s, addr_size-1); + ip_addr[addr_size-1] = '\0'; + } + + return retval; +} + +/* *************************************************** */ + +static void help() { + print_n2n_version(); + + printf("edge (see edge.conf)\n" + "or\n" + ); + printf("edge " +#if defined(N2N_CAN_NAME_IFACE) + "-d " +#endif /* #if defined(N2N_CAN_NAME_IFACE) */ + "-a [static:|dhcp:] " + "-c " + "[-k ]\n" + " " + "[-s ] " +#ifndef WIN32 + "[-u -g ]" +#endif /* #ifndef WIN32 */ + +#ifndef WIN32 + "[-f]" +#endif /* #ifndef WIN32 */ +#ifdef __linux__ + "[-T ]" +#endif + "[-n cidr:gateway] " + "[-m ] " + "-l \n" + " " + "[-p ] [-M ] " +#ifndef __APPLE__ + "[-D] " +#endif + "[-r] [-E] [-v] [-i ] [-L ] [-t ] [-A[]] [-H] [-z[]] [-h]\n\n"); + +#if defined(N2N_CAN_NAME_IFACE) + printf("-d | tun device name\n"); +#endif + + printf("-a | Set interface address. For DHCP use '-r -a dhcp:0.0.0.0'\n"); + printf("-c | n2n community name the edge belongs to.\n"); + printf("-k | Encryption key (ASCII) - also N2N_KEY=.\n"); + printf("-s | Edge interface netmask in dotted decimal notation (255.255.255.0).\n"); + printf("-l | Supernode IP:port\n"); + printf("-i | Registration interval, for NAT hole punching (default 20 seconds)\n"); + printf("-L | TTL for registration packet when UDP NAT hole punching through supernode (default 0 for not set )\n"); + printf("-p | Fixed local UDP port.\n"); +#ifndef WIN32 + printf("-u | User ID (numeric) to use when privileges are dropped.\n"); + printf("-g | Group ID (numeric) to use when privileges are dropped.\n"); +#endif /* ifndef WIN32 */ +#ifndef WIN32 + printf("-f | Do not fork and run as a daemon; rather run in foreground.\n"); +#endif /* #ifndef WIN32 */ + printf("-m | Fix MAC address for the TAP interface (otherwise it may be random)\n" + " | eg. -m 01:02:03:04:05:06\n"); + printf("-M | Specify n2n MTU of edge interface (default %d).\n", DEFAULT_MTU); +#ifndef __APPLE__ + printf("-D | Enable PMTU discovery. PMTU discovery can reduce fragmentation but\n" + " | causes connections stall when not properly supported.\n"); +#endif + printf("-r | Enable packet forwarding through n2n community.\n"); + printf("-A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then).\n"); + printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default),\n"); + printf(" | " +#ifdef N2N_HAVE_AES + "-A3 or -A (deprecated) = AES-CBC, " +#endif +#ifdef HAVE_OPENSSL_1_1 + "-A4 = ChaCha20, " +#endif + "-A5 = Speck-CTR.\n"); + printf("-H | Enable full header encryption. Requires supernode with fixed community.\n"); + printf("-z1 ... -z2 or -z | Enable compression for outgoing data packets: -z1 or -z = lzo1x" +#ifdef N2N_HAVE_ZSTD + ", -z2 = zstd" +#endif + " (default=disabled).\n"); + printf("-E | Accept multicast MAC addresses (default=drop).\n"); + printf("-S | Do not connect P2P. Always use the supernode.\n"); +#ifdef __linux__ + printf("-T | TOS for packets (e.g. 0x48 for SSH like priority)\n"); +#endif + printf("-n | Route an IPv4 network via the gw. Use 0.0.0.0/0 for the default gw. Can be set multiple times.\n"); + printf("-v | Make more verbose. Repeat as required.\n"); + printf("-t | Management UDP Port (for multiple edges on a machine).\n"); + + printf("\nEnvironment variables:\n"); + printf(" N2N_KEY | Encryption key (ASCII). Not with -k.\n"); + +#ifdef WIN32 + printf("\nAvailable TAP adapters:\n"); + win_print_available_adapters(); +#endif + + exit(0); +} + +/* *************************************************** */ + +static void setPayloadCompression(n2n_edge_conf_t *conf, int compression) { + /* even though 'compression' and 'conf->compression' share the same encoding scheme, + * a switch-statement under conditional compilation is used to sort out the + * unsupported optarguments */ + switch (compression) { + case 1: + { + conf->compression = N2N_COMPRESSION_ID_LZO; + break; + } +#ifdef N2N_HAVE_ZSTD + case 2: + { + conf->compression = N2N_COMPRESSION_ID_ZSTD; + break; + } +#endif + default: + { + conf->compression = N2N_COMPRESSION_ID_NONE; + traceEvent(TRACE_NORMAL, "the %s compression given by -z_ option is not supported in this version.", compression_str(compression)); + exit(1); // to make the user aware + } + } +} + +/* *************************************************** */ + +static void setPayloadEncryption( n2n_edge_conf_t *conf, int cipher) { + /* even though 'cipher' and 'conf->transop_id' share the same encoding scheme, + * a switch-statement under conditional compilation is used to sort out the + * unsupported ciphers */ + switch (cipher) { + case 1: + { + conf->transop_id = N2N_TRANSFORM_ID_NULL; + break; + } + case 2: + { + conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; + break; + } +#ifdef N2N_HAVE_AES + case 3: + { + conf->transop_id = N2N_TRANSFORM_ID_AESCBC; + break; + } +#endif +#ifdef HAVE_OPENSSL_1_1 + case 4: + { + conf->transop_id = N2N_TRANSFORM_ID_CHACHA20; + break; + } +#endif + case 5: + { + conf->transop_id = N2N_TRANSFORM_ID_SPECK; + break; + } + default: + { + conf->transop_id = N2N_TRANSFORM_ID_INVAL; + traceEvent(TRACE_NORMAL, "the %s cipher given by -A_ option is not supported in this version.", transop_str(cipher)); + exit(1); + } + } +} + +/* *************************************************** */ + +static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec, n2n_edge_conf_t *conf) { + /* traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, optargument ? optargument : ""); */ + + switch(optkey) { + case 'a': /* IP address and mode of TUNTAP interface */ + { + scan_address(ec->ip_addr, N2N_NETMASK_STR_SIZE, + ec->ip_mode, N2N_IF_MODE_SIZE, + optargument); + break; + } + + case 'c': /* community as a string */ + { + memset(conf->community_name, 0, N2N_COMMUNITY_SIZE); + strncpy((char *)conf->community_name, optargument, N2N_COMMUNITY_SIZE); + conf->community_name[N2N_COMMUNITY_SIZE-1] = '\0'; + break; + } + + case 'E': /* multicast ethernet addresses accepted. */ + { + conf->drop_multicast=0; + traceEvent(TRACE_DEBUG, "Enabling ethernet multicast traffic"); + break; + } + +#ifndef WIN32 + case 'u': /* unprivileged uid */ + { + ec->userid = atoi(optargument); + break; + } + + case 'g': /* unprivileged uid */ + { + ec->groupid = atoi(optargument); + break; + } +#endif + +#ifndef WIN32 + case 'f' : /* do not fork as daemon */ + { + ec->daemon=0; + break; + } +#endif /* #ifndef WIN32 */ + + case 'm' : /* TUNTAP MAC address */ + { + strncpy(ec->device_mac,optargument,N2N_MACNAMSIZ); + ec->device_mac[N2N_MACNAMSIZ-1] = '\0'; + break; + } + + case 'M' : /* TUNTAP MTU */ + { + ec->mtu = atoi(optargument); + break; + } + +#ifndef __APPLE__ + case 'D' : /* enable PMTU discovery */ + { + conf->disable_pmtu_discovery = 0; + break; + } +#endif + + case 'k': /* encrypt key */ + { + if(conf->encrypt_key) free(conf->encrypt_key); + conf->encrypt_key = strdup(optargument); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", conf->encrypt_key); + break; + } + + case 'r': /* enable packet routing across n2n endpoints */ + { + conf->allow_routing = 1; + break; + } + + case 'A': + { + int cipher; + + if (optargument) { + cipher = atoi(optargument); + } else { + traceEvent(TRACE_NORMAL, "the use of the solitary -A switch is deprecated and might not be supported in future versions. " + "please use -A3 instead to choose a the AES-CBC cipher for payload encryption."); + + cipher = N2N_TRANSFORM_ID_AESCBC; // default, if '-A' only + } + + setPayloadEncryption(conf, cipher); + break; + } + + case 'H': /* indicate header encryption */ + { + /* we cannot be sure if this gets parsed before the community name is set. + * so, only an indicator is set, action is taken later*/ + conf->header_encryption = HEADER_ENCRYPTION_ENABLED; + break; + } + + case 'z': + { + int compression; + + if (optargument) { + compression = atoi(optargument); + } else + compression = N2N_COMPRESSION_ID_LZO; // default, if '-z' only + + setPayloadCompression(conf, compression); + break; + } + + case 'l': /* supernode-list */ + if(optargument) { + if(edge_conf_add_supernode(conf, optargument) != 0) { + traceEvent(TRACE_WARNING, "Too many supernodes!"); + exit(1); + } + break; + } + + case 'i': /* supernode registration interval */ + conf->register_interval = atoi(optargument); + break; + + case 'L': /* supernode registration interval */ + conf->register_ttl = atoi(optarg); + break; + +#if defined(N2N_CAN_NAME_IFACE) + case 'd': /* TUNTAP name */ + { + strncpy(ec->tuntap_dev_name, optargument, N2N_IFNAMSIZ); + ec->tuntap_dev_name[N2N_IFNAMSIZ-1] = '\0'; + break; + } +#endif + + case 'p': + { + conf->local_port = atoi(optargument); + break; + } + + case 't': + { + conf->mgmt_port = atoi(optargument); + break; + } + +#ifdef __linux__ + case 'T': + { + if((optargument[0] == '0') && (optargument[1] == 'x')) + conf->tos = strtol(&optargument[2], NULL, 16); + else + conf->tos = atoi(optargument); + + break; + } +#endif + + case 'n': + { + char cidr_net[64], gateway[64]; + n2n_route_t route; + + if(sscanf(optargument, "%63[^/]/%d:%63s", cidr_net, &route.net_bitlen, gateway) != 3) { + traceEvent(TRACE_WARNING, "Bad cidr/gateway format '%d'. See -h.", optargument); + break; + } + + route.net_addr = inet_addr(cidr_net); + route.gateway = inet_addr(gateway); + + if((route.net_bitlen < 0) || (route.net_bitlen > 32)) { + traceEvent(TRACE_WARNING, "Bad prefix '%d' in '%s'", route.net_bitlen, optargument); + break; + } + + if(route.net_addr == INADDR_NONE) { + traceEvent(TRACE_WARNING, "Bad network '%s' in '%s'", cidr_net, optargument); + break; + } + + if(route.gateway == INADDR_NONE) { + traceEvent(TRACE_WARNING, "Bad gateway '%s' in '%s'", gateway, optargument); + break; + } + + traceEvent(TRACE_DEBUG, "Adding %s/%d via %s", cidr_net, route.net_bitlen, gateway); + + conf->routes = realloc(conf->routes, sizeof(struct n2n_route) * (conf->num_routes + 1)); + conf->routes[conf->num_routes] = route; + conf->num_routes++; + + break; + } + + case 's': /* Subnet Mask */ + { + if(0 != ec->got_s) { + traceEvent(TRACE_WARNING, "Multiple subnet masks supplied"); + } + strncpy(ec->netmask, optargument, N2N_NETMASK_STR_SIZE); + ec->netmask[N2N_NETMASK_STR_SIZE - 1] = '\0'; + ec->got_s = 1; + break; + } + + case 'S': + { + conf->allow_p2p = 0; + break; + } + + case 'h': /* help */ + { + help(); + break; + } + + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + + default: + { + traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored", (char)optkey); + return(-1); + } + } + + return(0); +} + +/* *********************************************** */ + +static const struct option long_options[] = + { + { "community", required_argument, NULL, 'c' }, + { "supernode-list", required_argument, NULL, 'l' }, + { "tun-device", required_argument, NULL, 'd' }, + { "euid", required_argument, NULL, 'u' }, + { "egid", required_argument, NULL, 'g' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +/* *************************************************** */ + +/* read command line options */ +static int loadFromCLI(int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) { + u_char c; + + while ((c = getopt_long(argc, argv, + "k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:SDL:z::A::Hn:" +#ifdef __linux__ + "T:" +#endif + , + long_options, NULL)) != '?') { + if(c == 255) break; + setOption(c, optarg, ec, conf); + } + + return 0; +} + +/* *************************************************** */ + +static char *trim(char *s) { + char *end; + + while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) s++; + if(s[0] == 0) return s; + + end = &s[strlen(s) - 1]; + while(end > s + && (isspace(end[0])|| (end[0] == '"') || (end[0] == '\''))) + end--; + end[1] = 0; + + return s; +} + +/* *************************************************** */ + +/* parse the configuration file */ +static int loadFromFile(const char *path, n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) { + char buffer[4096], *line, *key, *value; + u_int line_len, opt_name_len; + FILE *fd; + const struct option *opt; + + fd = fopen(path, "r"); + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "Config file %s not found", path); + return -1; + } + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + line = trim(line); + value = NULL; + + if((line_len = strlen(line)) < 2 || line[0] == '#') + continue; + + if(!strncmp(line, "--", 2)) { /* long opt */ + key = &line[2], line_len -= 2; + + opt = long_options; + while(opt->name != NULL) { + opt_name_len = strlen(opt->name); + + if(!strncmp(key, opt->name, opt_name_len) + && (line_len <= opt_name_len + || key[opt_name_len] == '\0' + || key[opt_name_len] == ' ' + || key[opt_name_len] == '=')) { + if(line_len > opt_name_len) key[opt_name_len] = '\0'; + if(line_len > opt_name_len + 1) value = trim(&key[opt_name_len + 1]); + + // traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value); + setOption(opt->val, value, ec, conf); + break; + } + + opt++; + } + } else if(line[0] == '-') { /* short opt */ + char *equal; + + key = &line[1], line_len--; + + equal = strchr(line, '='); + + if(equal) { + equal[0] = '\0'; + + value = &equal[1]; + + } else { + + value = NULL; + + /* Adding an exception for -A_ -z_ which can come + without '=' and even without any further data */ + + if (key[0] == 'z') { + if (key[1]) value = &key[1]; + key = "z"; + } else if (key[0] == 'A') { + if (key[1]) value = &key[1]; + key = "A"; + } + } + // traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value); + setOption(key[0], value, ec, conf); + } else { + traceEvent(TRACE_WARNING, "Skipping unrecognized line: %s", line); + continue; + } + } + + fclose(fd); + + return 0; +} + +/* ************************************** */ + +#if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */ + +static char gratuitous_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* Ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* Hw Size */ + 0x04, /* Protocol Size */ + 0x00, 0x01, /* ARP Request */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ + 0x00, 0x00, 0x00, 0x00, /* Src IP */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ + 0x00, 0x00, 0x00, 0x00 /* Target IP */ +}; + +/* ************************************** */ + +/** Build a gratuitous ARP packet for a /24 layer 3 (IP) network. */ +static int build_gratuitous_arp(char *buffer, uint16_t buffer_len) { + if(buffer_len < sizeof(gratuitous_arp)) return(-1); + + memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); + memcpy(&buffer[6], device.mac_addr, 6); + memcpy(&buffer[22], device.mac_addr, 6); + memcpy(&buffer[28], &device.ip_addr, 4); + + /* REVISIT: BbMaj7 - use a real netmask here. This is valid only by accident + * for /24 IPv4 networks. */ + buffer[31] = 0xFF; /* Use a faked broadcast address */ + memcpy(&buffer[38], &device.ip_addr, 4); + return(sizeof(gratuitous_arp)); +} + +/* ************************************** */ + +/** Called from update_supernode_reg to periodically send gratuitous ARP + * broadcasts. */ +static void send_grat_arps(n2n_edge_t * eee,) { + char buffer[48]; + size_t len; + + traceEvent(TRACE_NORMAL, "Sending gratuitous ARP..."); + len = build_gratuitous_arp(buffer, sizeof(buffer)); + send_packet2net(eee, buffer, len); + send_packet2net(eee, buffer, len); /* Two is better than one :-) */ +} + +#endif /* #if defined(DUMMY_ID_00001) */ + +/* ************************************** */ + +static void daemonize() { +#ifndef WIN32 + int childpid; + + traceEvent(TRACE_NORMAL, "Parent process is exiting (this is normal)"); + + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + if((childpid = fork()) < 0) + traceEvent(TRACE_ERROR, "Occurred while daemonizing (errno=%d)", + errno); + else { + if(!childpid) { /* child */ + int rc; + + //traceEvent(TRACE_NORMAL, "Bye bye: I'm becoming a daemon..."); + rc = chdir("/"); + if(rc != 0) + traceEvent(TRACE_ERROR, "Error while moving to / directory"); + + setsid(); /* detach from the terminal */ + + fclose(stdin); + fclose(stdout); + /* fclose(stderr); */ + + /* + * clear any inherited file mode creation mask + */ + //umask(0); + + /* + * Use line buffered stdout + */ + /* setlinebuf (stdout); */ + setvbuf(stdout, (char *)NULL, _IOLBF, 0); + } else /* father */ + exit(0); + } +#endif +} + +/* *************************************************** */ + +static int keep_on_running; + +#if defined(__linux__) || defined(WIN32) +#ifdef WIN32 +BOOL WINAPI term_handler(DWORD sig) +#else + static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "Ok I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "Shutting down..."); + called = 1; + } + + keep_on_running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} +#endif /* defined(__linux__) || defined(WIN32) */ + +/* *************************************************** */ + +/** Entry point to program from kernel. */ +int main(int argc, char* argv[]) { + int rc; + tuntap_dev tuntap; /* a tuntap device */ + n2n_edge_t *eee; /* single instance for this program */ + n2n_edge_conf_t conf; /* generic N2N edge config */ + n2n_tuntap_priv_config_t ec; /* config used for standalone program execution */ +#ifndef WIN32 + struct passwd *pw = NULL; +#endif +#ifdef HAVE_LIBCAP + cap_t caps; +#endif + + /* Defaults */ + edge_init_conf_defaults(&conf); + memset(&ec, 0, sizeof(ec)); + ec.mtu = DEFAULT_MTU; + ec.daemon = 1; /* By default run in daemon mode. */ + +#ifndef WIN32 + if(((pw = getpwnam("n2n")) != NULL) || + ((pw = getpwnam("nobody")) != NULL)) { + ec.userid = pw->pw_uid; + ec.groupid = pw->pw_gid; + } +#endif + +#ifdef WIN32 + ec.tuntap_dev_name[0] = '\0'; +#else + snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), "edge0"); +#endif + snprintf(ec.ip_mode, sizeof(ec.ip_mode), "static"); + snprintf(ec.netmask, sizeof(ec.netmask), "255.255.255.0"); + + if((argc >= 2) && (argv[1][0] != '-')) { + rc = loadFromFile(argv[1], &conf, &ec); + if(argc > 2) + rc = loadFromCLI(argc, argv, &conf, &ec); + } else if(argc > 1) + rc = loadFromCLI(argc, argv, &conf, &ec); + else +#ifdef WIN32 + /* Load from current directory */ + rc = loadFromFile("edge.conf", &conf, &ec); +#else + rc = -1; +#endif + + if(conf.transop_id == N2N_TRANSFORM_ID_NULL) { + if(conf.encrypt_key) { + /* make sure that Twofish is default cipher if key only (and no cipher) is specified */ + traceEvent(TRACE_WARNING, "Switching to Twofish as key was provided."); + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + } + } + + if(rc < 0) + help(); + + if(edge_verify_conf(&conf) != 0) + help(); + + traceEvent(TRACE_NORMAL, "Starting n2n edge %s %s", PACKAGE_VERSION, PACKAGE_BUILDDATE); + +#if defined(HAVE_OPENSSL_1_1) + traceEvent(TRACE_NORMAL, "Using %s", OpenSSL_version(0)); +#endif + + traceEvent(TRACE_NORMAL, "Using compression: %s.", compression_str(conf.compression)); + traceEvent(TRACE_NORMAL, "Using %s cipher.", transop_str(conf.transop_id)); + + /* Random seed */ + n2n_srand (n2n_seed()); + + if(0 == strcmp("dhcp", ec.ip_mode)) { + traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled."); + + conf.dyn_ip_mode = 1; + } else + traceEvent(TRACE_NORMAL, "ip_mode='%s'", ec.ip_mode); + + if(!( +#ifdef __linux__ + (ec.tuntap_dev_name[0] != 0) && +#endif + (ec.ip_addr[0] != 0) + )) + help(); + +#ifndef WIN32 + /* If running suid root then we need to setuid before using the force. */ + if(setuid(0) != 0) + traceEvent(TRACE_ERROR, "Unable to become root [%u/%s]", errno, strerror(errno)); + /* setgid(0); */ +#endif + + if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key)) + traceEvent(TRACE_WARNING, "Community and encryption key must differ, otherwise security will be compromised"); + + if(tuntap_open(&tuntap, ec.tuntap_dev_name, ec.ip_mode, ec.ip_addr, ec.netmask, ec.device_mac, ec.mtu) < 0) + exit(1); + + if((eee = edge_init(&tuntap, &conf, &rc)) == NULL) { + traceEvent(TRACE_ERROR, "Failed in edge_init"); + exit(1); + } + memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec)); + +#ifndef WIN32 + if(ec.daemon) { + setUseSyslog(1); /* traceEvent output now goes to syslog. */ + daemonize(); + } +#endif /* #ifndef WIN32 */ + +#ifndef WIN32 + +#ifdef HAVE_LIBCAP + /* Before dropping the privileges, retain capabilities to regain them in future. */ + caps = cap_get_proc(); + + cap_set_flag(caps, CAP_PERMITTED, num_cap, cap_values, CAP_SET); + cap_set_flag(caps, CAP_EFFECTIVE, num_cap, cap_values, CAP_SET); + + if((cap_set_proc(caps) != 0) || (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0)) + traceEvent(TRACE_WARNING, "Unable to retain permitted capabilities [%s]\n", strerror(errno)); +#else +#ifndef __APPLE__ + traceEvent(TRACE_WARNING, "n2n has not been compiled with libcap-dev. Some commands may fail."); +#endif +#endif /* HAVE_LIBCAP */ + + if((ec.userid != 0) || (ec.groupid != 0)) { + traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d", + (signed int)ec.userid, (signed int)ec.groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + if((setgid(ec.groupid) != 0) + || (setuid(ec.userid) != 0)) { + traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno)); + exit(1); + } + } + + if((getuid() == 0) || (getgid() == 0)) + traceEvent(TRACE_WARNING, "Running as root is discouraged, check out the -u/-g options"); +#endif + +#ifdef __linux__ + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); +#endif +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#endif + + keep_on_running = 1; + traceEvent(TRACE_NORMAL, "edge started"); + rc = run_edge_loop(eee, &keep_on_running); + print_edge_stats(eee); + +#ifdef HAVE_LIBCAP + /* Before completing the cleanup, regain the capabilities as some + * cleanup tasks require them (e.g. routes cleanup). */ + cap_set_flag(caps, CAP_EFFECTIVE, num_cap, cap_values, CAP_SET); + + if(cap_set_proc(caps) != 0) + traceEvent(TRACE_WARNING, "Could not regain the capabilities [%s]\n", strerror(errno)); + + cap_free(caps); +#endif + + /* Cleanup */ + edge_term(eee); + edge_term_conf(&conf); + tuntap_close(&tuntap); + + if(conf.encrypt_key) free(conf.encrypt_key); + + return(rc); +} + +/* ************************************** */ diff --git a/bundles/n2n_ntop_v2/src/edge_utils.c b/bundles/n2n_ntop_v2/src/edge_utils.c new file mode 100644 index 00000000..9dd59356 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/edge_utils.c @@ -0,0 +1,2626 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "edge_utils_win32.h" + +/* heap allocation for compression as per lzo example doc */ +#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] +static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); + +/* ************************************** */ + +static const char * supernode_ip(const n2n_edge_t * eee); +static void send_register(n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac); +static void check_peer_registration_needed(n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer); +static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos); +static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); +static void edge_cleanup_routes(n2n_edge_t *eee); +static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn); +static void check_known_peer_sock_change(n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t when); + +/* ************************************** */ + +int edge_verify_conf(const n2n_edge_conf_t *conf) { + if(conf->community_name[0] == 0) + return(-1); + + if(conf->sn_num == 0) + return(-2); + + if(conf->register_interval < 1) + return(-3); + + if(((conf->encrypt_key == NULL) && (conf->transop_id != N2N_TRANSFORM_ID_NULL)) || + ((conf->encrypt_key != NULL) && (conf->transop_id == N2N_TRANSFORM_ID_NULL))) + return(-4); + + return(0); +} + + +/* ************************************** */ + +void edge_set_callbacks(n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks) { + memcpy(&eee->cb, callbacks, sizeof(n2n_edge_callbacks_t)); +} + +/* ************************************** */ + +void edge_set_userdata(n2n_edge_t *eee, void *user_data) { + eee->user_data = user_data; +} + +/* ************************************** */ + +void* edge_get_userdata(n2n_edge_t *eee) { + return(eee->user_data); +} + +/* ************************************** */ + +int edge_get_n2n_socket(n2n_edge_t *eee) { + return(eee->udp_sock); +} + +/* ************************************** */ + +int edge_get_management_socket(n2n_edge_t *eee) { + return(eee->udp_mgmt_sock); +} + +/* ************************************** */ + +const char* transop_str(enum n2n_transform tr) { + switch(tr) { + case N2N_TRANSFORM_ID_NULL: return("null"); + case N2N_TRANSFORM_ID_TWOFISH: return("twofish"); + case N2N_TRANSFORM_ID_AESCBC: return("AES-CBC"); + case N2N_TRANSFORM_ID_CHACHA20:return("ChaCha20"); + case N2N_TRANSFORM_ID_SPECK :return("Speck"); + default: return("invalid"); + }; +} + +/* ************************************** */ + +const char* compression_str(uint8_t cmpr) { + switch(cmpr) { + case N2N_COMPRESSION_ID_NONE: return("none"); + case N2N_COMPRESSION_ID_LZO: return("lzo1x"); + +#ifdef HAVE_LIBZSTD + case N2N_COMPRESSION_ID_ZSTD: return("zstd"); +#endif + default: return("invalid"); + }; +} + +/* ************************************** */ + +/** Destination 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF is multicast ethernet. + */ +static int is_ethMulticast(const void * buf, size_t bufsize) { + int retval = 0; + + /* Match 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF */ + if(bufsize >= sizeof(ether_hdr_t)) { + /* copy to aligned memory */ + ether_hdr_t eh; + memcpy(&eh, buf, sizeof(ether_hdr_t)); + + if((0x01 == eh.dhost[0]) && + (0x00 == eh.dhost[1]) && + (0x5E == eh.dhost[2]) && + (0 == (0x80 & eh.dhost[3]))) + retval = 1; /* This is an ethernet multicast packet [RFC1112]. */ + } + + return retval; +} + +/* ************************************** */ + +/** Destination MAC 33:33:0:00:00:00 - 33:33:FF:FF:FF:FF is reserved for IPv6 + * neighbour discovery. + */ +static int is_ip6_discovery(const void * buf, size_t bufsize) { + int retval = 0; + + if(bufsize >= sizeof(ether_hdr_t)) { + /* copy to aligned memory */ + ether_hdr_t eh; + + memcpy(&eh, buf, sizeof(ether_hdr_t)); + + if((0x33 == eh.dhost[0]) && (0x33 == eh.dhost[1])) + retval = 1; /* This is an IPv6 multicast packet [RFC2464]. */ + } + return retval; +} + +/* ************************************** */ + +/** Initialise an edge to defaults. + * + * This also initialises the NULL transform operation opstruct. + */ +n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv) { + n2n_transform_t transop_id = conf->transop_id; + n2n_edge_t *eee = calloc(1, sizeof(n2n_edge_t)); + int rc = -1, i; + + if((rc = edge_verify_conf(conf)) != 0) { + traceEvent(TRACE_ERROR, "Invalid configuration"); + goto edge_init_error; + } + + if(!eee) { + traceEvent(TRACE_ERROR, "Cannot allocate memory"); + goto edge_init_error; + } + +#ifdef WIN32 + initWin32(); +#endif + + memcpy(&eee->conf, conf, sizeof(*conf)); + memcpy(&eee->device, dev, sizeof(*dev)); + eee->start_time = time(NULL); + + eee->known_peers = NULL; + eee->pending_peers = NULL; + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; + eee->sn_last_valid_time_stamp = initial_time_stamp (); + + pearson_hash_init(); + + if(eee->conf.compression == N2N_COMPRESSION_ID_LZO) + if(lzo_init() != LZO_E_OK) { + traceEvent(TRACE_ERROR, "LZO compression error"); + goto edge_init_error; + } + +#ifdef N2N_HAVE_ZSTD + // zstd does not require initialization. if it were required, this would be a good place +#endif + + for(i=0; isn_num; ++i) + traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (conf->sn_ip_array[i])); + + /* Set the active supernode */ + supernode2addr(&(eee->supernode), conf->sn_ip_array[eee->sn_idx]); + + /* Set active transop */ + switch(transop_id) { + case N2N_TRANSFORM_ID_TWOFISH: + rc = n2n_transop_twofish_init(&eee->conf, &eee->transop); + break; +#ifdef N2N_HAVE_AES + case N2N_TRANSFORM_ID_AESCBC: + rc = n2n_transop_aes_cbc_init(&eee->conf, &eee->transop); + break; +#endif +#ifdef HAVE_OPENSSL_1_1 + case N2N_TRANSFORM_ID_CHACHA20: + rc = n2n_transop_cc20_init(&eee->conf, &eee->transop); + break; +#endif + case N2N_TRANSFORM_ID_SPECK: + rc = n2n_transop_speck_init(&eee->conf, &eee->transop); + break; + default: + rc = n2n_transop_null_init(&eee->conf, &eee->transop); + } + + if((rc < 0) || (eee->transop.fwd == NULL) || (eee->transop.transform_id != transop_id)) { + traceEvent(TRACE_ERROR, "Transop init failed"); + goto edge_init_error; + } + + /* Set the key schedule (context) for header encryption if enabled */ + if(conf->header_encryption == HEADER_ENCRYPTION_ENABLED) { + traceEvent(TRACE_NORMAL, "Header encryption is enabled."); + packet_header_setup_key ((char *)(conf->community_name), &(eee->conf.header_encryption_ctx),&(eee->conf.header_iv_ctx)); + } + + if(eee->transop.no_encryption) + traceEvent(TRACE_WARNING, "Encryption is disabled in edge"); + + if(edge_init_sockets(eee, conf->local_port, conf->mgmt_port, conf->tos) < 0) { + traceEvent(TRACE_ERROR, "socket setup failed"); + goto edge_init_error; + } + + if(edge_init_routes(eee, conf->routes, conf->num_routes) < 0) { + traceEvent(TRACE_ERROR, "routes setup failed"); + goto edge_init_error; + } + + //edge_init_success: + *rv = 0; + return(eee); + + edge_init_error: + if(eee) + free(eee); + *rv = rc; + return(NULL); +} + +/* ************************************** */ + +static int find_and_remove_peer(struct peer_info **head, const n2n_mac_t mac) { + struct peer_info *peer; + + HASH_FIND_PEER(*head, mac, peer); + if(peer) { + HASH_DEL(*head, peer); + free(peer); + return(1); + } + + return(0); +} + +/* ************************************** */ + +static uint32_t localhost_v4 = 0x7f000001; +static uint8_t localhost_v6[IPV6_SIZE] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + +/* Exclude localhost as it may be received when an edge node runs + * in the same supernode host. + */ +static int is_valid_peer_sock(const n2n_sock_t *sock) { + switch(sock->family) { + case AF_INET: + { + uint32_t *a = (uint32_t*)sock->addr.v4; + + if(*a != htonl(localhost_v4)) + return(1); + } + break; + + case AF_INET6: + if(memcmp(sock->addr.v6, localhost_v6, IPV6_SIZE)) + return(1); + break; + } + + return(0); +} + +/* ***************************************************** */ + +/** Resolve the supernode IP address. + * + * REVISIT: This is a really bad idea. The edge will block completely while the + * hostname resolution is performed. This could take 15 seconds. + */ +static int supernode2addr(n2n_sock_t * sn, const n2n_sn_name_t addrIn) { + n2n_sn_name_t addr; + const char *supernode_host; + int rv = 0; + + memcpy(addr, addrIn, N2N_EDGE_SN_HOST_SIZE); + + supernode_host = strtok(addr, ":"); + + if(supernode_host) { + in_addr_t sn_addr; + char *supernode_port = strtok(NULL, ":"); + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + int nameerr; + + if(supernode_port) + sn->port = atoi(supernode_port); + else + traceEvent(TRACE_WARNING, "Bad supernode parameter (-l ) %s %s:%s", + addr, supernode_host, supernode_port); + + nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); + + if(0 == nameerr) + { + struct sockaddr_in * saddr; + + /* ainfo s the head of a linked list if non-NULL. */ + if(ainfo && (PF_INET == ainfo->ai_family)) + { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + + memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); + sn->family=AF_INET; + } + else + { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "Failed to resolve supernode IPv4 address for %s", supernode_host); + rv = -1; + } + + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + ainfo = NULL; + } else { + traceEvent(TRACE_WARNING, "Failed to resolve supernode host %s", supernode_host); + rv = -2; + } + + } else { + traceEvent(TRACE_WARNING, "Wrong supernode parameter (-l )"); + rv = -3; + } + + return(rv); +} + +/* ************************************** */ + +static const int definitely_from_supernode = 1; + +/*** + * + * For a given packet, find the apporopriate internal last valid time stamp for lookup + * and verify it (and also update, if applicable). + */ +static int find_peer_time_stamp_and_verify (n2n_edge_t * eee, + int from_supernode, n2n_mac_t mac, + uint64_t stamp) { + + uint64_t * previous_stamp = NULL; + + if(from_supernode) { + // from supernode + previous_stamp = &(eee->sn_last_valid_time_stamp); + } else { + // from (peer) edge + struct peer_info *peer; + HASH_FIND_PEER(eee->pending_peers, mac, peer); + if(!peer) { + HASH_FIND_PEER(eee->known_peers, mac, peer); + } + if(peer) { + // time_stamp_verify_and_update allows the pointer a previous stamp to be NULL + // if it is a (so far) unknown peer + previous_stamp = &(peer->last_valid_time_stamp); + } + } + + // failure --> 0; success --> 1 + return ( time_stamp_verify_and_update (stamp, previous_stamp) ); +} + +/* ************************************** */ + +/*** + * + * Register over multicast in case there is a peer on the same network listening + */ +static void register_with_local_peers(n2n_edge_t * eee) { +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(eee->multicast_joined && eee->conf.allow_p2p) { + /* send registration to the local multicast group */ + traceEvent(TRACE_DEBUG, "Registering with multicast group %s:%u", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + send_register(eee, &(eee->multicast_peer), NULL); + } +#else + traceEvent(TRACE_DEBUG, "Multicast peers discovery is disabled, skipping"); +#endif +} + +/* ************************************** */ + +/** Start the registration process. + * + * If the peer is already in pending_peers, ignore the request. + * If not in pending_peers, add it and send a REGISTER. + * + * If hdr is for a direct peer-to-peer packet, try to register back to sender + * even if the MAC is in pending_peers. This is because an incident direct + * packet indicates that peer-to-peer exchange should work so more aggressive + * registration can be permitted (once per incoming packet) as this should only + * last for a small number of packets.. + * + * Called from the main loop when Rx a packet for our device mac. + */ +static void register_with_new_peer(n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer) { + /* REVISIT: purge of pending_peers not yet done. */ + struct peer_info * scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + + /* NOTE: pending_peers are purged periodically with purge_expired_registrations */ + if(scan == NULL) { + scan = calloc(1, sizeof(struct peer_info)); + + memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); + scan->sock = *peer; + scan->timeout = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */ + scan->last_seen = time(NULL); /* Don't change this it marks the pending peer for removal. */ + scan->last_valid_time_stamp = initial_time_stamp (); + + HASH_ADD_PEER(eee->pending_peers, scan); + + traceEvent(TRACE_DEBUG, "=== new pending %s -> %s", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf, &(scan->sock))); + + traceEvent(TRACE_DEBUG, "Pending peers list size=%u", + HASH_COUNT(eee->pending_peers)); + + /* trace Sending REGISTER */ + if(from_supernode) { + /* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole) + * and then ask supernode to forward. Supernode then ask peer to ack. Some nat device + * drop and block ports with incoming UDP packet if out-come traffic does not exist. + * So we can alternatively set TTL so that the packet sent to peer never really reaches + * The register_ttl is basically nat level + 1. Set it to 1 means host like DMZ. + */ + if(eee->conf.register_ttl == 1) { + /* We are DMZ host or port is directly accessible. Just let peer to send back the ack */ +#ifndef WIN32 + } else if(eee->conf.register_ttl > 1) { + /* Setting register_ttl usually implies that the edge knows the internal net topology + * clearly, we can apply aggressive port prediction to support incoming Symmetric NAT + */ + int curTTL = 0; + socklen_t lenTTL = sizeof(int); + n2n_sock_t sock = scan->sock; + int alter = 16; /* TODO: set by command line or more reliable prediction method */ + + getsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, &lenTTL); + setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, + (void *)(char *)&eee->conf.register_ttl, + sizeof(eee->conf.register_ttl)); + for (; alter > 0; alter--, sock.port++) + { + send_register(eee, &sock, mac); + } + setsockopt(eee->udp_sock, IPPROTO_IP, IP_TTL, (void *)(char *)&curTTL, sizeof(curTTL)); +#endif + } else { /* eee->conf.register_ttl <= 0 */ + /* Normal STUN */ + send_register(eee, &(scan->sock), mac); + } + send_register(eee, &(eee->supernode), mac); + } else { + /* P2P register, send directly */ + send_register(eee, &(scan->sock), mac); + } + + register_with_local_peers(eee); + } else + scan->sock = *peer; +} + +/* ************************************** */ + +/** Update the last_seen time for this peer, or get registered. */ +static void check_peer_registration_needed(n2n_edge_t * eee, + uint8_t from_supernode, + const n2n_mac_t mac, + const n2n_sock_t * peer) { + struct peer_info *scan; + + HASH_FIND_PEER(eee->known_peers, mac, scan); + + if(scan == NULL) { + /* Not in known_peers - start the REGISTER process. */ + register_with_new_peer(eee, from_supernode, mac, peer); + } else { + /* Already in known_peers. */ + time_t now = time(NULL); + + if(!from_supernode) + scan->last_p2p = now; + + if((now - scan->last_seen) > 0 /* >= 1 sec */) { + /* Don't register too often */ + check_known_peer_sock_change(eee, from_supernode, mac, peer, now); + } + } +} +/* ************************************** */ + + +/* Confirm that a pending peer is reachable directly via P2P. + * + * peer must be a pointer to an element of the pending_peers list. + */ +static void peer_set_p2p_confirmed(n2n_edge_t * eee, + const n2n_mac_t mac, + const n2n_sock_t * peer, + time_t now) { + struct peer_info *scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + + if(scan) { + HASH_DEL(eee->pending_peers, scan); + + /* Add scan to known_peers. */ + HASH_ADD_PEER(eee->known_peers, scan); + + scan->sock = *peer; + scan->last_p2p = now; + + traceEvent(TRACE_DEBUG, "P2P connection established: %s [%s]", + macaddr_str(mac_buf, mac), + sock_to_cstr(sockbuf, peer)); + + traceEvent(TRACE_DEBUG, "=== new peer %s -> %s", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf, &(scan->sock))); + + traceEvent(TRACE_DEBUG, "Pending peers list size=%u", + HASH_COUNT(eee->pending_peers)); + + traceEvent(TRACE_DEBUG, "Known peers list size=%u", + HASH_COUNT(eee->known_peers)); + + scan->last_seen = now; + } else + traceEvent(TRACE_DEBUG, "Failed to find sender in pending_peers."); +} + +/* ************************************** */ + +int is_empty_ip_address(const n2n_sock_t * sock) { + const uint8_t * ptr=NULL; + size_t len=0; + size_t i; + + if(AF_INET6 == sock->family) + { + ptr = sock->addr.v6; + len = 16; + } + else + { + ptr = sock->addr.v4; + len = 4; + } + + for (i=0; iknown_peers, mac, scan); + + if(!scan) + /* Not in known_peers */ + return; + + if(!sock_equal(&(scan->sock), peer)) { + if(!from_supernode) { + /* This is a P2P packet */ + traceEvent(TRACE_NORMAL, "Peer changed %s: %s -> %s", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf1, &(scan->sock)), + sock_to_cstr(sockbuf2, peer)); + /* The peer has changed public socket. It can no longer be assumed to be reachable. */ + HASH_DEL(eee->known_peers, scan); + free(scan); + + register_with_new_peer(eee, from_supernode, mac, peer); + } else { + /* Don't worry about what the supernode reports, it could be seeing a different socket. */ + } + } else + scan->last_seen = when; +} + +/* ************************************** */ + +/** Send a datagram to a socket defined by a n2n_sock_t */ +static ssize_t sendto_sock(int fd, const void * buf, + size_t len, const n2n_sock_t * dest) { + struct sockaddr_in peer_addr; + ssize_t sent; + + if(!dest->family) + // Invalid socket + return 0; + + fill_sockaddr((struct sockaddr *) &peer_addr, + sizeof(peer_addr), + dest); + + sent = sendto(fd, buf, len, 0/*flags*/, + (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in)); + if(sent < 0) + { + char * c = strerror(errno); + traceEvent(TRACE_ERROR, "sendto failed (%d) %s", errno, c); + } + else + { + traceEvent(TRACE_DEBUG, "sendto sent=%d to ", (signed int)sent); + } + + return sent; +} + +/* ************************************** */ + +/* Bind eee->udp_multicast_sock to multicast group */ +static void check_join_multicast_group(n2n_edge_t *eee) { +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(!eee->multicast_joined) { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = inet_addr(N2N_MULTICAST_GROUP); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + + if(setsockopt(eee->udp_multicast_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { + traceEvent(TRACE_WARNING, "Failed to bind to local multicast group %s:%u [errno %u]", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT, errno); + +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + } else { + traceEvent(TRACE_NORMAL, "Successfully joined multicast group %s:%u", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + eee->multicast_joined = 1; + } + } +#endif +} + +/* ************************************** */ + +/** Send a REGISTER_SUPER packet to the current supernode. */ +static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, int sn_idx) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0}; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_SUPER_t reg; + n2n_sock_str_t sockbuf; + + memset(&cmn, 0, sizeof(cmn)); + memset(®, 0, sizeof(reg)); + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register_super; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx) + eee->last_cookie[idx] = n2n_rand() % 0xff; + + memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE); + reg.auth.scheme=0; /* No auth yet */ + + idx=0; + encode_mac(reg.edgeMac, &idx, eee->device.mac_addr); + + idx=0; + encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®); + + traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s", + sock_to_cstr(sockbuf, supernode)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + time_stamp (), pearson_hash_16 (pktbuf, idx)); + + /* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode); +} + +/* ************************************** */ + +/** Send a QUERY_PEER packet to the current supernode. */ +static void send_query_peer( n2n_edge_t * eee, + const n2n_mac_t dstMac) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_QUERY_PEER_t query = {{0}}; + + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_query_peer; + cmn.flags = 0; + memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE ); + + idx=0; + encode_mac( query.srcMac, &idx, eee->device.mac_addr ); + idx=0; + encode_mac( query.targetMac, &idx, dstMac ); + + idx=0; + encode_QUERY_PEER( pktbuf, &idx, &cmn, &query ); + + traceEvent( TRACE_DEBUG, "send QUERY_PEER to supernode" ); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){ + packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + time_stamp (), pearson_hash_16 (pktbuf, idx)); + } + sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) ); +} + +/** Send a REGISTER packet to another edge. */ +static void send_register(n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_mac_t peer_mac) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_t reg; + n2n_sock_str_t sockbuf; + + if(!eee->conf.allow_p2p) { + traceEvent(TRACE_DEBUG, "Skipping register as P2P is disabled"); + return; + } + + memset(&cmn, 0, sizeof(cmn)); + memset(®, 0, sizeof(reg)); + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + idx=0; + encode_uint32(reg.cookie, &idx, 123456789); + idx=0; + encode_mac(reg.srcMac, &idx, eee->device.mac_addr); + + if(peer_mac) { + /* Can be NULL for multicast registrations */ + idx=0; + encode_mac(reg.dstMac, &idx, peer_mac); + } + + idx=0; + encode_REGISTER(pktbuf, &idx, &cmn, ®); + + traceEvent(TRACE_INFO, "Send REGISTER to %s", + sock_to_cstr(sockbuf, remote_peer)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + time_stamp (), pearson_hash_16 (pktbuf, idx)); + + /* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer); +} + +/* ************************************** */ + +/** Send a REGISTER_ACK packet to a peer edge. */ +static void send_register_ack(n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_REGISTER_t * reg) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_ACK_t ack; + n2n_sock_str_t sockbuf; + + if(!eee->conf.allow_p2p) { + traceEvent(TRACE_DEBUG, "Skipping register ACK as P2P is disabled"); + return; + } + + memset(&cmn, 0, sizeof(cmn)); + memset(&ack, 0, sizeof(reg)); + cmn.ttl=N2N_DEFAULT_TTL; + cmn.pc = n2n_register_ack; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + memset(&ack, 0, sizeof(ack)); + memcpy(ack.cookie, reg->cookie, N2N_COOKIE_SIZE); + memcpy(ack.srcMac, eee->device.mac_addr, N2N_MAC_SIZE); + memcpy(ack.dstMac, reg->srcMac, N2N_MAC_SIZE); + + idx=0; + encode_REGISTER_ACK(pktbuf, &idx, &cmn, &ack); + + traceEvent(TRACE_INFO, "send REGISTER_ACK %s", + sock_to_cstr(sockbuf, remote_peer)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + time_stamp (), pearson_hash_16 (pktbuf, idx)); + + /* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, remote_peer); +} + +/* ************************************** */ + +/** @brief Check to see if we should re-register with the supernode. + * + * This is frequently called by the main loop. + */ +static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) { + u_int sn_idx; + + if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->conf.register_interval/10)))) { + /* fall through */ + traceEvent(TRACE_DEBUG, "update_supernode_reg: doing fast retry."); + } else if(nowTime < (eee->last_register_req + eee->conf.register_interval)) + return; /* Too early */ + + check_join_multicast_group(eee); + + if(0 == eee->sup_attempts) { + /* Give up on that supernode and try the next one. */ + ++(eee->sn_idx); + + if(eee->sn_idx >= eee->conf.sn_num) { + /* Got to end of list, go back to the start. Also works for list of one entry. */ + eee->sn_idx=0; + } + + traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee)); + + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; + } + else + --(eee->sup_attempts); + + for(sn_idx=0; sn_idxconf.sn_num; sn_idx++) { + if(supernode2addr(&(eee->supernode), eee->conf.sn_ip_array[sn_idx]) == 0) { + traceEvent(TRACE_INFO, "Registering with supernode [id: %u/%u][%s][attempts left %u]", + sn_idx+1, eee->conf.sn_num, + supernode_ip(eee), (unsigned int)eee->sup_attempts); + + send_register_super(eee, &(eee->supernode), sn_idx); + } + } + + register_with_local_peers(eee); + + eee->sn_wait=1; + + /* REVISIT: turn-on gratuitous ARP with config option. */ + /* send_grat_arps(sock_fd, is_udp_sock); */ + + eee->last_register_req = nowTime; +} + +/* ************************************** */ + +/** NOT IMPLEMENTED + * + * This would send a DEREGISTER packet to a peer edge or supernode to indicate + * the edge is going away. + */ +static void send_deregister(n2n_edge_t * eee, + n2n_sock_t * remote_peer) { + /* Marshall and send message */ +} + +/* ************************************** */ + +/** Return the IP address of the current supernode in the ring. */ +static const char * supernode_ip(const n2n_edge_t * eee) { + return (eee->conf.sn_ip_array)[eee->sn_idx]; +} + +/* ************************************** */ + +/** A PACKET has arrived containing an encapsulated ethernet datagram - usually + * encrypted. */ +static int handle_PACKET(n2n_edge_t * eee, + const n2n_common_t * cmn, + const n2n_PACKET_t * pkt, + const n2n_sock_t * orig_sender, + uint8_t * payload, + size_t psize) { + ssize_t data_sent_len; + uint8_t from_supernode; + uint8_t * eth_payload=NULL; + int retval = -1; + time_t now; + ether_hdr_t * eh; + ipstr_t ip_buf; + + now = time(NULL); + + traceEvent(TRACE_DEBUG, "handle_PACKET size %u transform %u", + (unsigned int)psize, (unsigned int)pkt->transform); + /* hexdump(payload, psize); */ + + from_supernode= cmn->flags & N2N_FLAGS_FROM_SUPERNODE; + + if(from_supernode) + { + if(!memcmp(pkt->dstMac, broadcast_mac, N2N_MAC_SIZE)) + ++(eee->stats.rx_sup_broadcast); + + ++(eee->stats.rx_sup); + eee->last_sup=now; + } + else + { + ++(eee->stats.rx_p2p); + eee->last_p2p=now; + } + + /* Update the sender in peer table entry */ + check_peer_registration_needed(eee, from_supernode, pkt->srcMac, orig_sender); + + /* Handle transform. */ + { + uint8_t decodebuf[N2N_PKT_BUF_SIZE]; + size_t eth_size; + n2n_transform_t rx_transop_id; + + rx_transop_id = (n2n_transform_t)pkt->transform; + /* optional compression is encoded in uppermost bit of transform field. + * this is an intermediate solution to maintain compatibility until some + * upcoming major release (3.0?) brings up changes in packet structure anyway + * in the course of which a dedicated compression field could be spent. + * REVISIT then. */ + uint16_t rx_compression_id; + + rx_compression_id = (uint16_t)rx_transop_id >> (8*sizeof((uint16_t)rx_transop_id)-N2N_COMPRESSION_ID_BITLEN); + rx_transop_id &= (1 << (8*sizeof((uint16_t)rx_transop_id)-N2N_COMPRESSION_ID_BITLEN)) -1; + + if(rx_transop_id == eee->conf.transop_id) { + uint8_t is_multicast; + eth_payload = decodebuf; + eh = (ether_hdr_t*)eth_payload; + eth_size = eee->transop.rev(&eee->transop, + eth_payload, N2N_PKT_BUF_SIZE, + payload, psize, pkt->srcMac); + ++(eee->transop.rx_cnt); /* stats */ + + /* decompress if necessary */ + uint8_t * deflation_buffer = 0; + int32_t deflated_len; + switch (rx_compression_id) { + case N2N_COMPRESSION_ID_NONE: + break; // continue afterwards + + case N2N_COMPRESSION_ID_LZO: + deflation_buffer = malloc (N2N_PKT_BUF_SIZE); + lzo1x_decompress (eth_payload, eth_size, deflation_buffer, (lzo_uint*)&deflated_len, NULL); + break; +#ifdef N2N_HAVE_ZSTD + case N2N_COMPRESSION_ID_ZSTD: + deflated_len = N2N_PKT_BUF_SIZE; + deflation_buffer = malloc (deflated_len); + deflated_len = (int32_t)ZSTD_decompress (deflation_buffer, deflated_len, eth_payload, eth_size); + if(ZSTD_isError(deflated_len)) { + traceEvent (TRACE_ERROR, "payload decompression failed with zstd error '%s'.", + ZSTD_getErrorName(deflated_len)); + free (deflation_buffer); + return (-1); // cannot help it + } + break; +#endif + default: + traceEvent (TRACE_ERROR, "payload decompression failed: received packet indicating unsupported %s compression.", + compression_str(rx_compression_id)); + return (-1); // cannot handle it + } + + if(rx_compression_id) { + traceEvent (TRACE_DEBUG, "payload decompression [%s]: deflated %u bytes to %u bytes", + compression_str(rx_compression_id), eth_size, (int)deflated_len); + memcpy(eth_payload ,deflation_buffer, deflated_len ); + eth_size = deflated_len; + free (deflation_buffer); + } + + is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size)); + + if(eee->conf.drop_multicast && is_multicast) { + traceEvent(TRACE_INFO, "Dropping RX multicast"); + return(-1); + } else if((!eee->conf.allow_routing) && (!is_multicast)) { + /* Check if it is a routed packet */ + if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) { + uint32_t *dst = (uint32_t*)ð_payload[ETH_FRAMESIZE + IP4_DSTOFFSET]; + uint8_t *dst_mac = (uint8_t*)eth_payload; + + /* Note: all elements of the_ip are in network order */ + if(!memcmp(dst_mac, broadcast_mac, N2N_MAC_SIZE)) + traceEvent(TRACE_DEBUG, "Broadcast packet [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + else if((*dst != eee->device.ip_addr)) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + return(-1); + } else { + /* This packet is directed to us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + if(eee->cb.packet_from_peer) { + uint16_t tmp_eth_size = eth_size; + if(eee->cb.packet_from_peer(eee, orig_sender, eth_payload, &tmp_eth_size) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "DROP packet %u", (unsigned int)eth_size); + + return(0); + } + eth_size = tmp_eth_size; + } + + /* Write ethernet packet to tap device. */ + traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size); + data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size); + + if(data_sent_len == eth_size) + { + retval = 0; + } + } + else + { + traceEvent(TRACE_ERROR, "invalid transop ID: expected %s(%u), got %s(%u)", + transop_str(eee->conf.transop_id), eee->conf.transop_id, + transop_str(rx_transop_id), rx_transop_id); + } + } + + return retval; +} + +/* ************************************** */ + +/** Read a datagram from the management UDP socket and take appropriate + * action. */ +static void readFromMgmtSocket(n2n_edge_t * eee, int * keep_running) { + uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */ + ssize_t recvlen; + /* ssize_t sendlen; */ + struct sockaddr_in sender_sock; + socklen_t i; + size_t msg_len; + time_t now; + + now = time(NULL); + i = sizeof(sender_sock); + recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if(recvlen < 0) + { + traceEvent(TRACE_ERROR, "mgmt recvfrom failed with %s", strerror(errno)); + + return; /* failed to receive data from UDP */ + } + + if(recvlen >= 4) + { + if(0 == memcmp(udp_buf, "stop", 4)) + { + traceEvent(TRACE_ERROR, "stop command received."); + *keep_running = 0; + return; + } + + if(0 == memcmp(udp_buf, "help", 4)) + { + msg_len=0; + setTraceLevel(getTraceLevel()+1); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "Help for edge management console:\n" + " stop Gracefully exit edge\n" + " help This help message\n" + " +verb Increase verbosity of logging\n" + " -verb Decrease verbosity of logging\n" + " Display statistics\n\n"); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); + + return; + } + + } + + if(recvlen >= 5) + { + if(0 == memcmp(udp_buf, "+verb", 5)) + { + msg_len=0; + setTraceLevel(getTraceLevel()+1); + + traceEvent(TRACE_ERROR, "+verb traceLevel=%u", (unsigned int)getTraceLevel()); + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> +OK traceLevel=%u\n", (unsigned int)getTraceLevel()); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); + + return; + } + + if(0 == memcmp(udp_buf, "-verb", 5)) + { + msg_len=0; + + if(getTraceLevel() > 0) + { + setTraceLevel(getTraceLevel()-1); + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> -OK traceLevel=%u\n", getTraceLevel()); + } + else + { + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> -NOK traceLevel=%u\n", getTraceLevel()); + } + + traceEvent(TRACE_ERROR, "-verb traceLevel=%u", (unsigned int)getTraceLevel()); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); + return; + } + } + + traceEvent(TRACE_DEBUG, "mgmt status rq"); + + msg_len=0; + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "Statistics for edge\n"); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "uptime %lu\n", + time(NULL) - eee->start_time); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "paths super:%u,%u p2p:%u,%u\n", + (unsigned int)eee->stats.tx_sup, + (unsigned int)eee->stats.rx_sup, + (unsigned int)eee->stats.tx_p2p, + (unsigned int)eee->stats.rx_p2p); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "transop |%6u|%6u|\n", + (unsigned int)eee->transop.tx_cnt, + (unsigned int)eee->transop.rx_cnt); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "peers pend:%u full:%u\n", + HASH_COUNT(eee->pending_peers), + HASH_COUNT(eee->known_peers)); + + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "last super:%lu(%ld sec ago) p2p:%lu(%ld sec ago)\n", + eee->last_sup, (now-eee->last_sup), eee->last_p2p, + (now-eee->last_p2p)); + + traceEvent(TRACE_DEBUG, "mgmt status sending: %s", udp_buf); + + + /* sendlen = */ sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); +} + +/* ************************************** */ + +static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) { + struct peer_info *scan; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + + if(!scan) { + scan = calloc(1, sizeof(struct peer_info)); + + memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); + scan->timeout = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */ + scan->last_seen = now; /* Don't change this it marks the pending peer for removal. */ + scan->last_valid_time_stamp = initial_time_stamp (); + + HASH_ADD_PEER(eee->pending_peers, scan); + } + + if(now - scan->last_sent_query > REGISTER_SUPER_INTERVAL_DFL) { + send_query_peer(eee, scan->mac_addr); + scan->last_sent_query = now; + return(0); + } + + return(1); +} + +/* ************************************** */ + +/* @return 1 if destination is a peer, 0 if destination is supernode */ +static int find_peer_destination(n2n_edge_t * eee, + n2n_mac_t mac_address, + n2n_sock_t * destination) { + struct peer_info *scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + int retval=0; + time_t now = time(NULL); + + if(!memcmp(mac_address, broadcast_mac, N2N_MAC_SIZE)) { + traceEvent(TRACE_DEBUG, "Broadcast destination peer, using supernode"); + memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); + return(0); + } + + traceEvent(TRACE_DEBUG, "Searching destination peer for MAC %02X:%02X:%02X:%02X:%02X:%02X", + mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, + mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); + + HASH_FIND_PEER(eee->known_peers, mac_address, scan); + + if(scan && (scan->last_seen > 0)) { + if((now - scan->last_p2p) >= (scan->timeout / 2)) { + /* Too much time passed since we saw the peer, need to register again + * since the peer address may have changed. */ + traceEvent(TRACE_DEBUG, "Refreshing idle known peer"); + HASH_DEL(eee->known_peers, scan); + free(scan); + /* NOTE: registration will be performed upon the receival of the next response packet */ + } else { + /* Valid known peer found */ + memcpy(destination, &scan->sock, sizeof(n2n_sock_t)); + retval=1; + } + } + + if(retval == 0) { + memcpy(destination, &(eee->supernode), sizeof(struct sockaddr_in)); + traceEvent(TRACE_DEBUG, "P2P Peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X] not found, using supernode", + mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, + mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); + + check_query_peer_info(eee, now, mac_address); + } + + traceEvent(TRACE_DEBUG, "find_peer_address (%s) -> [%s]", + macaddr_str(mac_buf, mac_address), + sock_to_cstr(sockbuf, destination)); + + return retval; +} + +/* ***************************************************** */ + +/** Send an ecapsulated ethernet PACKET to a destination edge or broadcast MAC + * address. */ +static int send_packet(n2n_edge_t * eee, + n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktlen) { + int is_p2p; + /*ssize_t s; */ + n2n_sock_str_t sockbuf; + n2n_sock_t destination; + macstr_t mac_buf; + + /* hexdump(pktbuf, pktlen); */ + + is_p2p = find_peer_destination(eee, dstMac, &destination); + + if(is_p2p) + ++(eee->stats.tx_p2p); + else { + ++(eee->stats.tx_sup); + + if(!memcmp(dstMac, broadcast_mac, N2N_MAC_SIZE)) + ++(eee->stats.tx_sup_broadcast); + } + + traceEvent(TRACE_INFO, "Tx PACKET to %s (dest=%s) [%u B]", + sock_to_cstr(sockbuf, &destination), + macaddr_str(mac_buf, dstMac), pktlen); + + /* s = */ sendto_sock(eee->udp_sock, pktbuf, pktlen, &destination); + + return 0; +} + +/* ************************************** */ + +/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ +void edge_send_packet2net(n2n_edge_t * eee, + uint8_t *tap_pkt, size_t len) { + ipstr_t ip_buf; + n2n_mac_t destMac; + + n2n_common_t cmn; + n2n_PACKET_t pkt; + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx=0; + n2n_transform_t tx_transop_idx = eee->transop.transform_id; + + ether_hdr_t eh; + + /* tap_pkt is not aligned so we have to copy to aligned memory */ + memcpy(&eh, tap_pkt, sizeof(ether_hdr_t)); + + /* Discard IP packets that are not originated by this hosts */ + if(!(eee->conf.allow_routing)) { + if(ntohs(eh.type) == 0x0800) { + /* This is an IP packet from the local source address - not forwarded. */ + uint32_t *src = (uint32_t*)&tap_pkt[ETH_FRAMESIZE + IP4_SRCOFFSET]; + + /* Note: all elements of the_ip are in network order */ + if(*src != eee->device.ip_addr) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "Discarding routed packet [%s]", + intoa(ntohl(*src), ip_buf, sizeof(ip_buf))); + return; + } else { + /* This packet is originated by us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + /* Optionally compress then apply transforms, eg encryption. */ + + /* Once processed, send to destination in PACKET */ + + memcpy(destMac, tap_pkt, N2N_MAC_SIZE); /* dest MAC is first in ethernet header */ + + memset(&cmn, 0, sizeof(cmn)); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + memset(&pkt, 0, sizeof(pkt)); + memcpy(pkt.srcMac, eee->device.mac_addr, N2N_MAC_SIZE); + memcpy(pkt.dstMac, destMac, N2N_MAC_SIZE); + + pkt.sock.family=0; /* do not encode sock */ + pkt.transform = tx_transop_idx; + + // compression needs to be tried before encode_PACKET is called for compression indication gets encoded there + pkt.compression = N2N_COMPRESSION_ID_NONE; + + if(eee->conf.compression) { + uint8_t * compression_buffer = NULL; + int32_t compression_len; + + switch (eee->conf.compression) { + case N2N_COMPRESSION_ID_LZO: + compression_buffer = malloc (len + len / 16 + 64 + 3); + if(lzo1x_1_compress(tap_pkt, len, compression_buffer, (lzo_uint*)&compression_len, wrkmem) == LZO_E_OK) { + if(compression_len < len) { + pkt.compression = N2N_COMPRESSION_ID_LZO; + } + } + break; +#ifdef N2N_HAVE_ZSTD + case N2N_COMPRESSION_ID_ZSTD: + compression_len = N2N_PKT_BUF_SIZE + 128; + compression_buffer = malloc (compression_len); // leaves enough room, for exact size call compression_len = ZSTD_compressBound (len); (slower) + compression_len = (int32_t)ZSTD_compress(compression_buffer, compression_len, tap_pkt, len, ZSTD_COMPRESSION_LEVEL) ; + if(!ZSTD_isError(compression_len)) { + if(compression_len < len) { + pkt.compression = N2N_COMPRESSION_ID_ZSTD; + } + } else { + traceEvent (TRACE_ERROR, "payload compression failed with zstd error '%s'.", + ZSTD_getErrorName(compression_len)); + free (compression_buffer); + // continue with unset without pkt.compression --> will send uncompressed + } + break; +#endif + default: + break; + } + + if(pkt.compression) { + traceEvent (TRACE_DEBUG, "payload compression [%s]: compressed %u bytes to %u bytes\n", + compression_str(pkt.compression), len, compression_len); + + memcpy (tap_pkt, compression_buffer, compression_len); + len = compression_len; + } + + if(compression_buffer) { + free (compression_buffer); + } + } + /* optional compression is encoded in uppermost bits of transform field. + * this is an intermediate solution to maintain compatibility until some + * upcoming major release (3.0?) brings up changes in packet structure anyway + * in the course of which a dedicated compression field could be spent. + * REVISIT then. */ + pkt.transform = pkt.transform | (pkt.compression << (8*sizeof(pkt.transform)-N2N_COMPRESSION_ID_BITLEN)); + + idx=0; + encode_PACKET(pktbuf, &idx, &cmn, &pkt); + + uint16_t headerIdx = idx; + + idx += eee->transop.fwd(&eee->transop, + pktbuf+idx, N2N_PKT_BUF_SIZE-idx, + tap_pkt, len, pkt.dstMac); + + traceEvent(TRACE_DEBUG, "Encode %u B PACKET [%u B data, %u B overhead] transform %u", + (u_int)idx, (u_int)len, (u_int)(idx-len), tx_transop_idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (pktbuf, headerIdx, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + time_stamp (), pearson_hash_16 (pktbuf, idx)); + +#ifdef MTU_ASSERT_VALUE + { + const u_int eth_udp_overhead = ETH_FRAMESIZE + IP4_MIN_SIZE + UDP_SIZE; + + // MTU assertion which avoids fragmentation by N2N + assert(idx + eth_udp_overhead <= MTU_ASSERT_VALUE); + } +#endif + + eee->transop.tx_cnt++; /* stats */ + + send_packet(eee, destMac, pktbuf, idx); /* to peer or supernode */ +} + +/* ************************************** */ + +/** Read a single packet from the TAP interface, process it and write out the + * corresponding packet to the cooked socket. + */ +void edge_read_from_tap(n2n_edge_t * eee) { + /* tun -> remote */ + uint8_t eth_pkt[N2N_PKT_BUF_SIZE]; + macstr_t mac_buf; + ssize_t len; + + len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE ); + if((len <= 0) || (len > N2N_PKT_BUF_SIZE)) + { + traceEvent(TRACE_WARNING, "read()=%d [%d/%s]", + (signed int)len, errno, strerror(errno)); + traceEvent(TRACE_WARNING, "TAP I/O operation aborted, restart later."); + sleep(3); + tuntap_close(&(eee->device)); + tuntap_open(&(eee->device), eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode, eee->tuntap_priv_conf.ip_addr, + eee->tuntap_priv_conf.netmask, eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu); + } + else + { + const uint8_t * mac = eth_pkt; + traceEvent(TRACE_DEBUG, "### Rx TAP packet (%4d) for %s", + (signed int)len, macaddr_str(mac_buf, mac)); + + if(eee->conf.drop_multicast && + (is_ip6_discovery(eth_pkt, len) || + is_ethMulticast(eth_pkt, len) + ) + ) + { + traceEvent(TRACE_INFO, "Dropping TX multicast"); + } + else + { + if(eee->cb.packet_from_tap) { + uint16_t tmp_len = len; + if(eee->cb.packet_from_tap(eee, eth_pkt, &tmp_len) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "DROP packet %u", (unsigned int)len); + + return; + } + len = tmp_len; + } + + edge_send_packet2net(eee, eth_pkt, len); + } + } +} + +/* ************************************** */ + + +/* ************************************** */ + +/** Read a datagram from the main UDP socket to the internet. */ +static void readFromIPSocket(n2n_edge_t * eee, int in_sock) { + n2n_common_t cmn; /* common fields in the packet header */ + + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ + macstr_t mac_buf1; + macstr_t mac_buf2; + + uint8_t udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */ + ssize_t recvlen; + size_t rem; + size_t idx; + size_t msg_type; + uint8_t from_supernode; + struct sockaddr_in sender_sock; + n2n_sock_t sender; + n2n_sock_t * orig_sender=NULL; + time_t now=0; + uint64_t stamp = 0; + + size_t i; + + i = sizeof(sender_sock); + recvlen = recvfrom(in_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t*)&i); + + if(recvlen < 0) { +#ifdef WIN32 + if(WSAGetLastError() != WSAECONNRESET) +#endif + { + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", recvlen, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + } + + return; /* failed to receive data from UDP */ + } + + /* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which + * IP transport version the packet arrived on. May need to UDP sockets. */ + sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */ + sender.port = ntohs(sender_sock.sin_port); + memcpy(&(sender.addr.v4), &(sender_sock.sin_addr.s_addr), IPV4_SIZE); + + /* The packet may not have an orig_sender socket spec. So default to last + * hop as sender. */ + orig_sender=&sender; + + traceEvent(TRACE_DEBUG, "### Rx N2N UDP (%d) from %s", + (signed int)recvlen, sock_to_cstr(sockbuf1, &sender)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + uint16_t checksum = 0; + if( packet_header_decrypt (udp_buf, recvlen, (char *)eee->conf.community_name, eee->conf.header_encryption_ctx, + eee->conf.header_iv_ctx, + &stamp, &checksum) == 0) { + traceEvent(TRACE_DEBUG, "readFromIPSocket failed to decrypt header."); + return; + } + + // time stamp verification follows in the packet specific section as it requires to determine the + // sender from the hash list by its MAC, or the packet might be from the supernode, this all depends + // on packet type, path taken (via supernode) and packet structure (MAC is not always in the same place) + + if (checksum != pearson_hash_16 (udp_buf, recvlen)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped packet due to checksum error."); + return; + } + } + + /* hexdump(udp_buf, recvlen); */ + + rem = recvlen; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + if(decode_common(&cmn, udp_buf, &rem, &idx) < 0) + { + traceEvent(TRACE_ERROR, "Failed to decode common section in N2N_UDP"); + return; /* failed to decode packet */ + } + + now = time(NULL); + + msg_type = cmn.pc; /* packet code */ + from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; + + if(0 == memcmp(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE)) { + switch(msg_type) { + case MSG_TYPE_PACKET: + { + /* process PACKET - most frequent so first in list. */ + n2n_PACKET_t pkt; + + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify (eee, from_supernode, pkt.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PACKET due to time stamp error."); + return; + } + } + + if(is_valid_peer_sock(&pkt.sock)) + orig_sender = &(pkt.sock); + + if(!from_supernode) { + /* This is a P2P packet from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed in + * handle_PACKET to double check this. + */ + traceEvent(TRACE_DEBUG, "Got P2P packet"); + traceEvent(TRACE_DEBUG, "[P2P] Rx data from %s [%u B]", sock_to_cstr(sockbuf1, &sender), recvlen); + find_and_remove_peer(&eee->pending_peers, pkt.srcMac); + } + else { + /* [PsP] : edge Peer->Supernode->edge Peer */ + traceEvent(TRACE_DEBUG, "[PsP] Rx data from %s (Via=%s) [%u B]", + sock_to_cstr(sockbuf2, orig_sender), sock_to_cstr(sockbuf1, &sender), recvlen); + } + + handle_PACKET(eee, &cmn, &pkt, orig_sender, udp_buf+idx, recvlen-idx); + break; + } + case MSG_TYPE_REGISTER: + { + /* Another edge is registering with us */ + n2n_REGISTER_t reg; + int via_multicast; + + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify (eee, from_supernode, reg.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER due to time stamp error."); + return; + } + } + + if(is_valid_peer_sock(®.sock)) + orig_sender = &(reg.sock); + + via_multicast = !memcmp(reg.dstMac, null_mac, N2N_MAC_SIZE); + + if(via_multicast && !memcmp(reg.srcMac, eee->device.mac_addr, N2N_MAC_SIZE)) { + traceEvent(TRACE_DEBUG, "Skipping REGISTER from self"); + break; + } + + if(!via_multicast && memcmp(reg.dstMac, eee->device.mac_addr, N2N_MAC_SIZE)) { + traceEvent(TRACE_DEBUG, "Skipping REGISTER for other peer"); + break; + } + + if(!from_supernode) { + /* This is a P2P registration from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed below + * to double check this. + */ + traceEvent(TRACE_DEBUG, "Got P2P register"); + traceEvent(TRACE_NORMAL, "[P2P] Rx REGISTER from %s", sock_to_cstr(sockbuf1, &sender)); + find_and_remove_peer(&eee->pending_peers, reg.srcMac); + + /* NOTE: only ACK to peers */ + send_register_ack(eee, orig_sender, ®); + } + else { + traceEvent(TRACE_NORMAL, "[PsP] Rx REGISTER src=%s dst=%s from sn=%s (edge:%s)", + macaddr_str(mac_buf1, reg.srcMac), macaddr_str(mac_buf2, reg.dstMac), + sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender)); + } + + check_peer_registration_needed(eee, from_supernode, reg.srcMac, orig_sender); + break; + } + case MSG_TYPE_REGISTER_ACK: + { + /* Peer edge is acknowledging our register request */ + n2n_REGISTER_ACK_t ra; + + decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify (eee, !definitely_from_supernode, ra.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_ACK due to time stamp error."); + return; + } + } + + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); + + traceEvent(TRACE_INFO, "Rx REGISTER_ACK src=%s dst=%s from peer %s (%s)", + macaddr_str(mac_buf1, ra.srcMac), + macaddr_str(mac_buf2, ra.dstMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender)); + + peer_set_p2p_confirmed(eee, ra.srcMac, &sender, now); + break; + } + case MSG_TYPE_REGISTER_SUPER_ACK: + { + // Indicates successful connection between the edge and SN nodes + static int bTrace = 1; + if (bTrace) + { + traceEvent(TRACE_NORMAL, "[OK] Edge Peer <<< ================ >>> Super Node"); + bTrace = 0; + } + + n2n_REGISTER_SUPER_ACK_t ra; + + if(eee->sn_wait) + { + decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped REGISTER_SUPER_ACK due to time stamp error."); + return; + } + } + + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); + + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK myMAC=%s [%s] (external %s). Attempts %u", + macaddr_str(mac_buf1, ra.edgeMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender), + (unsigned int)eee->sup_attempts); + + if(memcmp(ra.edgeMac, eee->device.mac_addr, N2N_MAC_SIZE)) { + traceEvent(TRACE_INFO, "readFromIPSocket dropped REGISTER_SUPER_ACK due to wrong addressing."); + return; + } + + if(0 == memcmp(ra.cookie, eee->last_cookie, N2N_COOKIE_SIZE)) + { + if(ra.num_sn > 0) + { + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK backup supernode at %s", + sock_to_cstr(sockbuf1, &(ra.sn_bak))); + } + + eee->last_sup = now; + eee->sn_wait=0; + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ + + if(eee->cb.sn_registration_updated) + eee->cb.sn_registration_updated(eee, now, &sender); + + /* NOTE: the register_interval should be chosen by the edge node + * based on its NAT configuration. */ + //eee->conf.register_interval = ra.lifetime; + } + else + { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie."); + } + } + else + { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER."); + } + break; + } case MSG_TYPE_PEER_INFO: { + n2n_PEER_INFO_t pi; + struct peer_info * scan; + decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx ); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify (eee, definitely_from_supernode, null_mac, stamp)) { + traceEvent(TRACE_DEBUG, "readFromIPSocket dropped PEER_INFO due to time stamp error."); + return; + } + } + + if(!is_valid_peer_sock(&pi.sock)) { + traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]", + sock_to_cstr(sockbuf1, &pi.sock), + macaddr_str(mac_buf1, pi.mac) ); + break; + } + + HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); + if(scan) { + scan->sock = pi.sock; + traceEvent(TRACE_INFO, "Rx PEER_INFO for %s: is at %s", + macaddr_str(mac_buf1, pi.mac), + sock_to_cstr(sockbuf1, &pi.sock)); + send_register(eee, &scan->sock, scan->mac_addr); + } else { + traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", + macaddr_str(mac_buf1, pi.mac) ); + } + + break; + } + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); + return; + } /* switch(msg_type) */ + } else if(from_supernode) /* if(community match) */ + traceEvent(TRACE_WARNING, "Received packet with unknown community"); + else + traceEvent(TRACE_INFO, "Ignoring packet with unknown community"); +} + +/* ************************************** */ + +void print_edge_stats(const n2n_edge_t *eee) { + const struct n2n_edge_stats *s = &eee->stats; + + traceEvent(TRACE_NORMAL, "**********************************"); + traceEvent(TRACE_NORMAL, "Packet stats:"); + traceEvent(TRACE_NORMAL, " TX P2P: %u pkts", s->tx_p2p); + traceEvent(TRACE_NORMAL, " RX P2P: %u pkts", s->rx_p2p); + traceEvent(TRACE_NORMAL, " TX Supernode: %u pkts (%u broadcast)", s->tx_sup, s->tx_sup_broadcast); + traceEvent(TRACE_NORMAL, " RX Supernode: %u pkts (%u broadcast)", s->rx_sup, s->rx_sup_broadcast); + traceEvent(TRACE_NORMAL, "**********************************"); +} + +/* ************************************** */ + +int run_edge_loop(n2n_edge_t * eee, int *keep_running) { + size_t numPurged; + time_t lastIfaceCheck=0; + time_t lastTransop=0; + time_t last_purge_known = 0; + time_t last_purge_pending = 0; + +#ifdef WIN32 + struct tunread_arg arg; + arg.eee = eee; + arg.keep_running = keep_running; + HANDLE tun_read_thread = startTunReadThread(&arg); +#endif + + *keep_running = 1; + update_supernode_reg(eee, time(NULL)); + + /* Main loop + * + * select() is used to wait for input on either the TAP fd or the UDP/TCP + * socket. When input is present the data is read and processed by either + * readFromIPSocket() or edge_read_from_tap() + */ + + while(*keep_running) { + int rc, max_sock = 0; + fd_set socket_mask; + struct timeval wait_time; + time_t nowTime; + + FD_ZERO(&socket_mask); + FD_SET(eee->udp_sock, &socket_mask); + FD_SET(eee->udp_mgmt_sock, &socket_mask); + max_sock = max(eee->udp_sock, eee->udp_mgmt_sock); + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + FD_SET(eee->udp_multicast_sock, &socket_mask); + max_sock = max(eee->udp_sock, eee->udp_multicast_sock); +#endif + +#ifndef WIN32 + FD_SET(eee->device.fd, &socket_mask); + max_sock = max(max_sock, eee->device.fd); +#endif + + wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS; wait_time.tv_usec = 0; + + rc = select(max_sock+1, &socket_mask, NULL, NULL, &wait_time); + nowTime=time(NULL); + + /* Make sure ciphers are updated before the packet is treated. */ + if((nowTime - lastTransop) > TRANSOP_TICK_INTERVAL) { + lastTransop = nowTime; + + eee->transop.tick(&eee->transop, nowTime); + } + + if(rc > 0) { + /* Any or all of the FDs could have input; check them all. */ + + if(FD_ISSET(eee->udp_sock, &socket_mask)) { + /* Read a cooked socket from the internet socket (unicast). Writes on the TAP + * socket. */ + readFromIPSocket(eee, eee->udp_sock); + } + + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(FD_ISSET(eee->udp_multicast_sock, &socket_mask)) { + /* Read a cooked socket from the internet socket (multicast). Writes on the TAP + * socket. */ + traceEvent(TRACE_DEBUG, "Received packet from multicast socket"); + readFromIPSocket(eee, eee->udp_multicast_sock); + } +#endif + + if(FD_ISSET(eee->udp_mgmt_sock, &socket_mask)) { + /* Read a cooked socket from the internet socket. Writes on the TAP + * socket. */ + readFromMgmtSocket(eee, keep_running); + + if(!(*keep_running)) + break; + } + +#ifndef WIN32 + if(FD_ISSET(eee->device.fd, &socket_mask)) { + /* Read an ethernet frame from the TAP socket. Write on the IP + * socket. */ + edge_read_from_tap(eee); + } +#endif + } + + /* Finished processing select data. */ + update_supernode_reg(eee, nowTime); + + numPurged = purge_expired_registrations(&eee->known_peers, &last_purge_known); + numPurged += purge_expired_registrations(&eee->pending_peers, &last_purge_pending); + + if(numPurged > 0) { + traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u", + numPurged, + HASH_COUNT(eee->pending_peers), + HASH_COUNT(eee->known_peers)); + } + + if(eee->conf.dyn_ip_mode && + ((nowTime - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) { + uint32_t old_ip = eee->device.ip_addr; + + traceEvent(TRACE_NORMAL, "Re-checking dynamic IP address."); + tuntap_get_address(&(eee->device)); + lastIfaceCheck = nowTime; + + if((old_ip != eee->device.ip_addr) && eee->cb.ip_address_changed) + eee->cb.ip_address_changed(eee, old_ip, eee->device.ip_addr); + } + + if (eee->cb.main_loop_period) + eee->cb.main_loop_period(eee, nowTime); + + } /* while */ + +#ifdef WIN32 + WaitForSingleObject(tun_read_thread, INFINITE); +#endif + + send_deregister(eee, &(eee->supernode)); + + closesocket(eee->udp_sock); + + return(0); +} + +/* ************************************** */ + +/** Deinitialise the edge and deallocate any owned memory. */ +void edge_term(n2n_edge_t * eee) { + if(eee->udp_sock >= 0) + closesocket(eee->udp_sock); + + if(eee->udp_mgmt_sock >= 0) + closesocket(eee->udp_mgmt_sock); + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(eee->udp_multicast_sock >= 0) + closesocket(eee->udp_multicast_sock); +#endif + + clear_peer_list(&eee->pending_peers); + clear_peer_list(&eee->known_peers); + + eee->transop.deinit(&eee->transop); + + edge_cleanup_routes(eee); + + closeTraceFile(); + + free(eee); +} + +/* ************************************** */ + +static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos) { + int sockopt; + + if(udp_local_port > 0) + traceEvent(TRACE_NORMAL, "Binding to local port %d", udp_local_port); + + eee->udp_sock = open_socket(udp_local_port, 1 /* bind ANY */); + if(eee->udp_sock < 0) { + traceEvent(TRACE_ERROR, "Failed to bind main UDP port %u", udp_local_port); + return(-1); + } + + if(tos) { + /* https://www.tucny.com/Home/dscp-tos */ + sockopt = tos; + + if(setsockopt(eee->udp_sock, IPPROTO_IP, IP_TOS, (char *)&sockopt, sizeof(sockopt)) == 0) + traceEvent(TRACE_NORMAL, "TOS set to 0x%x", tos); + else + traceEvent(TRACE_ERROR, "Could not set TOS 0x%x[%d]: %s", tos, errno, strerror(errno)); + } + +#ifdef IP_PMTUDISC_DO + sockopt = (eee->conf.disable_pmtu_discovery) ? IP_PMTUDISC_DONT : IP_PMTUDISC_DO; + + if(setsockopt(eee->udp_sock, IPPROTO_IP, IP_MTU_DISCOVER, &sockopt, sizeof(sockopt)) < 0) + traceEvent(TRACE_WARNING, "Could not %s PMTU discovery[%d]: %s", + (eee->conf.disable_pmtu_discovery) ? "disable" : "enable", errno, strerror(errno)); + else + traceEvent(TRACE_DEBUG, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled"); +#endif + + eee->udp_mgmt_sock = open_socket(mgmt_port, 0 /* bind LOOPBACK */); + if(eee->udp_mgmt_sock < 0) { + traceEvent(TRACE_ERROR, "Failed to bind management UDP port %u", mgmt_port); + return(-2); + } + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + /* Populate the multicast group for local edge */ + eee->multicast_peer.family = AF_INET; + eee->multicast_peer.port = N2N_MULTICAST_PORT; + eee->multicast_peer.addr.v4[0] = 224; /* N2N_MULTICAST_GROUP */ + eee->multicast_peer.addr.v4[1] = 0; + eee->multicast_peer.addr.v4[2] = 0; + eee->multicast_peer.addr.v4[3] = 68; + + eee->udp_multicast_sock = open_socket(N2N_MULTICAST_PORT, 1 /* bind ANY */); + if(eee->udp_multicast_sock < 0) + return(-3); + else { + u_int enable_reuse = 1; + + /* allow multiple sockets to use the same PORT number */ + setsockopt(eee->udp_multicast_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable_reuse, sizeof(enable_reuse)); +#ifdef SO_REUSEPORT /* no SO_REUSEPORT in Windows / old linux versions */ + setsockopt(eee->udp_multicast_sock, SOL_SOCKET, SO_REUSEPORT, &enable_reuse, sizeof(enable_reuse)); +#endif + } +#endif + + return(0); +} + +/* ************************************** */ + +#ifdef __linux__ + +static uint32_t get_gateway_ip() { + FILE *fd; + char *token = NULL; + char *gateway_ip_str = NULL; + char buf[256]; + uint32_t gateway = 0; + + if(!(fd = fopen("/proc/net/route", "r"))) + return(0); + + while(fgets(buf, sizeof(buf), fd)) { + if(strtok(buf, "\t") && (token = strtok(NULL, "\t")) && (!strcmp(token, "00000000"))) { + token = strtok(NULL, "\t"); + + if(token) { + struct in_addr addr; + + addr.s_addr = strtoul(token, NULL, 16); + gateway_ip_str = inet_ntoa(addr); + + if(gateway_ip_str) { + gateway = addr.s_addr; + break; + } + } + } + } + + fclose(fd); + + return(gateway); +} + +static char* route_cmd_to_str(int cmd, const n2n_route_t *route, char *buf, size_t bufsize) { + const char *cmd_str; + struct in_addr addr; + char netbuf[64], gwbuf[64]; + + switch(cmd) { + case RTM_NEWROUTE: + cmd_str = "Add"; + break; + case RTM_DELROUTE: + cmd_str = "Delete"; + break; + default: + cmd_str = "?"; + } + + addr.s_addr = route->net_addr; + inet_ntop(AF_INET, &addr, netbuf, sizeof(netbuf)); + addr.s_addr = route->gateway; + inet_ntop(AF_INET, &addr, gwbuf, sizeof(gwbuf)); + + snprintf(buf, bufsize, "%s %s/%d via %s", cmd_str, netbuf, route->net_bitlen, gwbuf); + + return(buf); +} + +/* Adapted from https://olegkutkov.me/2019/08/29/modifying-linux-network-routes-using-netlink/ */ +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +/* Add new data to rtattr */ +static int rtattr_add(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) +{ + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + if(NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { + traceEvent(TRACE_ERROR, "rtattr_add error: message exceeded bound of %d\n", maxlen); + return -1; + } + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; + + if(alen) + memcpy(RTA_DATA(rta), data, alen); + + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + + return 0; +} + +static int routectl(int cmd, int flags, n2n_route_t *route, int if_idx) { + int rv = -1; + int rv2; + char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ + char route_buf[256]; + struct iovec iov; + struct msghdr msg; + struct sockaddr_nl sa; + uint8_t read_reply = 1; + int nl_sock; + + struct { + struct nlmsghdr n; + struct rtmsg r; + char buf[4096]; + } nl_request; + + if((nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); + return(-1); + } + + /* Subscribe to route change events */ + iov.iov_base = nl_buf; + iov.iov_len = sizeof(nl_buf); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_NOTIFY; + sa.nl_pid = getpid(); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + /* Subscribe to route events */ + if(bind(nl_sock, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); + goto out; + } + + /* Initialize request structure */ + memset(&nl_request, 0, sizeof(nl_request)); + nl_request.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + nl_request.n.nlmsg_flags = NLM_F_REQUEST | flags; + nl_request.n.nlmsg_type = cmd; + nl_request.r.rtm_family = AF_INET; + nl_request.r.rtm_table = RT_TABLE_MAIN; + nl_request.r.rtm_scope = RT_SCOPE_NOWHERE; + + /* Set additional flags if NOT deleting route */ + if(cmd != RTM_DELROUTE) { + nl_request.r.rtm_protocol = RTPROT_BOOT; + nl_request.r.rtm_type = RTN_UNICAST; + } + + nl_request.r.rtm_family = AF_INET; + nl_request.r.rtm_dst_len = route->net_bitlen; + + /* Select scope, for simplicity we supports here only IPv6 and IPv4 */ + if(nl_request.r.rtm_family == AF_INET6) + nl_request.r.rtm_scope = RT_SCOPE_UNIVERSE; + else + nl_request.r.rtm_scope = RT_SCOPE_LINK; + + /* Set gateway */ + if(route->net_bitlen) { + if(rtattr_add(&nl_request.n, sizeof(nl_request), RTA_GATEWAY, &route->gateway, 4) < 0) + goto out; + + nl_request.r.rtm_scope = 0; + nl_request.r.rtm_family = AF_INET; + } + + /* Don't set destination and interface in case of default gateways */ + if(route->net_bitlen) { + /* Set destination network */ + if(rtattr_add(&nl_request.n, sizeof(nl_request), /*RTA_NEWDST*/ RTA_DST, &route->net_addr, 4) < 0) + goto out; + + /* Set interface */ + if(if_idx > 0) { + if(rtattr_add(&nl_request.n, sizeof(nl_request), RTA_OIF, &if_idx, sizeof(int)) < 0) + goto out; + } + } + + /* Send message to the netlink */ + if((rv2 = send(nl_sock, &nl_request, sizeof(nl_request), 0)) != sizeof(nl_request)) { + traceEvent(TRACE_ERROR, "netlink send failed [%d]: %s", errno, strerror(errno)); + goto out; + } + + /* Wait for the route notification. Assume that the first reply we get is the correct one. */ + traceEvent(TRACE_DEBUG, "waiting for netlink response..."); + + while(read_reply) { + ssize_t len = recvmsg(nl_sock, &msg, 0); + struct nlmsghdr *nh; + + for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { + /* Stop after the first reply */ + read_reply = 0; + + if(nh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = NLMSG_DATA(nh); + int errcode = err->error; + + if(errcode < 0) + errcode = -errcode; + + /* Ignore EEXIST as existing rules are ok */ + if(errcode != EEXIST) { + traceEvent(TRACE_ERROR, "[err=%d] route: %s", errcode, route_cmd_to_str(cmd, route, route_buf, sizeof(route_buf))); + goto out; + } + } + + if(nh->nlmsg_type == NLMSG_DONE) + break; + + if(nh->nlmsg_type == cmd) { + traceEvent(TRACE_DEBUG, "Found netlink reply"); + break; + } + } + } + + traceEvent(TRACE_DEBUG, route_cmd_to_str(cmd, route, route_buf, sizeof(route_buf))); + rv = 0; + + out: + close(nl_sock); + + return(rv); +} +#endif + +/* ************************************** */ + +static int edge_init_routes_linux(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) { +#ifdef __linux__ + int i; + for (i = 0; inet_addr == 0) && (route->net_bitlen == 0)) { + /* This is a default gateway rule. We need to: + * + * 1. Add a route to the supernode via the host internet gateway + * 2. Add the new default gateway route + * + * Instead of modifying the system default gateway, we use the trick + * of adding a route to the networks 0.0.0.0/1 and 128.0.0.0/1, thus + * covering the whole IPv4 range. Such routes in linux take precedence + * over the default gateway (0.0.0.0/0) since are more specific. + * This leaves the default gateway unchanged so that after n2n is + * stopped the cleanup is easier. + * See https://github.com/zerotier/ZeroTierOne/issues/178#issuecomment-204599227 + */ + n2n_sock_t sn; + n2n_route_t custom_route; + uint32_t *a; + + if (eee->sn_route_to_clean) { + traceEvent(TRACE_ERROR, "Only one default gateway route allowed"); + return(-1); + } + + if (eee->conf.sn_num != 1) { + traceEvent(TRACE_ERROR, "Only one supernode supported with routes"); + return(-1); + } + + if (supernode2addr(&sn, eee->conf.sn_ip_array[0]) < 0) + return(-1); + + if (sn.family != AF_INET) { + traceEvent(TRACE_ERROR, "Only IPv4 routes supported"); + return(-1); + } + + a = (u_int32_t*)sn.addr.v4; + custom_route.net_addr = *a; + custom_route.net_bitlen = 32; + custom_route.gateway = get_gateway_ip(); + + if (!custom_route.gateway) { + traceEvent(TRACE_ERROR, "could not determine the gateway IP address"); + return(-1); + } + + /* ip route add supernode via internet_gateway */ + if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, -1) < 0) + return(-1); + + /* Save the route to delete it when n2n is stopped */ + eee->sn_route_to_clean = calloc(1, sizeof(n2n_route_t)); + + /* Store a copy of the rules into the runtime to delete it during shutdown */ + if (eee->sn_route_to_clean) + *eee->sn_route_to_clean = custom_route; + + /* ip route add 0.0.0.0/1 via n2n_gateway */ + custom_route.net_addr = 0; + custom_route.net_bitlen = 1; + custom_route.gateway = route->gateway; + + if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0) + return(-1); + + /* ip route add 128.0.0.0/1 via n2n_gateway */ + custom_route.net_addr = 128; + custom_route.net_bitlen = 1; + custom_route.gateway = route->gateway; + + if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0) + return(-1); + } + else { + /* ip route add net via n2n_gateway */ + if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, route, eee->device.if_idx) < 0) + return(-1); + } + } +#endif + + return(0); +} + +/* ************************************** */ + +static int edge_init_routes_win(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) +{ +#ifdef WIN32 + int i; + struct in_addr net_addr, gateway; + char c_net_addr[32]; + char c_gateway[32]; + char cmd[256]; + + for (i = 0; i < num_routes; i++) + { + n2n_route_t *route = &routes[i]; + if ((route->net_addr == 0) && (route->net_bitlen == 0)) + { + traceEvent(TRACE_NORMAL, "Warning: The 0.0.0.0/0 route settings are not supported on Windows"); + return (-1); + } + else + { + /* ip route add net via n2n_gateway */ + memcpy(&net_addr, &(route->net_addr), sizeof(net_addr)); + memcpy(&gateway, &(route->gateway), sizeof(gateway)); + _snprintf(c_net_addr, sizeof(c_net_addr), inet_ntoa(net_addr)); + _snprintf(c_gateway, sizeof(c_gateway), inet_ntoa(gateway)); + _snprintf(cmd, sizeof(cmd), "route add %s/%d %s > nul", c_net_addr, route->net_bitlen, c_gateway); + traceEvent(TRACE_NORMAL, "ROUTE CMD = '%s'\n", cmd); + system(cmd); + } + } + +#endif // WIN32 + + return (0); +} + +/* ************************************** */ + +/* Add the user-provided routes to the linux routing table. Network routes + * are bound to the n2n TAP device, so they are automatically removed when + * the TAP device is destroyed. */ +static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) { +#ifdef __linux__ + return edge_init_routes_linux(eee, routes, num_routes); +#endif + +#ifdef WIN32 + return edge_init_routes_win(eee, routes, num_routes); +#endif + return 0; +} + +/* ************************************** */ + +static void edge_cleanup_routes(n2n_edge_t *eee) { +#ifdef __linux__ + if(eee->sn_route_to_clean) { + /* ip route del supernode via internet_gateway */ + routectl(RTM_DELROUTE, 0, eee->sn_route_to_clean, -1); + free(eee->sn_route_to_clean); + } +#endif +} + +/* ************************************** */ + +void edge_init_conf_defaults(n2n_edge_conf_t *conf) { + memset(conf, 0, sizeof(*conf)); + + conf->local_port = 0 /* any port */; + conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */ + conf->transop_id = N2N_TRANSFORM_ID_NULL; + conf->header_encryption = HEADER_ENCRYPTION_NONE; + conf->compression = N2N_COMPRESSION_ID_NONE; + conf->drop_multicast = 1; + conf->allow_p2p = 1; + conf->disable_pmtu_discovery = 1; + conf->register_interval = REGISTER_SUPER_INTERVAL_DFL; + + if(getenv("N2N_KEY")) { + conf->encrypt_key = strdup(getenv("N2N_KEY")); + conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; + } +} + +/* ************************************** */ + +void edge_term_conf(n2n_edge_conf_t *conf) { + if(conf->routes) free(conf->routes); +} + +/* ************************************** */ + +const n2n_edge_conf_t* edge_get_conf(const n2n_edge_t *eee) { + return(&eee->conf); +} + +/* ************************************** */ + +int edge_conf_add_supernode(n2n_edge_conf_t *conf, const char *ip_and_port) { + if(conf->sn_num >= N2N_EDGE_NUM_SUPERNODES) + return(-1); + + strncpy((conf->sn_ip_array[conf->sn_num]), ip_and_port, N2N_EDGE_SN_HOST_SIZE); + traceEvent(TRACE_NORMAL, "Adding supernode[%u] = %s", (unsigned int)conf->sn_num, (conf->sn_ip_array[conf->sn_num])); + conf->sn_num++; + + return(0); +} + +/* ************************************** */ + +int quick_edge_init(char *device_name, char *community_name, + char *encrypt_key, char *device_mac, + char *local_ip_address, + char *supernode_ip_address_port, + int *keep_on_running) { + tuntap_dev tuntap; + n2n_edge_t *eee; + n2n_edge_conf_t conf; + int rv; + + /* Setup the configuration */ + edge_init_conf_defaults(&conf); + conf.encrypt_key = encrypt_key; + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + snprintf((char*)conf.community_name, sizeof(conf.community_name), "%s", community_name); + edge_conf_add_supernode(&conf, supernode_ip_address_port); + + /* Validate configuration */ + if(edge_verify_conf(&conf) != 0) + return(-1); + + /* Open the tuntap device */ + if(tuntap_open(&tuntap, device_name, "static", + local_ip_address, "255.255.255.0", + device_mac, DEFAULT_MTU) < 0) + return(-2); + + /* Init edge */ + if((eee = edge_init(&tuntap, &conf, &rv)) == NULL) + goto quick_edge_init_end; + + rv = run_edge_loop(eee, keep_on_running); + edge_term(eee); + edge_term_conf(&conf); + + quick_edge_init_end: + tuntap_close(&tuntap); + return(rv); +} + +/* ************************************** */ diff --git a/bundles/n2n_ntop_v2/src/edge_utils_win32.c b/bundles/n2n_ntop_v2/src/edge_utils_win32.c new file mode 100644 index 00000000..306fd503 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/edge_utils_win32.c @@ -0,0 +1,49 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifdef WIN32 + +#include "edge_utils_win32.h" + +/* ************************************** */ + +static DWORD* tunReadThread(LPVOID lpArg) { + struct tunread_arg *arg = (struct tunread_arg*)lpArg; + + while(*arg->keep_running) + edge_read_from_tap(arg->eee); + + return((DWORD*)NULL); +} + +/* ************************************** */ + +/** Start a second thread in Windows because TUNTAP interfaces do not expose + * file descriptors. */ +HANDLE startTunReadThread(struct tunread_arg *arg) { + DWORD dwThreadId; + + return(CreateThread(NULL, /* security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ + (void*)arg, /* argument to thread function */ + 0, /* thread creation flags */ + &dwThreadId)); /* thread id out */ +} +#endif + diff --git a/bundles/n2n_ntop_v2/src/example_edge_embed.c b/bundles/n2n_ntop_v2/src/example_edge_embed.c new file mode 100644 index 00000000..ac809d5c --- /dev/null +++ b/bundles/n2n_ntop_v2/src/example_edge_embed.c @@ -0,0 +1,75 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +static int keep_running; + +int main() +{ + n2n_edge_conf_t conf; + tuntap_dev tuntap; + n2n_edge_t *eee; + int rc; + + edge_init_conf_defaults(&conf); + conf.allow_p2p = 1; // Whether to allow peer-to-peer communication + conf.allow_routing = 1; // Whether to allow the edge to route packets to other edges + snprintf((char *)conf.community_name, sizeof(conf.community_name), "%s", "mycommunity"); // Community to connect to + conf.disable_pmtu_discovery = 1; // Whether to disable the path MTU discovery + conf.drop_multicast = 0; // Whether to disable multicast + conf.dyn_ip_mode = 0; // Whether the IP address is set dynamically (see IP mode; 0 if static, 1 if dynamic) + conf.encrypt_key = "mysecret"; // Secret to decrypt & encrypt with + conf.local_port = 0; // What port to use (0 = any port) + conf.mgmt_port = N2N_EDGE_MGMT_PORT; // Edge management port (5644 by default) + conf.register_interval = 1; // Interval for both UDP NAT hole punching and supernode registration + conf.register_ttl = 1; // Interval for UDP NAT hole punching through supernode + edge_conf_add_supernode(&conf, "localhost:1234"); // Supernode to connect to + conf.tos = 16; // Type of service for sent packets + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; // Use the twofish encryption + + if (edge_verify_conf(&conf) != 0) + { + return -1; + } + + if (tuntap_open(&tuntap, + "edge0", // Name of the device to create + "static", // IP mode; static|dhcp + "10.0.0.1", // Set ip address + "255.255.255.0", // Netmask to use + "DE:AD:BE:EF:01:10", // Set mac address + DEFAULT_MTU) < 0) // MTU to use + { + return -1; + } + + eee = edge_init(&tuntap, &conf, &rc); + if (eee == NULL) + { + exit(1); + } + + keep_running = 1; + rc = run_edge_loop(eee, &keep_running); + + edge_term(eee); + tuntap_close(&tuntap); + + return rc; +} diff --git a/bundles/n2n_ntop_v2/src/example_edge_embed_quick_edge_init.c b/bundles/n2n_ntop_v2/src/example_edge_embed_quick_edge_init.c new file mode 100644 index 00000000..39d1cd0d --- /dev/null +++ b/bundles/n2n_ntop_v2/src/example_edge_embed_quick_edge_init.c @@ -0,0 +1,54 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +/* + This tool demonstrates how to easily embed + n2n on an existing application + */ + +int main(int argc, char* argv[]) { + char *device_name = (char*)"n2n0"; + char *network_name = (char*)"mynetwork"; + char *secret_key = (char*)"mysecret"; + char *my_mac_address = (char*)"DE:AD:BE:EF:01:10"; + char *my_ipv4_addr = (char*)"1.2.3.4"; + char *supernode = (char*)"7.8.9.10:1234"; + int keep_on_running = 1; + + /* Increase tracelevel to see what's happening */ + setTraceLevel(10); + + /* Random seed */ + n2n_srand (n2n_seed()); + + /* + NOTE + + As the function below won't end, you should + call it inside a separate thread + */ + return(quick_edge_init(device_name, + network_name, + secret_key, + my_mac_address, + my_ipv4_addr, + supernode, + &keep_on_running)); +} diff --git a/bundles/n2n_ntop_v2/src/example_sn_embed.c b/bundles/n2n_ntop_v2/src/example_sn_embed.c new file mode 100644 index 00000000..4428e694 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/example_sn_embed.c @@ -0,0 +1,50 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +static int keep_running; + +int main() +{ + n2n_sn_t sss_node; + int rc; + + sn_init(&sss_node); + sss_node.daemon = 0; // Whether to daemonize + sss_node.lport = 1234; // Main UDP listen port + + sss_node.sock = open_socket(sss_node.lport, 1); + if (-1 == sss_node.sock) + { + exit(-2); + } + + sss_node.mgmt_sock = open_socket(5645, 0); // Main UDP management port + if (-1 == sss_node.mgmt_sock) + { + exit(-2); + } + + keep_running = 1; + rc = run_sn_loop(&sss_node, &keep_running); + + sn_term(&sss_node); + + return rc; +} diff --git a/bundles/n2n_ntop_v2/src/header_encryption.c b/bundles/n2n_ntop_v2/src/header_encryption.c new file mode 100644 index 00000000..c526726e --- /dev/null +++ b/bundles/n2n_ntop_v2/src/header_encryption.c @@ -0,0 +1,113 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + +#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) + +/* ********************************************************************** */ + +uint32_t packet_header_decrypt (uint8_t packet[], uint16_t packet_len, + char * community_name, he_context_t * ctx, + he_context_t * ctx_iv, uint64_t * stamp, uint16_t * checksum) { + + // assemble IV + // the last four are ASCII "n2n!" and do not get overwritten + uint8_t iv[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6E, 0x32, 0x6E, 0x21 }; + // the first 96 bits of the packet get padded with ASCII "n2n!" + // to full 128 bit IV + memcpy (iv, packet, 12); + + // extract time stamp (first 64 bit) and checksum (last 16 bit) blended in IV + speck_he_iv_decrypt (iv, (speck_context_t*)ctx_iv); + *checksum = be16toh (((uint16_t*)iv)[5]); + *stamp = be64toh (((uint64_t*)iv)[0]); + + memcpy (iv, packet, 12); + + // try community name as possible key and check for magic bytes + uint32_t magic = 0x6E326E00; // ="n2n_" + uint32_t test_magic; + // check for magic bytes and reasonable value in header len field + // so, as a first step, decrypt 4 bytes only starting at byte 12 + speck_he ((uint8_t*)&test_magic, &packet[12], 4, iv, (speck_context_t*)ctx); + test_magic = be32toh (test_magic); + if( (((test_magic >> 8) << 8) == magic) // check the thre uppermost bytes + && (((uint8_t)test_magic) <= packet_len) // lowest 8 bit of test_magic are header_len + ) { + // decrypt the complete header + speck_he (&packet[12], &packet[12], (uint8_t)(test_magic) - 12, iv, (speck_context_t*)ctx); + // restore original packet order + memcpy (&packet[0], &packet[16], 4); + memcpy (&packet[4], community_name, N2N_COMMUNITY_SIZE); + return (1); // successful + } else + return (0); // unsuccessful +} + +/* ********************************************************************** */ + +int32_t packet_header_encrypt (uint8_t packet[], uint8_t header_len, he_context_t * ctx, + he_context_t * ctx_iv, uint64_t stamp, uint16_t checksum) { + + uint8_t iv[16]; + uint16_t *iv16 = (uint16_t*)&iv; + uint32_t *iv32 = (uint32_t*)&iv; + uint64_t *iv64 = (uint64_t*)&iv; + const uint32_t magic = 0x6E326E21; // = ASCII "n2n!" + + if(header_len < 20) { + traceEvent(TRACE_DEBUG, "packet_header_encrypt dropped a packet too short to be valid."); + return (-1); + } + + memcpy (&packet[16], &packet[00], 4); + + iv64[0] = htobe64 (stamp); + iv16[4] = n2n_rand (); + iv16[5] = htobe16 (checksum); + iv32[3] = htobe32 (magic); + // blend checksum into 96-bit IV + speck_he_iv_encrypt (iv, (speck_context_t*)ctx_iv); + + memcpy (packet, iv, 16); + packet[15] = header_len; + + speck_he (&packet[12], &packet[12], header_len - 12, iv, (speck_context_t*)ctx); + return (0); +} + +/* ********************************************************************** */ + +void packet_header_setup_key (const char * community_name, he_context_t ** ctx, + he_context_t ** ctx_iv) { + + uint8_t key[16]; + pearson_hash_128 (key, (uint8_t*)community_name, N2N_COMMUNITY_SIZE); + + *ctx = (he_context_t*)calloc(1, sizeof (speck_context_t)); + speck_expand_key_he (key, (speck_context_t*)*ctx); + + // hash again and use last 96 bit (skipping 4 bytes) as key for IV encryption + // REMOVE as soon as checksum and replay protection get their own fields + pearson_hash_128 (key, key, sizeof (key)); + *ctx_iv = (he_context_t*)calloc(1, sizeof (speck_context_t)); + speck_expand_key_he_iv (&key[4], (speck_context_t*)*ctx_iv); +} diff --git a/bundles/n2n_ntop_v2/src/minilzo.c b/bundles/n2n_ntop_v2/src/minilzo.c new file mode 100644 index 00000000..6a62b31b --- /dev/null +++ b/bundles/n2n_ntop_v2/src/minilzo.c @@ -0,0 +1,4112 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO +#define LZO_BUILD + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if defined(__IBMCPP__) && !defined(__IBMC__) +# define __IBMC__ __IBMCPP__ +#endif +#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) +# define __INTEL_COMPILER __ICL +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if defined(__INTEL_COMPILER) && defined(__linux__) +# pragma warning(disable: 193) +#endif +#if defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif 0 && defined(__C251__) +# pragma warning disable = 322 +#endif +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if (_MSC_VER >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if 0 +#define LZO_0xffffL 0xfffful +#define LZO_0xffffffffL 0xfffffffful +#else +#define LZO_0xffffL 65535ul +#define LZO_0xffffffffL 4294967295ul +#endif +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +#else +# define LZO_EXTERN_C extern +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if defined(LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif defined(LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif (defined(__mips__) && defined(__psp__)) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) || defined(__MACOS__) +# define LZO_OS_POSIX_MACOSX 1 +# define LZO_INFO_OS_POSIX "macosx" +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +#elif defined(__INTEL_COMPILER) +# define LZO_CC_INTELC 1 +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_WIN32) || defined(_WIN64) +# define LZO_CC_SYNTAX_MSC 1 +# else +# define LZO_CC_SYNTAX_GNUC 1 +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__llvm__) && defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# else +# define LZO_CC_LLVM (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# endif +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) +# define LZO_CC_IBMC 1 +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(_MSC_VER) +# define LZO_CC_MSC 1 +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#elif defined(__MWERKS__) +# define LZO_CC_MWERKS 1 +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC)+0 > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if (__ZTC__ == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !defined(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if defined(LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_ARCH_IA16 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +# define LZO_ARCH_IA16PM 1 +#endif +#if defined(LZO_ARCH_ARM_THUMB) && !defined(LZO_ARCH_ARM) +# error "this should not happen" +#endif +#if defined(LZO_ARCH_I086PM) && !defined(LZO_ARCH_I086) +# error "this should not happen" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "this should not happen" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "this should not happen" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "this should not happen" +# endif +#endif +#if !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "this should not happen" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !defined(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "this should not happen" +# elif (LZO_CC_ZORTECHC) +# else +# error "this should not happen" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#endif +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#endif +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#endif +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#endif +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#endif +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#endif +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && defined(LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if defined(LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if (LZO_ARCH_I086) +# define __LZO_WORDSIZE 2 +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "LZO_MM" +# endif +#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) +# define __LZO_WORDSIZE 1 +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define __LZO_WORDSIZE 4 +# define LZO_SIZEOF_VOID_P 4 +# else +# define __LZO_WORDSIZE 2 +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_M16C) +# define __LZO_WORDSIZE 2 +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +# define __LZO_WORDSIZE 8 +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define __LZO_WORDSIZE LZO_SIZEOF_LONG +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#elif (LZO_ARCH_SPU) +# if 0 +# define __LZO_WORDSIZE 16 +# endif +# define LZO_SIZEOF_VOID_P 4 +#else +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_WORDSIZE) +# if defined(__LZO_WORDSIZE) +# define LZO_WORDSIZE __LZO_WORDSIZE +# else +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +# endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#else +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "LZO_MM" +# endif +#else +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !defined(LZO_ABI_BIG_ENDIAN) && !defined(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_M68K || LZO_ARCH_S390) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if defined(LZO_ABI_BIG_ENDIAN) && defined(LZO_ABI_LITTLE_ENDIAN) +# error "this should not happen" +#endif +#if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif defined(LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif defined(LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if !defined(__LZO_LIBC_OVERRIDE) +#if defined(LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif defined(LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif defined(LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif defined(LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif defined(LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uclibc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#else +# define __lzo_gnuc_extension__ +#endif +#endif +#if !defined(__lzo_ua_volatile) +# define __lzo_ua_volatile volatile +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#endif +#endif +#if defined(__lzo_alignof) +# define __lzo_HAVE_alignof 1 +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# define __lzo_HAVE_constructor 1 +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# define __lzo_HAVE_destructor 1 +#endif +#if defined(__lzo_HAVE_destructor) && !defined(__lzo_HAVE_constructor) +# error "this should not happen" +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_CILLY || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define __lzo_inline inline +#endif +#endif +#if defined(__lzo_inline) +# define __lzo_HAVE_inline 1 +#else +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#endif +#endif +#if defined(__lzo_forceinline) +# define __lzo_HAVE_forceinline 1 +#else +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#endif +#endif +#if defined(__lzo_noinline) +# define __lzo_HAVE_noinline 1 +#else +# define __lzo_noinline +#endif +#if (defined(__lzo_HAVE_forceinline) || defined(__lzo_HAVE_noinline)) && !defined(__lzo_HAVE_inline) +# error "this should not happen" +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#endif +#endif +#if defined(__lzo_noreturn) +# define __lzo_HAVE_noreturn 1 +#else +# define __lzo_noreturn +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# define __lzo_HAVE_nothrow 1 +#else +# define __lzo_nothrow +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#endif +#endif +#if defined(__lzo_restrict) +# define __lzo_HAVE_restrict 1 +#else +# define __lzo_restrict +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# define __lzo_HAVE_likely 1 +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# define __lzo_HAVE_unlikely 1 +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# elif (LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if (0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)]; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)]; +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)]; +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];} +# endif +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !defined(LZO_CFG_NO_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# define LZO_OPT_UNALIGNED64 1 +#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) +#elif (LZO_ARCH_ARM) +# define LZO_OPT_AVOID_SHORT 1 +# define LZO_OPT_AVOID_USHORT 1 +#elif (LZO_ARCH_CRIS) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_I386) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(LZO_ABI_BIG_ENDIAN) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_S390) +# define LZO_OPT_UNALIGNED16 1 +# define LZO_OPT_UNALIGNED32 1 +# if (LZO_SIZEOF_SIZE_T == 8) +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#if !defined(LZO_CFG_NO_INLINE_ASM) +#if defined(LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if !defined(LZO_CFG_NO_UNALIGNED) +#if defined(LZO_ABI_NEUTRAL_ENDIAN) || defined(LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(LZO_CFG_NO_INLINE_ASM) +#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +#elif (LZO_CC_INTELC) +# define __LZO_ASM_CLOBBER "memory" +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +#endif +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2030) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +# define ACC_LIBC_FREESTANDING 1 +# define ACC_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_NO_UNALIGNED) +# define ACC_CFG_NO_UNALIGNED 1 +#endif +#if defined(LZO_ARCH_GENERIC) +# define ACC_ARCH_GENERIC 1 +#endif +#if defined(LZO_ABI_NEUTRAL_ENDIAN) +# define ACC_ABI_NEUTRAL_ENDIAN 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define ACC_CONFIG_NO_HEADER 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#endif + +#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_BORLANDC && LZO_ARCH_I086) +# pragma option -h +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +# pragma warning(disable: 4514 4710 4711) +#endif + +#if (LZO_CC_SUNPROC) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +#endif + +#if defined(__LZO_MMODEL_HUGE) && (!LZO_HAVE_MM_HUGE_PTR) +# error "this should not happen - check defines for __huge" +#endif + +#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define ACC_WANT_ACC_INCD_H 1 +# define ACC_WANT_ACC_INCE_H 1 +# define ACC_WANT_ACC_INCI_H 1 +#elif 1 +# include +#else +# define ACC_WANT_ACC_INCD_H 1 +#endif + +#if (LZO_ARCH_I086) +# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT +# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) +# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) +# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) +# define __LZO_UINTPTR_T_IS_POINTER 1 + typedef char* lzo_uintptr_t; +# define lzo_uintptr_t lzo_uintptr_t +# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t size_t +# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long +# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned int +# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) +# define lzo_uintptr_t unsigned long long +# else +# define lzo_uintptr_t size_t +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if defined(LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !defined(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !defined(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !defined(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !defined(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#elif !defined(__LZO_MMODEL_HUGE) +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if defined(LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if !defined(__lzo_inline) +# define __lzo_inline +#endif +#if !defined(__lzo_forceinline) +# define __lzo_forceinline +#endif +#if !defined(__lzo_noinline) +# define __lzo_noinline +#endif + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_LSIZE(bits) (1ul << (bits)) +#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#if 1 && !defined(LZO_CFG_NO_UNALIGNED) +#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if (LZO_SIZEOF_SHORT == 2) +# define LZO_UNALIGNED_OK_2 +# endif +# if (LZO_SIZEOF_INT == 4) +# define LZO_UNALIGNED_OK_4 +# endif +#endif +#endif + +#if defined(LZO_UNALIGNED_OK_2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(short) == 2) +#endif +#if defined(LZO_UNALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#elif defined(LZO_ALIGNED_OK_4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +__LZO_EXTERN_C int __lzo_init_done; +__LZO_EXTERN_C const char __lzo_copyright[]; +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(lzo_uintptr_t) +# if defined(__LZO_MMODEL_HUGE) +# define lzo_uintptr_t unsigned long +# else +# define lzo_uintptr_t acc_uintptr_t +# ifdef __ACC_INTPTR_T_IS_POINTER +# define __LZO_UINTPTR_T_IS_POINTER 1 +# endif +# endif +#endif + +#if (LZO_ARCH_I086) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) +#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#elif (LZO_MM_PVP) +#define PTR(a) ((lzo_bytep) (a)) +#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) +#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_int32 a_lzo_int32; + lzo_uint32 a_lzo_uint32; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + lzo_voidp a_lzo_voidp; + void * a_void_p; + lzo_bytep a_lzo_bytep; + lzo_bytepp a_lzo_bytepp; + lzo_uintp a_lzo_uintp; + lzo_uint * a_lzo_uint_p; + lzo_uint32p a_lzo_uint32p; + lzo_uint32 * a_lzo_uint32_p; + unsigned char * a_uchar_p; + char * a_char_p; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#define LZO_DETERMINISTIC + +#define LZO_DICT_USE_PTR +#if 0 && (LZO_ARCH_I086) +# undef LZO_DICT_USE_PTR +#endif + +#if defined(LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) + p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#elif (LZO_MM_PVP) + p = (lzo_uintptr_t) (ptr); + p = (p << 3) | (p >> 61); +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if defined(__LZO_UINTPTR_T_IS_POINTER) + size_t n = (size_t) ptr; + n = (((n + size - 1) / size) * size) - n; +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Built: " __DATE__ " " __TIME__ " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ +#if (LZO_OS_DOS16 && LZO_CC_TURBOC) + return (lzo_voidp) __lzo_copyright; +#else + return (const lzo_bytep) __lzo_copyright; +#endif +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32) +lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32 s1 = adler & 0xffff; + lzo_uint32 s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCMP) + const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMCPY) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMMOVE) + lzo_hbyte_p p1 = (lzo_hbyte_p) dest; + const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !defined(HAVE_MEMSET) + lzo_hbyte_p p = (lzo_hbyte_p) s; + if __lzo_likely(len > 0) do + *p++ = (unsigned char) c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, c, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif + +#if !defined(__LZO_IN_MINILZO) + +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) + + ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) + ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) + +#if !defined(__LZO_UINTPTR_T_IS_POINTER) + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + + ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) + ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) + ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + +#endif +#undef ACCCHK_ASSERT + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ + lzo_bool r = 1; + union { unsigned char c[2*sizeof(lzo_xint)]; lzo_xint l[2]; } u; + lzo_uintptr_t p; + +#if !defined(LZO_CFG_NO_CONFIG_CHECK) +#if defined(LZO_ABI_BIG_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[sizeof(lzo_xint) - 1] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_ABI_LITTLE_ENDIAN) + u.l[0] = u.l[1] = 0; u.c[0] = 128; + r &= (u.l[0] == 128); +#endif +#if defined(LZO_UNALIGNED_OK_2) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_ushortp) (p+1)) == 0); +#endif +#if defined(LZO_UNALIGNED_OK_4) + p = (lzo_uintptr_t) (const lzo_voidp) &u.c[0]; + u.l[0] = u.l[1] = 0; + r &= ((* (const lzo_uint32p) (p+1)) == 0); +#endif +#endif + + LZO_UNUSED(u); LZO_UNUSED(p); + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +int __lzo_init_done = 0; + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define ACC_WANT_ACC_CHK_CH 1 +#undef ACCCHK_ASSERT +#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef ACCCHK_ASSERT + + __lzo_init_done = 1; + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#define do_compress _lzo1x_1_do_compress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#define LZO_NEED_DICT_H +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#define LZO_EOF_CODE +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 8 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 8 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +static void DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if defined(LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_uint) ((p)-(in))) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if defined(LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) <= 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if defined(LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define DO_COMPRESS lzo1x_1_compress + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + register const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - M2_MAX_LEN - 5; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += 4; + for (;;) + { + register const lzo_bytep m_pos; + lzo_uint m_off; + lzo_uint m_len; + lzo_uint dindex; + + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } + else + { + if __lzo_likely(m_pos[2] == ip[2]) + { +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) + { + assert(op - 2 > out); op[-2] |= LZO_BYTE(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (m_pos[3] == ip[3]) +#endif + goto match; + } + else + { +#if 0 +#if 0 + if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else + if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif + { + register lzo_uint t; + + t = lit; + assert(op - 2 > out); op[-2] |= LZO_BYTE(t); + do *op++ = *ii++; while (--t > 0); + assert(ii == ip); + m_off -= 1; + *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); + ip += 2; + goto match_done; + } +#endif + } + } + +literal: + UPDATE_I(dict,0,dindex,ip,in); + ++ip; + if __lzo_unlikely(ip >= ip_end) + break; + continue; + +match: + UPDATE_I(dict,0,dindex,ip,in); + if (pd(ip,ii) > 0) + { + register lzo_uint t = pd(ip,ii); + + if (t <= 3) + { + assert(op - 2 > out); + op[-2] |= LZO_BYTE(t); + } + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + register lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + assert(ii == ip); + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ || + m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y + || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ + || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif + ) + { + --ip; + m_len = pd(ip, ii); + assert(m_len >= 3); assert(m_len <= M2_MAX_LEN); + + if (m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } + else +#if defined(LZO1X) + { + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + goto m3_m4_offset; + } +#elif defined(LZO1Y) + goto m4_match; +#endif + } + else + { + { + const lzo_bytep end = in_end; + const lzo_bytep m = m_pos + M2_MAX_LEN + 1; + while (ip < end && *m == *ip) + m++, ip++; + m_len = pd(ip, ii); + } + assert(m_len > M2_MAX_LEN); + + if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= 33) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } + else + { +#if defined(LZO1Y) +m4_match: +#endif + m_off -= 0x4000; + assert(m_off > 0); assert(m_off <= 0x7fff); + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | + ((m_off & 0x4000) >> 11) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11)); +m3_m4_len: + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = LZO_BYTE(m_len); + } + } + +m3_m4_offset: + *op++ = LZO_BYTE((m_off & 63) << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + +#if 0 +match_done: +#endif + ii = ip; + if __lzo_unlikely(ip >= ip_end) + break; + } + + *out_len = pd(op, out); + return pd(in_end,ii); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + lzo_bytep op = out; + lzo_uint t; + + if __lzo_unlikely(in_len <= M2_MAX_LEN + 5) + t = in_len; + else + { + t = do_compress(in,in_len,op,out_len,wrkmem); + op += *out_len; + } + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] |= LZO_BYTE(t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP +#else +# define TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP +#else +# define NEED_IP(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP +#else +# define NEED_OP(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP +#endif + +#undef __COPY4 +#define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src) + +#undef COPY4 +#if defined(LZO_UNALIGNED_OK_4) +# define COPY4(dst,src) __COPY4(dst,src) +#elif defined(LZO_ALIGNED_OK_4) +# define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src)) +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + register lzo_bytep op; + register const lzo_bytep ip; + register lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + register const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) + { + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !defined(LZO_UNALIGNED_OK_4) + } + else +#endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + do { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + NEED_IP(1); + while (*ip == 0) + { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +#if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +#endif + +eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ + diff --git a/bundles/n2n_ntop_v2/src/n2n.c b/bundles/n2n_ntop_v2/src/n2n.c new file mode 100644 index 00000000..7c8109e5 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/n2n.c @@ -0,0 +1,468 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#include "minilzo.h" + +#include + + +static const uint8_t broadcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const uint8_t multicast_addr[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */ +static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */ + +/* ************************************** */ + +SOCKET open_socket(int local_port, int bind_any) { + SOCKET sock_fd; + struct sockaddr_in local_address; + int sockopt; + + if((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", + strerror(errno), sock_fd); + return(-1); + } + +#ifndef WIN32 + /* fcntl(sock_fd, F_SETFL, O_NONBLOCK); */ +#endif + + sockopt = 1; + setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); + + memset(&local_address, 0, sizeof(local_address)); + local_address.sin_family = AF_INET; + local_address.sin_port = htons(local_port); + local_address.sin_addr.s_addr = htonl(bind_any ? INADDR_ANY : INADDR_LOOPBACK); + + if(bind(sock_fd,(struct sockaddr*) &local_address, sizeof(local_address)) == -1) { + traceEvent(TRACE_ERROR, "Bind error on local port %u [%s]\n", local_port, strerror(errno)); + return(-1); + } + + return(sock_fd); +} + +static int traceLevel = 2 /* NORMAL */; +static int useSyslog = 0, syslog_opened = 0; +static FILE *traceFile = NULL; + +int getTraceLevel() { + return(traceLevel); +} + +void setTraceLevel(int level) { + traceLevel = level; +} + +void setUseSyslog(int use_syslog) { + useSyslog= use_syslog; +} + +void setTraceFile(FILE *f) { + traceFile = f; +} + +void closeTraceFile() { + if (traceFile != NULL && traceFile != stdout) { + fclose(traceFile); + } +#ifndef WIN32 + if (useSyslog && syslog_opened) { + closelog(); + syslog_opened = 0; + } +#endif +} + +#define N2N_TRACE_DATESIZE 32 +void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...) { + va_list va_ap; + + if(traceFile == NULL) + traceFile = stdout; + + if(eventTraceLevel <= traceLevel) { + char buf[1024]; + char out_buf[1280]; + char theDate[N2N_TRACE_DATESIZE]; + char *extra_msg = ""; + time_t theTime = time(NULL); + int i; + + /* We have two paths - one if we're logging, one if we aren't + * Note that the no-log case is those systems which don't support it(WIN32), + * those without the headers !defined(USE_SYSLOG) + * those where it's parametrically off... + */ + + memset(buf, 0, sizeof(buf)); + strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); + + va_start(va_ap, format); + vsnprintf(buf, sizeof(buf)-1, format, va_ap); + va_end(va_ap); + + if(eventTraceLevel == 0 /* TRACE_ERROR */) + extra_msg = "ERROR: "; + else if(eventTraceLevel == 1 /* TRACE_WARNING */) + extra_msg = "WARNING: "; + + while(buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + +#ifndef WIN32 + if(useSyslog) { + if(!syslog_opened) { + openlog("n2n", LOG_PID, LOG_DAEMON); + syslog_opened = 1; + } + + snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); + syslog(LOG_INFO, "%s", out_buf); + } else { + for(i=strlen(file)-1; i>0; i--) if(file[i] == '/') { i++; break; }; + snprintf(out_buf, sizeof(out_buf), "%s [%s:%d] %s%s", theDate, &file[i], line, extra_msg, buf); + fprintf(traceFile, "%s\n", out_buf); + fflush(traceFile); + } +#else + /* this is the WIN32 code */ + for(i=strlen(file)-1; i>0; i--) if(file[i] == '\\') { i++; break; }; + snprintf(out_buf, sizeof(out_buf), "%s [%s:%d] %s%s", theDate, &file[i], line, extra_msg, buf); + fprintf(traceFile, "%s\n", out_buf); + fflush(traceFile); +#endif + } + +} + +/* *********************************************** */ + +/* addr should be in network order. Things are so much simpler that way. */ +char* intoa(uint32_t /* host order */ addr, char* buf, uint16_t buf_len) { + char *cp, *retStr; + uint8_t byteval; + int n; + + cp = &buf[buf_len]; + *--cp = '\0'; + + n = 4; + do { + byteval = addr & 0xff; + *--cp = byteval % 10 + '0'; + byteval /= 10; + if(byteval > 0) { + *--cp = byteval % 10 + '0'; + byteval /= 10; + if(byteval > 0) + *--cp = byteval + '0'; + } + *--cp = '.'; + addr >>= 8; + } while(--n > 0); + + /* Convert the string to lowercase */ + retStr =(char*)(cp+1); + + return(retStr); +} + +/* *********************************************** */ + +char * macaddr_str(macstr_t buf, + const n2n_mac_t mac) +{ + snprintf(buf, N2N_MACSTR_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0] & 0xFF, mac[1] & 0xFF, mac[2] & 0xFF, + mac[3] & 0xFF, mac[4] & 0xFF, mac[5] & 0xFF); + return(buf); +} + +/* *********************************************** */ + +uint8_t is_multi_broadcast(const uint8_t * dest_mac) { + + int is_broadcast =(memcmp(broadcast_addr, dest_mac, 6) == 0); + int is_multicast =(memcmp(multicast_addr, dest_mac, 3) == 0); + int is_ipv6_multicast =(memcmp(ipv6_multicast_addr, dest_mac, 2) == 0); + + return is_broadcast || is_multicast || is_ipv6_multicast; + +} + +/* http://www.faqs.org/rfcs/rfc908.html */ + + +/* *********************************************** */ + +char* msg_type2str(uint16_t msg_type) { + switch(msg_type) { + case MSG_TYPE_REGISTER: return("MSG_TYPE_REGISTER"); + case MSG_TYPE_DEREGISTER: return("MSG_TYPE_DEREGISTER"); + case MSG_TYPE_PACKET: return("MSG_TYPE_PACKET"); + case MSG_TYPE_REGISTER_ACK: return("MSG_TYPE_REGISTER_ACK"); + case MSG_TYPE_REGISTER_SUPER: return("MSG_TYPE_REGISTER_SUPER"); + case MSG_TYPE_REGISTER_SUPER_ACK: return("MSG_TYPE_REGISTER_SUPER_ACK"); + case MSG_TYPE_REGISTER_SUPER_NAK: return("MSG_TYPE_REGISTER_SUPER_NAK"); + case MSG_TYPE_FEDERATION: return("MSG_TYPE_FEDERATION"); + default: return("???"); + } + + return("???"); +} + +/* *********************************************** */ + +void hexdump(const uint8_t * buf, size_t len) +{ + size_t i; + + if(0 == len) { return; } + + for(i=0; i 0) &&((i % 16) == 0)) { printf("\n"); } + printf("%02X ", buf[i] & 0xFF); + } + + printf("\n"); +} + +/* *********************************************** */ + +void print_n2n_version() { + printf("Welcome to n2n v.%s for %s\n" + "Built on %s\n" + "Copyright 2007-2020 - ntop.org and contributors\n\n", + GIT_RELEASE, PACKAGE_OSNAME, PACKAGE_BUILDDATE); +} + +/* *********************************************** */ + +size_t purge_expired_registrations(struct peer_info ** peer_list, time_t* p_last_purge) { + time_t now = time(NULL); + size_t num_reg = 0; + + if((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) return 0; + + traceEvent(TRACE_DEBUG, "Purging old registrations"); + + num_reg = purge_peer_list(peer_list, now-REGISTRATION_TIMEOUT); + + (*p_last_purge) = now; + traceEvent(TRACE_DEBUG, "Remove %ld registrations", num_reg); + + return num_reg; +} + +/** Purge old items from the peer_list and return the number of items that were removed. */ +size_t purge_peer_list(struct peer_info ** peer_list, + time_t purge_before) +{ + struct peer_info *scan, *tmp; + size_t retval=0; + + HASH_ITER(hh, *peer_list, scan, tmp) { + if(scan->last_seen < purge_before) { + HASH_DEL(*peer_list, scan); + retval++; + free(scan); + } + } + + return retval; +} + +/** Purge all items from the peer_list and return the number of items that were removed. */ +size_t clear_peer_list(struct peer_info ** peer_list) +{ + struct peer_info *scan, *tmp; + size_t retval=0; + + HASH_ITER(hh, *peer_list, scan, tmp) { + HASH_DEL(*peer_list, scan); + retval++; + free(scan); + } + + return retval; +} + +static uint8_t hex2byte(const char * s) +{ + char tmp[3]; + tmp[0]=s[0]; + tmp[1]=s[1]; + tmp[2]=0; /* NULL term */ + + return((uint8_t)strtol(tmp, NULL, 16)); +} + +extern int str2mac(uint8_t * outmac /* 6 bytes */, const char * s) +{ + size_t i; + + /* break it down as one case for the first "HH", the 5 x through loop for + * each ":HH" where HH is a two hex nibbles in ASCII. */ + + *outmac=hex2byte(s); + ++outmac; + s+=2; /* don't skip colon yet - helps generalise loop. */ + + for(i=1; i<6; ++i) + { + s+=1; + *outmac=hex2byte(s); + ++outmac; + s+=2; + } + + return 0; /* ok */ +} + +extern char * sock_to_cstr(n2n_sock_str_t out, + const n2n_sock_t * sock) { + if(NULL == out) { return NULL; } + memset(out, 0, N2N_SOCKBUF_SIZE); + + if(AF_INET6 == sock->family) { + /* INET6 not written yet */ + snprintf(out, N2N_SOCKBUF_SIZE, "XXXX:%hu", sock->port); + return out; + } else { + const uint8_t * a = sock->addr.v4; + + snprintf(out, N2N_SOCKBUF_SIZE, "%hu.%hu.%hu.%hu:%hu", + (unsigned short)(a[0] & 0xff), + (unsigned short)(a[1] & 0xff), + (unsigned short)(a[2] & 0xff), + (unsigned short)(a[3] & 0xff), + (unsigned short)sock->port); + return out; + } +} + +/* @return 1 if the two sockets are equivalent. */ +int sock_equal(const n2n_sock_t * a, + const n2n_sock_t * b) { + if(a->port != b->port) { return(0); } + if(a->family != b->family) { return(0); } + + switch(a->family) { + case AF_INET: + if(memcmp(a->addr.v4, b->addr.v4, IPV4_SIZE)) + return(0); + break; + default: + if(memcmp(a->addr.v6, b->addr.v6, IPV6_SIZE)) + return(0); + break; + } + + /* equal */ + return(1); +} + +/* *********************************************** */ + +#if defined(WIN32) && !defined(__GNUC__) +int gettimeofday(struct timeval *tp, void *tzp) { + time_t clock; + struct tm tm; + SYSTEMTIME wtm; + GetLocalTime(&wtm); + tm.tm_year = wtm.wYear - 1900; + tm.tm_mon = wtm.wMonth - 1; + tm.tm_mday = wtm.wDay; + tm.tm_hour = wtm.wHour; + tm.tm_min = wtm.wMinute; + tm.tm_sec = wtm.wSecond; + tm.tm_isdst = -1; + clock = mktime(&tm); + tp->tv_sec = clock; + tp->tv_usec = wtm.wMilliseconds * 1000; + return (0); +} +#endif + + +// returns a time stamp for use with replay protection +uint64_t time_stamp (void) { + + struct timeval tod; + uint64_t micro_seconds; + + gettimeofday (&tod, NULL); + /* We will (roughly) calculate the microseconds since 1970 leftbound into the return value. + The leading 32 bits are used for tv_sec. The following 20 bits (sufficent as microseconds + fraction never exceeds 1,000,000,) encode the value tv_usec. The remaining lowest 12 bits + are kept random for use in IV */ + micro_seconds = n2n_rand(); + micro_seconds = ( (((uint64_t)(tod.tv_sec) << 32) + (tod.tv_usec << 12)) + | (micro_seconds >> 52) ); + // more exact but more costly due to the multiplication: + // micro_seconds = (tod.tv_sec * 1000000 + tod.tv_usec) << 12) | ... + + return (micro_seconds); +} + + +// returns an initial time stamp for use with replay protection +uint64_t initial_time_stamp (void) { + + return ( time_stamp() - TIME_STAMP_FRAME ); +} + + +// checks if a provided time stamp is consistent with current time and previously valid time stamps +// and, in case of validity, updates the "last valid time stamp" +int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp) { + + int64_t diff; // do not change to unsigned + + // is it around current time (+/- allowed deviation TIME_STAMP_FRAME)? + diff = stamp - time_stamp(); + // abs() + diff = (diff < 0 ? -diff : diff); + if(diff >= TIME_STAMP_FRAME) { + traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp out of allowed frame."); + return (0); // failure + } + + // if applicable: is it higher than previous time stamp (including allowed deviation of TIME_STAMP_JITTER)? + if(NULL != previous_stamp) { + // if no jitter allowed, reset lowest three (random) nybbles; the codnition shoudl already be evaluated by the compiler + if(TIME_STAMP_JITTER == 0) { + stamp = (stamp >> 12) << 12; + *previous_stamp = (*previous_stamp >> 12) << 12; + } + diff = stamp - *previous_stamp + TIME_STAMP_JITTER; + if(diff <= 0) { + traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp too old compared to previous."); + return (0); // failure + } + // for not allowing to exploit the allowed TIME_STAMP_JITTER to "turn the clock backwards", + // set the higher of the values + *previous_stamp = (stamp > *previous_stamp ? stamp : *previous_stamp); + } + + return (1); // success +} diff --git a/bundles/n2n_ntop_v2/src/pearson.c b/bundles/n2n_ntop_v2/src/pearson.c new file mode 100644 index 00000000..a515b521 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/pearson.c @@ -0,0 +1,338 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +// taken from https://github.com/Logan007/pearson +// This is free and unencumbered software released into the public domain. + +#include +#include + +#include "pearson.h" + +// compile with 'LOW_MEM_FOOTPRINT' defined to make use of 256 byte look-up tabe only +// otherwise, a 16-bit look-up table is used which allows considerably faster hashing +// however, it needs to be generated by once calling pearson_hash_init() upfront +// #define LOW_MEM_FOOTPRINT + +// table as in original paper "Fast Hashing of Variable-Length Text Strings" by Peter K. Pearson +// as published in The Communications of the ACM Vol.33, No. 6 (June 1990), pp. 677-680. +static const uint8_t t[256] ={ + 0x01, 0x57, 0x31, 0x0c, 0xb0, 0xb2, 0x66, 0xa6, 0x79, 0xc1, 0x06, 0x54, 0xf9, 0xe6, 0x2c, 0xa3, + 0x0e, 0xc5, 0xd5, 0xb5, 0xa1, 0x55, 0xda, 0x50, 0x40, 0xef, 0x18, 0xe2, 0xec, 0x8e, 0x26, 0xc8, + 0x6e, 0xb1, 0x68, 0x67, 0x8d, 0xfd, 0xff, 0x32, 0x4d, 0x65, 0x51, 0x12, 0x2d, 0x60, 0x1f, 0xde, + 0x19, 0x6b, 0xbe, 0x46, 0x56, 0xed, 0xf0, 0x22, 0x48, 0xf2, 0x14, 0xd6, 0xf4, 0xe3, 0x95, 0xeb, + 0x61, 0xea, 0x39, 0x16, 0x3c, 0xfa, 0x52, 0xaf, 0xd0, 0x05, 0x7f, 0xc7, 0x6f, 0x3e, 0x87, 0xf8, + 0xae, 0xa9, 0xd3, 0x3a, 0x42, 0x9a, 0x6a, 0xc3, 0xf5, 0xab, 0x11, 0xbb, 0xb6, 0xb3, 0x00, 0xf3, + 0x84, 0x38, 0x94, 0x4b, 0x80, 0x85, 0x9e, 0x64, 0x82, 0x7e, 0x5b, 0x0d, 0x99, 0xf6, 0xd8, 0xdb, + 0x77, 0x44, 0xdf, 0x4e, 0x53, 0x58, 0xc9, 0x63, 0x7a, 0x0b, 0x5c, 0x20, 0x88, 0x72, 0x34, 0x0a, + 0x8a, 0x1e, 0x30, 0xb7, 0x9c, 0x23, 0x3d, 0x1a, 0x8f, 0x4a, 0xfb, 0x5e, 0x81, 0xa2, 0x3f, 0x98, + 0xaa, 0x07, 0x73, 0xa7, 0xf1, 0xce, 0x03, 0x96, 0x37, 0x3b, 0x97, 0xdc, 0x5a, 0x35, 0x17, 0x83, + 0x7d, 0xad, 0x0f, 0xee, 0x4f, 0x5f, 0x59, 0x10, 0x69, 0x89, 0xe1, 0xe0, 0xd9, 0xa0, 0x25, 0x7b, + 0x76, 0x49, 0x02, 0x9d, 0x2e, 0x74, 0x09, 0x91, 0x86, 0xe4, 0xcf, 0xd4, 0xca, 0xd7, 0x45, 0xe5, + 0x1b, 0xbc, 0x43, 0x7c, 0xa8, 0xfc, 0x2a, 0x04, 0x1d, 0x6c, 0x15, 0xf7, 0x13, 0xcd, 0x27, 0xcb, + 0xe9, 0x28, 0xba, 0x93, 0xc6, 0xc0, 0x9b, 0x21, 0xa4, 0xbf, 0x62, 0xcc, 0xa5, 0xb4, 0x75, 0x4c, + 0x8c, 0x24, 0xd2, 0xac, 0x29, 0x36, 0x9f, 0x08, 0xb9, 0xe8, 0x71, 0xc4, 0xe7, 0x2f, 0x92, 0x78, + 0x33, 0x41, 0x1c, 0x90, 0xfe, 0xdd, 0x5d, 0xbd, 0xc2, 0x8b, 0x70, 0x2b, 0x47, 0x6d, 0xb8, 0xd1 }; + +/* +// alternative table as used in RFC 3074 and NOT as in original paper +static const uint8_t t[256] ={ +0xfb, 0xaf, 0x77, 0xd7, 0x51, 0x0e, 0x4f, 0xbf, 0x67, 0x31, 0xb5, 0x8f, 0xba, 0x9d, 0x00, 0xe8, +0x1f, 0x20, 0x37, 0x3c, 0x98, 0x3a, 0x11, 0xed, 0xae, 0x46, 0xa0, 0x90, 0xdc, 0x5a, 0x39, 0xdf, +0x3b, 0x03, 0x12, 0x8c, 0x6f, 0xa6, 0xcb, 0xc4, 0x86, 0xf3, 0x7c, 0x5f, 0xde, 0xb3, 0xc5, 0x41, +0xb4, 0x30, 0x24, 0x0f, 0x6b, 0x2e, 0xe9, 0x82, 0xa5, 0x1e, 0x7b, 0xa1, 0xd1, 0x17, 0x61, 0x10, +0x28, 0x5b, 0xdb, 0x3d, 0x64, 0x0a, 0xd2, 0x6d, 0xfa, 0x7f, 0x16, 0x8a, 0x1d, 0x6c, 0xf4, 0x43, +0xcf, 0x09, 0xb2, 0xcc, 0x4a, 0x62, 0x7e, 0xf9, 0xa7, 0x74, 0x22, 0x4d, 0xc1, 0xc8, 0x79, 0x05, +0x14, 0x71, 0x47, 0x23, 0x80, 0x0d, 0xb6, 0x5e, 0x19, 0xe2, 0xe3, 0xc7, 0x4b, 0x1b, 0x29, 0xf5, +0xe6, 0xe0, 0x2b, 0xe1, 0xb1, 0x1a, 0x9b, 0x96, 0xd4, 0x8e, 0xda, 0x73, 0xf1, 0x49, 0x58, 0x69, +0x27, 0x72, 0x3e, 0xff, 0xc0, 0xc9, 0x91, 0xd6, 0xa8, 0x9e, 0xdd, 0x94, 0x9a, 0x7a, 0x0c, 0x54, +0x52, 0xa3, 0x2c, 0x8b, 0xe4, 0xec, 0xcd, 0xf2, 0xd9, 0x0b, 0xbb, 0x92, 0x9f, 0x40, 0x56, 0xef, +0xc3, 0x2a, 0x6a, 0xc6, 0x76, 0x70, 0xb8, 0xac, 0x57, 0x02, 0xad, 0x75, 0xb0, 0xe5, 0xf7, 0xfd, +0x89, 0xb9, 0x63, 0xa4, 0x66, 0x93, 0x2d, 0x42, 0xe7, 0x34, 0x8d, 0xd3, 0xc2, 0xce, 0xf6, 0xee, +0x38, 0x6e, 0x4e, 0xf8, 0x3f, 0xf0, 0xbd, 0x5d, 0x5c, 0x33, 0x35, 0xb7, 0x13, 0xab, 0x48, 0x32, +0x21, 0x68, 0x65, 0x45, 0x08, 0xfc, 0x53, 0x78, 0x4c, 0x87, 0x55, 0x36, 0xca, 0x7d, 0xbc, 0xd5, +0x60, 0xeb, 0x88, 0xd0, 0xa2, 0x81, 0xbe, 0x84, 0x9c, 0x26, 0x2f, 0x01, 0x07, 0xfe, 0x18, 0x04, +0xd8, 0x83, 0x59, 0x15, 0x1c, 0x85, 0x25, 0x99, 0x95, 0x50, 0xaa, 0x44, 0x06, 0xa9, 0xea, 0x97 }; */ + + +#ifndef LOW_MEM_FOOTPRINT +static uint16_t t16[65536]; // 16-bit look-up table +#endif + +#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) +#define ROR32(x,r) (((x)>>(r))|((x)<<(32-(r)))) + + +void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len) { + + size_t i; + /* initial values - astonishingly, assembling using SHIFTs and ORs (in register) + * works faster on well pipelined CPUs than loading the 64-bit value from memory. + * however, there is one advantage to loading from memory: as we also store back to + * memory at the end, we do not need to care about endianess! */ + uint8_t upper[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + uint8_t lower[8] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; + + uint64_t upper_hash_mask = *(uint64_t*)&upper; + uint64_t lower_hash_mask = *(uint64_t*)&lower; + uint64_t high_upper_hash_mask = upper_hash_mask + 0x1010101010101010; + uint64_t high_lower_hash_mask = lower_hash_mask + 0x1010101010101010; + + uint64_t upper_hash = 0; + uint64_t lower_hash = 0; + uint64_t high_upper_hash = 0; + uint64_t high_lower_hash = 0; + + for (i = 0; i < len; i++) { + // broadcast the character, xor into hash, make them different permutations + uint64_t c = (uint8_t)in[i]; + c |= c << 8; + c |= c << 16; + c |= c << 32; + upper_hash ^= c ^ upper_hash_mask; + lower_hash ^= c ^ lower_hash_mask; + high_upper_hash ^= c ^ high_upper_hash_mask; + high_lower_hash ^= c ^ high_lower_hash_mask; + + // table lookup + uint64_t h = 0; +#ifdef LOW_MEM_FOOTPRINT // 256 byte look-up table ---------- + uint8_t x; + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + upper_hash = h; + + h = 0; + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + lower_hash = h; + + h = 0; + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_upper_hash; x = t[x]; high_upper_hash >>= 8; h |= x; h=ROR64(h,8); + high_upper_hash = h; + + h = 0; + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = high_lower_hash; x = t[x]; high_lower_hash >>= 8; h |= x; h=ROR64(h,8); + high_lower_hash = h; +#else // 16-bit look-up table ------------------------------- + uint16_t x; + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + upper_hash = h; + + h = 0; + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + lower_hash = h; + + h = 0; + x = high_upper_hash; x = t16[x]; high_upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_upper_hash; x = t16[x]; high_upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_upper_hash; x = t16[x]; high_upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_upper_hash; x = t16[x]; high_upper_hash >>= 16; h |= x; h=ROR64(h,16); + high_upper_hash = h; + + h = 0; + x = high_lower_hash; x = t16[x]; high_lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_lower_hash; x = t16[x]; high_lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_lower_hash; x = t16[x]; high_lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = high_lower_hash; x = t16[x]; high_lower_hash >>= 16; h |= x; h=ROR64(h,16); + high_lower_hash = h; +#endif // LOW_MEM_FOOTPRINT ------ + } + // store output + uint64_t *o; + o = (uint64_t*)&out[0]; + *o = high_upper_hash; + o = (uint64_t*)&out[8]; + *o = high_lower_hash; + o = (uint64_t*)&out[16]; + *o = upper_hash; + o = (uint64_t*)&out[24]; + *o = lower_hash; +} + + +void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len) { + + size_t i; + /* initial values - astonishingly, assembling using SHIFTs and ORs (in register) + * works faster on well pipelined CPUs than loading the 64-bit value from memory. + * however, there is one advantage to loading from memory: as we also store back to + * memory at the end, we do not need to care about endianess! */ + uint8_t upper[8] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + uint8_t lower[8] = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 }; + + uint64_t upper_hash_mask = *(uint64_t*)&upper; + uint64_t lower_hash_mask = *(uint64_t*)&lower; + + uint64_t upper_hash = 0; + uint64_t lower_hash = 0; + + for (i = 0; i < len; i++) { + // broadcast the character, xor into hash, make them different permutations + uint64_t c = (uint8_t)in[i]; + c |= c << 8; + c |= c << 16; + c |= c << 32; + upper_hash ^= c ^ upper_hash_mask; + lower_hash ^= c ^ lower_hash_mask; + // table lookup + uint64_t h = 0; +#ifdef LOW_MEM_FOOTPRINT // 256 byte look-up table ---------- + uint8_t x; + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + x = upper_hash; x = t[x]; upper_hash >>= 8; h |= x; h=ROR64(h,8); + upper_hash = h; + + h = 0; + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + x = lower_hash; x = t[x]; lower_hash >>= 8; h |= x; h=ROR64(h,8); + lower_hash= h; +#else // 16-bit look-up table ------------------------------- + uint16_t x; + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + x = upper_hash; x = t16[x]; upper_hash >>= 16; h |= x; h=ROR64(h,16); + upper_hash = h; + + h = 0; + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + x = lower_hash; x = t16[x]; lower_hash >>= 16; h |= x; h=ROR64(h,16); + lower_hash = h; +#endif // LOW_MEM_FOOTPRINT ------ + } + // store output + uint64_t *o; + o = (uint64_t*)&out[0]; + *o = upper_hash; + o = (uint64_t*)&out[8]; + *o = lower_hash; +} + +/* --- for later use --- +// 32-bit hash: the return value has to be interpreted as uint32_t and +// follows machine-specific endianess in memory +uint32_t pearson_hash_32 (const uint8_t *in, size_t len) { + + size_t i; + uint32_t hash = 0; + uint32_t hash_mask = 0x03020100; + + for (i = 0; i < len; i++) { + // broadcast the character, xor into hash, make them different permutations + uint32_t c = (uint8_t)in[i]; + c |= c << 8; + c |= c << 16; + hash ^= c ^ hash_mask; + // table lookup +#ifdef LOW_MEM_FOOTPRINT + uint32_t h = 0; + uint8_t x; + x = hash; x = t[x]; hash >>= 8; h |= x; h=ROR32(h,8); + x = hash; x = t[x]; hash >>= 8; h |= x; h=ROR32(h,8); + x = hash; x = t[x]; hash >>= 8; h |= x; h=ROR32(h,8); + x = hash; x = t[x]; hash >>= 8; h |= x; h=ROR32(h,8); + hash = h; +#else + hash = (t16[hash >> 16] << 16) + t16[(uint16_t)hash]; +#endif + } + // output + return hash; +} --- pearson_hash_32 for later use --- */ + + +// 16-bit hash: the return value has to be interpreted as uint16_t and +// follows machine-specific endianess in memory +uint16_t pearson_hash_16 (const uint8_t *in, size_t len) { + size_t i; + uint16_t hash = 0; + uint16_t hash_mask = 0x0100; + + for (i = 0; i < len; i++) { + // broadcast the character, xor into hash, make them different permutations + uint16_t c = (uint8_t)in[i]; + c |= c << 8; + hash ^= c ^ hash_mask; + // table lookup +#ifdef LOW_MEM_FOOTPRINT + hash = t[(uint8_t)hash] + (t[hash >> 8] << 8); +#else + hash = t16[hash]; +#endif + } + // output + return hash; +} + + +void pearson_hash_init () { + +#ifndef LOW_MEM_FOOTPRINT + size_t i; + + for (i = 0; i < 65536; i++) + t16[i] = (t[i >> 8] << 8) + t[(uint8_t)i]; +#endif +} diff --git a/bundles/n2n_ntop_v2/src/random_numbers.c b/bundles/n2n_ntop_v2/src/random_numbers.c new file mode 100644 index 00000000..aa98fb87 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/random_numbers.c @@ -0,0 +1,176 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifdef SYS_getrandom +#include +#endif + +#include "n2n.h" + + +/* The following code offers an alterate pseudo random number generator + namely XORSHIFT128+ to use instead of C's rand(). Its performance is + on par with C's rand(). +*/ + + +/* The state must be seeded in a way that it is not all zero, choose some + arbitrary defaults (in this case: taken from splitmix64) */ +static struct rn_generator_state_t rn_current_state = { + .a = 0x9E3779B97F4A7C15, + .b = 0xBF58476D1CE4E5B9 }; + + +/* used for mixing the initializing seed */ +static uint64_t splitmix64 (struct splitmix64_state_t *state) { + + uint64_t result = state->s; + + state->s = result + 0x9E3779B97F4A7C15; + + result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9; + result = (result ^ (result >> 27)) * 0x94D049BB133111EB; + + return result ^ (result >> 31); +} + + +int n2n_srand (uint64_t seed) { + uint8_t i; + struct splitmix64_state_t smstate = {seed}; + + rn_current_state.a = 0; + rn_current_state.b = 0; + + rn_current_state.a = splitmix64 (&smstate); + rn_current_state.b = splitmix64 (&smstate); + + /* the following lines could be deleted as soon as it is formally prooved that + there is no seed leading to (a == b == 0). Until then, just to be safe: */ + if ( (rn_current_state.a == 0) && (rn_current_state.b == 0) ) { + rn_current_state.a = 0x9E3779B97F4A7C15; + rn_current_state.b = 0xBF58476D1CE4E5B9; + } + + /* stabilize in unlikely case of weak state with only a few bits set */ + for(i = 0; i < 32; i++) + n2n_rand(); + + return 0; +} + + +/* The following code of xorshift128p was taken from + https://en.wikipedia.org/wiki/Xorshift as of July, 2019 + and thus is considered public domain. */ +uint64_t n2n_rand () { + + uint64_t t = rn_current_state.a; + uint64_t const s = rn_current_state.b; + + rn_current_state.a = s; + t ^= t << 23; + t ^= t >> 17; + t ^= s ^ (s >> 26); + rn_current_state.b = t; + + return t + s; +} + + +/* The following code tries to gather some entropy from several sources + for use as seed. Note, that this code does not set the random generator + state yet, a call to n2n_srand ( n2n_seed() ) would do. */ +uint64_t n2n_seed (void) { + + uint64_t seed = 0; + uint64_t ret = 0; + size_t i; + +#ifdef SYS_getrandom + int rc = -1; + for(i = 0; (i < RND_RETRIES) && (rc != sizeof(seed)); i++) { + rc = syscall (SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK); + // if successful, rc should contain the requested number of random bytes + if(rc != sizeof(seed)) { + if (errno != EAGAIN) { + traceEvent(TRACE_ERROR, "n2n_seed faced error errno=%u from getrandom syscall.", errno); + break; + } + } + } + // if we still see an EAGAIN error here, we must have run out of retries + if(errno == EAGAIN) { + traceEvent(TRACE_ERROR, "n2n_seed saw getrandom syscall indicate not being able to provide enough entropy yet."); + } +#endif + + // as we want randomness, it does no harm to add up even uninitialized values or + // erroneously arbitrary values returned from the syscall for the first time + ret += seed; + + // __RDRND__ is set only if architecturual feature is set, e.g. compile with -march=native +#ifdef __RDRND__ + for(i = 0; i < RND_RETRIES; i++) { + if(_rdrand64_step ((unsigned long long*)&seed)) { + // success! + // from now on, we keep this inside the loop because in case of failure + // and with unchanged values, we do not want to double the previous value + ret += seed; + break; + } + // continue loop to try again otherwise + } + if(i == RND_RETRIES){ + traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDRND."); + } +#endif + + // __RDSEED__ ist set only if architecturual feature is set, e.g. compile with -march=native +#ifdef __RDSEED__ + for(i = 0; i < RND_RETRIES; i++) { + if(_rdseed64_step((unsigned long long*)&seed)) { + // success! + ret += seed; + break; + } + // continue loop to try again otherwise + } + if(i == RND_RETRIES){ + traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDSEED."); + } +#endif + + /* The WIN32 code is still untested and thus commented + #ifdef WIN32 + HCRYPTPROV crypto_provider; + CryptAcquireContext (&crypto_provider, NULL, (LPCWSTR)L"Microsoft Base Cryptographic Provider v1.0", + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptGenRandom (crypto_provider, 8, &seed); + CryptReleaseContext (crypto_provider, 0); + ret += seed; + #endif */ + + seed = time(NULL); /* UTC in seconds */ + ret += seed; + + seed = clock() * 18444244737; /* clock() = ticks since program start */ + ret += seed; + + return ret; +} diff --git a/bundles/n2n_ntop_v2/src/sn.c b/bundles/n2n_ntop_v2/src/sn.c new file mode 100644 index 00000000..4087152a --- /dev/null +++ b/bundles/n2n_ntop_v2/src/sn.c @@ -0,0 +1,442 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* Supernode for n2n-2.x */ + +#include "n2n.h" +#include "header_encryption.h" + +static n2n_sn_t sss_node; + +/** Load the list of allowed communities. Existing/previous ones will be removed + * + */ +static int load_allowed_sn_community(n2n_sn_t *sss, char *path) { + char buffer[4096], *line; + FILE *fd = fopen(path, "r"); + struct sn_community *s, *tmp; + uint32_t num_communities = 0; + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "File %s not found", path); + return -1; + } + + HASH_ITER(hh, sss->communities, s, tmp) { + HASH_DEL(sss->communities, s); + if (NULL != s->header_encryption_ctx) + free (s->header_encryption_ctx); + free(s); + } + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + int len = strlen(line); + + if((len < 2) || line[0] == '#') + continue; + + len--; + while(len > 0) { + if((line[len] == '\n') || (line[len] == '\r')) { + line[len] = '\0'; + len--; + } else + break; + } + + s = (struct sn_community*)calloc(1,sizeof(struct sn_community)); + + if(s != NULL) { + strncpy((char*)s->community, line, N2N_COMMUNITY_SIZE-1); + s->community[N2N_COMMUNITY_SIZE-1] = '\0'; + /* we do not know if header encryption is used in this community, + * first packet will show. just in case, setup the key. */ + s->header_encryption = HEADER_ENCRYPTION_UNKNOWN; + packet_header_setup_key (s->community, &(s->header_encryption_ctx), &(s->header_iv_ctx)); + HASH_ADD_STR(sss->communities, community, s); + + num_communities++; + traceEvent(TRACE_INFO, "Added allowed community '%s' [total: %u]", + (char*)s->community, num_communities); + } + } + + fclose(fd); + + traceEvent(TRACE_NORMAL, "Loaded %u communities from %s", + num_communities, path); + + /* No new communities will be allowed */ + sss->lock_communities = 1; + + return(0); +} + + +/* *************************************************** */ + +/** Help message to print if the command line arguments are not valid. */ +static void help() { + print_n2n_version(); + + printf("supernode (see supernode.conf)\n" + "or\n" + ); + printf("supernode "); + printf("-l "); + printf("-c "); +#if defined(N2N_HAVE_DAEMON) + printf("[-f] "); +#endif +#ifndef WIN32 + printf("[-u -g ] "); +#endif /* ifndef WIN32 */ + printf("[-t ] "); + printf("[-v] "); + printf("\n\n"); + + printf("-l \tSet UDP main listen port to \n"); + printf("-c \tFile containing the allowed communities.\n"); +#if defined(N2N_HAVE_DAEMON) + printf("-f \tRun in foreground.\n"); +#endif /* #if defined(N2N_HAVE_DAEMON) */ +#ifndef WIN32 + printf("-u \tUser ID (numeric) to use when privileges are dropped.\n"); + printf("-g \tGroup ID (numeric) to use when privileges are dropped.\n"); +#endif /* ifndef WIN32 */ + printf("-t \tManagement UDP Port (for multiple supernodes on a machine).\n"); + printf("-v \tIncrease verbosity. Can be used multiple times.\n"); + printf("-h \tThis help message.\n"); + printf("\n"); + + exit(1); +} + + +/* *************************************************** */ + +static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) { + //traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : ""); + + switch(optkey) { + case 'l': /* local-port */ + sss->lport = atoi(_optarg); + break; + + case 't': /* mgmt-port */ + sss->mport = atoi(_optarg); + break; + +#ifndef WIN32 + case 'u': /* unprivileged uid */ + sss->userid = atoi(_optarg); + break; + + case 'g': /* unprivileged uid */ + sss->groupid = atoi(_optarg); + break; +#endif + + case 'c': /* community file */ + load_allowed_sn_community(sss, _optarg); + break; + + case 'f': /* foreground */ + sss->daemon = 0; + break; + + case 'h': /* help */ + help(); + break; + + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + + default: + traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey); + return(-1); + } + + return(0); +} + +/* *********************************************** */ + +static const struct option long_options[] = { + { "communities", required_argument, NULL, 'c' }, + { "foreground", no_argument, NULL, 'f' }, + { "local-port", required_argument, NULL, 'l' }, + { "mgmt-port", required_argument, NULL, 't' }, + { "help" , no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +/* *************************************************** */ + +/* read command line options */ +static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) { + u_char c; + + while((c = getopt_long(argc, argv, "fl:u:g:t:c:vh", + long_options, NULL)) != '?') { + if(c == 255) break; + setOption(c, optarg, sss); + } + + return 0; +} + +/* *************************************************** */ + +static char *trim(char *s) { + char *end; + + while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) + s++; + + if(s[0] == 0) return s; + + end = &s[strlen(s) - 1]; + while(end > s + && (isspace(end[0])|| (end[0] == '"') || (end[0] == '\''))) + end--; + end[1] = 0; + + return s; +} + +/* *************************************************** */ + +/* parse the configuration file */ +static int loadFromFile(const char *path, n2n_sn_t *sss) { + char buffer[4096], *line, *key, *value; + u_int line_len, opt_name_len; + FILE *fd; + const struct option *opt; + + fd = fopen(path, "r"); + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "Config file %s not found", path); + return -1; + } + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + + line = trim(line); + value = NULL; + + if((line_len = strlen(line)) < 2 || line[0] == '#') + continue; + + if(!strncmp(line, "--", 2)) { /* long opt */ + key = &line[2], line_len -= 2; + + opt = long_options; + while(opt->name != NULL) { + opt_name_len = strlen(opt->name); + + if(!strncmp(key, opt->name, opt_name_len) + && (line_len <= opt_name_len + || key[opt_name_len] == '\0' + || key[opt_name_len] == ' ' + || key[opt_name_len] == '=')) { + if(line_len > opt_name_len) key[opt_name_len] = '\0'; + if(line_len > opt_name_len + 1) value = trim(&key[opt_name_len + 1]); + + // traceEvent(TRACE_NORMAL, "long key: %s value: %s", key, value); + setOption(opt->val, value, sss); + break; + } + + opt++; + } + } else if(line[0] == '-') { /* short opt */ + key = &line[1], line_len--; + if(line_len > 1) key[1] = '\0'; + if(line_len > 2) value = trim(&key[2]); + + // traceEvent(TRACE_NORMAL, "key: %c value: %s", key[0], value); + setOption(key[0], value, sss); + } else { + traceEvent(TRACE_WARNING, "Skipping unrecognized line: %s", line); + continue; + } + } + + fclose(fd); + + return 0; +} + +/* *************************************************** */ + +#ifdef __linux__ +static void dump_registrations(int signo) { + struct sn_community *comm, *ctmp; + struct peer_info *list, *tmp; + char buf[32]; + time_t now = time(NULL); + u_int num = 0; + + traceEvent(TRACE_NORMAL, "===================================="); + + HASH_ITER(hh, sss_node.communities, comm, ctmp) { + traceEvent(TRACE_NORMAL, "Dumping community: %s", comm->community); + + HASH_ITER(hh, comm->edges, list, tmp) { + if(list->sock.family == AF_INET) + traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][last seen: %u sec ago]", + ++num, macaddr_str(buf, list->mac_addr), + list->sock.addr.v4[0], list->sock.addr.v4[1], list->sock.addr.v4[2], list->sock.addr.v4[3], + list->sock.port, + now-list->last_seen); + else + traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: IPv6:%u][last seen: %u sec ago]", + ++num, macaddr_str(buf, list->mac_addr), list->sock.port, + now-list->last_seen); + } + } + + traceEvent(TRACE_NORMAL, "===================================="); +} +#endif + +/* *************************************************** */ + +static int keep_running; + +#if defined(__linux__) || defined(WIN32) +#ifdef WIN32 +BOOL WINAPI term_handler(DWORD sig) +#else +static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "Ok I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "Shutting down..."); + called = 1; + } + + keep_running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} +#endif /* defined(__linux__) || defined(WIN32) */ + +/* *************************************************** */ + +/** Main program entry point from kernel. */ +int main(int argc, char * const argv[]) { + int rc; +#ifndef WIN32 + struct passwd *pw = NULL; +#endif + + sn_init(&sss_node); + + if((argc >= 2) && (argv[1][0] != '-')) { + rc = loadFromFile(argv[1], &sss_node); + if(argc > 2) + rc = loadFromCLI(argc, argv, &sss_node); + } else if(argc > 1) + rc = loadFromCLI(argc, argv, &sss_node); + else +#ifdef WIN32 + /* Load from current directory */ + rc = loadFromFile("supernode.conf", &sss_node); +#else + rc = -1; +#endif + + if(rc < 0) + help(); + +#if defined(N2N_HAVE_DAEMON) + if(sss_node.daemon) { + setUseSyslog(1); /* traceEvent output now goes to syslog. */ + + if(-1 == daemon(0, 0)) { + traceEvent(TRACE_ERROR, "Failed to become daemon."); + exit(-5); + } + } +#endif /* #if defined(N2N_HAVE_DAEMON) */ + + traceEvent(TRACE_DEBUG, "traceLevel is %d", getTraceLevel()); + + sss_node.sock = open_socket(sss_node.lport, 1 /*bind ANY*/); + if(-1 == sss_node.sock) { + traceEvent(TRACE_ERROR, "Failed to open main socket. %s", strerror(errno)); + exit(-2); + } else { + traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss_node.lport); + } + + sss_node.mgmt_sock = open_socket(sss_node.mport, 0 /* bind LOOPBACK */); + if(-1 == sss_node.mgmt_sock) { + traceEvent(TRACE_ERROR, "Failed to open management socket. %s", strerror(errno)); + exit(-2); + } else + traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", sss_node.mport); + +#ifndef WIN32 + if (((pw = getpwnam ("n2n")) != NULL) || ((pw = getpwnam ("nobody")) != NULL)) { + sss_node.userid = sss_node.userid == 0 ? pw->pw_uid : 0; + sss_node.groupid = sss_node.groupid == 0 ? pw->pw_gid : 0; + } + if((sss_node.userid != 0) || (sss_node.groupid != 0)) { + traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d", + (signed int)sss_node.userid, (signed int)sss_node.groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + if((setgid(sss_node.groupid) != 0) + || (setuid(sss_node.userid) != 0)) { + traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno)); + exit(1); + } + } + + if((getuid() == 0) || (getgid() == 0)) + traceEvent(TRACE_WARNING, "Running as root is discouraged, check out the -u/-g options"); +#endif + + traceEvent(TRACE_NORMAL, "supernode started"); + +#ifdef __linux__ + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); + signal(SIGHUP, dump_registrations); +#endif +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#endif + + keep_running = 1; + return run_sn_loop(&sss_node, &keep_running); +} + + diff --git a/bundles/n2n_ntop_v2/src/sn_utils.c b/bundles/n2n_ntop_v2/src/sn_utils.c new file mode 100644 index 00000000..9c184777 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/sn_utils.c @@ -0,0 +1,1038 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) + +static int try_forward(n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktsize); + +static ssize_t sendto_sock(n2n_sn_t *sss, + const n2n_sock_t *sock, + const uint8_t *pktbuf, + size_t pktsize); + +static int sendto_mgmt(n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size); + +static int try_broadcast(n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t srcMac, + const uint8_t * pktbuf, + size_t pktsize); + +static uint16_t reg_lifetime(n2n_sn_t *sss); + +static int update_edge(n2n_sn_t *sss, + const n2n_mac_t edgeMac, + struct sn_community *comm, + const n2n_sock_t *sender_sock, + time_t now); + +static int purge_expired_communities(n2n_sn_t *sss, + time_t* p_last_purge, + time_t now); + +static int sort_communities (n2n_sn_t *sss, + time_t* p_last_sort, + time_t now); + +static int process_mgmt(n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size, + time_t now); + +static int process_udp(n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + uint8_t *udp_buf, + size_t udp_size, + time_t now); + +/* ************************************** */ + +static int try_forward(n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktsize) +{ + struct peer_info * scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(comm->edges, dstMac, scan); + + if(NULL != scan) + { + int data_sent_len; + data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); + + if(data_sent_len == pktsize) + { + ++(sss->stats.fwd); + traceEvent(TRACE_DEBUG, "unicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } + else + { + ++(sss->stats.errors); + traceEvent(TRACE_ERROR, "unicast %lu to [%s] %s FAILED (%d: %s)", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + errno, strerror(errno)); + } + } + else + { + traceEvent(TRACE_DEBUG, "try_forward unknown MAC"); + + /* Not a known MAC so drop. */ + return(-2); + } + + return(0); +} + +/** Send a datagram to the destination embodied in a n2n_sock_t. + * + * @return -1 on error otherwise number of bytes sent + */ +static ssize_t sendto_sock(n2n_sn_t *sss, + const n2n_sock_t *sock, + const uint8_t *pktbuf, + size_t pktsize) +{ + n2n_sock_str_t sockbuf; + + if (AF_INET == sock->family) + { + struct sockaddr_in udpsock; + + udpsock.sin_family = AF_INET; + udpsock.sin_port = htons(sock->port); + memcpy(&(udpsock.sin_addr.s_addr), &(sock->addr.v4), IPV4_SIZE); + + traceEvent(TRACE_DEBUG, "sendto_sock %lu to [%s]", + pktsize, + sock_to_cstr(sockbuf, sock)); + + return sendto(sss->sock, pktbuf, pktsize, 0, + (const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in)); + } + else + { + /* AF_INET6 not implemented */ + errno = EAFNOSUPPORT; + return -1; + } +} + +/** Try and broadcast a message to all edges in the community. + * + * This will send the exact same datagram to zero or more edges registered to + * the supernode. + */ +static int try_broadcast(n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t srcMac, + const uint8_t * pktbuf, + size_t pktsize) +{ + struct peer_info *scan, *tmp; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + traceEvent(TRACE_DEBUG, "try_broadcast"); + + HASH_ITER(hh, comm->edges, scan, tmp) { + if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { + /* REVISIT: exclude if the destination socket is where the packet came from. */ + int data_sent_len; + + data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); + + if(data_sent_len != pktsize) + { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + strerror(errno)); + } + else + { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } + } + } + return 0; +} + + +/** Initialise the supernode structure */ +int sn_init(n2n_sn_t *sss) +{ +#ifdef WIN32 + initWin32(); +#endif + + pearson_hash_init(); + + memset(sss, 0, sizeof(n2n_sn_t)); + + sss->daemon = 1; /* By defult run as a daemon. */ + sss->lport = N2N_SN_LPORT_DEFAULT; + sss->mport = N2N_SN_MGMT_PORT; + sss->sock = -1; + sss->mgmt_sock = -1; + + n2n_srand (n2n_seed()); /* https://github.com/ntop/n2n/pull/373/files */ + + return 0; /* OK */ +} + +/** Deinitialise the supernode structure and deallocate any memory owned by + * it. */ +void sn_term(n2n_sn_t *sss) +{ + struct sn_community *community, *tmp; + + if (sss->sock >= 0) + { + closesocket(sss->sock); + } + sss->sock = -1; + + if (sss->mgmt_sock >= 0) + { + closesocket(sss->mgmt_sock); + } + sss->mgmt_sock = -1; + + HASH_ITER(hh, sss->communities, community, tmp) + { + clear_peer_list(&community->edges); + if (NULL != community->header_encryption_ctx) + free (community->header_encryption_ctx); + HASH_DEL(sss->communities, community); + free(community); + } +} + +/** Determine the appropriate lifetime for new registrations. + * + * If the supernode has been put into a pre-shutdown phase then this lifetime + * should not allow registrations to continue beyond the shutdown point. + */ +static uint16_t reg_lifetime(n2n_sn_t *sss) +{ + /* NOTE: UDP firewalls usually have a 30 seconds timeout */ + return 15; +} + +/** Update the edge table with the details of the edge which contacted the + * supernode. */ +static int update_edge(n2n_sn_t *sss, + const n2n_mac_t edgeMac, + struct sn_community *comm, + const n2n_sock_t *sender_sock, + time_t now) +{ + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + struct peer_info *scan; + + traceEvent(TRACE_DEBUG, "update_edge for %s [%s]", + macaddr_str(mac_buf, edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + + HASH_FIND_PEER(comm->edges, edgeMac, scan); + + if (NULL == scan) + { + /* Not known */ + + scan = (struct peer_info *)calloc(1, + sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ + + memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t)); + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + scan->last_valid_time_stamp = initial_time_stamp (); + + HASH_ADD_PEER(comm->edges, scan); + + traceEvent(TRACE_INFO, "update_edge created %s ==> %s", + macaddr_str(mac_buf, edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + } + else + { + /* Known */ + if (!sock_equal(sender_sock, &(scan->sock))) + { + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + + traceEvent(TRACE_INFO, "update_edge updated %s ==> %s", + macaddr_str(mac_buf, edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + } + else + { + traceEvent(TRACE_DEBUG, "update_edge unchanged %s ==> %s", + macaddr_str(mac_buf, edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + } + } + + scan->last_seen = now; + return 0; +} + +/*** + * + * For a given packet, find the apporopriate internal last valid time stamp for lookup + * and verify it (and also update, if applicable). + */ +static int find_edge_time_stamp_and_verify (struct peer_info * edges, + int from_supernode, n2n_mac_t mac, + uint64_t stamp) { + + uint64_t * previous_stamp = NULL; + + if(!from_supernode) { + struct peer_info *edge; + HASH_FIND_PEER(edges, mac, edge); + if(edge) { + // time_stamp_verify_and_update allows the pointer a previous stamp to be NULL + // if it is a (so far) unknown edge + previous_stamp = &(edge->last_valid_time_stamp); + } + } + + // failure --> 0; success --> 1 + return ( time_stamp_verify_and_update (stamp, previous_stamp) ); +} + +static int purge_expired_communities(n2n_sn_t *sss, + time_t* p_last_purge, + time_t now) +{ + struct sn_community *comm, *tmp; + size_t num_reg = 0; + + if ((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) return 0; + + traceEvent(TRACE_DEBUG, "Purging old communities and edges"); + + HASH_ITER(hh, sss->communities, comm, tmp) { + num_reg += purge_peer_list(&comm->edges, now - REGISTRATION_TIMEOUT); + if ((comm->edges == NULL) && (!sss->lock_communities)) { + traceEvent(TRACE_INFO, "Purging idle community %s", comm->community); + if (NULL != comm->header_encryption_ctx) + /* this should not happen as no 'locked' and thus only communities w/o encrypted header here */ + free(comm->header_encryption_ctx); + HASH_DEL(sss->communities, comm); + free(comm); + } + } + (*p_last_purge) = now; + + traceEvent(TRACE_DEBUG, "Remove %ld edges", num_reg); + + return 0; +} + + +static int number_enc_packets_sort (struct sn_community *a, struct sn_community *b) { + // comparison function for sorting communities in descending order of their + // number_enc_packets-fields + return (b->number_enc_packets - a->number_enc_packets); +} + +static int sort_communities (n2n_sn_t *sss, + time_t* p_last_sort, + time_t now) +{ + struct sn_community *comm, *tmp; + + if ((now - (*p_last_sort)) < SORT_COMMUNITIES_INTERVAL) return 0; + + // this routine gets periodically called as defined in SORT_COMMUNITIES_INTERVAL + // it sorts the communities in descending order of their number_enc_packets-fields... + HASH_SORT(sss->communities, number_enc_packets_sort); + + // ... and afterward resets the number_enc__packets-fields to zero + // (other models could reset it to half of their value to respect history) + HASH_ITER(hh, sss->communities, comm, tmp) { + comm->number_enc_packets = 0; + } + + (*p_last_sort) = now; + + return 0; +} + + +static int process_mgmt(n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size, + time_t now) +{ + char resbuf[N2N_SN_PKTBUF_SIZE]; + size_t ressize = 0; + uint32_t num_edges = 0; + uint32_t num = 0; + struct sn_community *community, *tmp; + struct peer_info * peer, *tmpPeer; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + traceEvent(TRACE_DEBUG, "process_mgmt"); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "----------------\n"); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "uptime %lu\n", (now - sss->start_time)); + + HASH_ITER(hh, sss->communities, community, tmp) + { + num_edges += HASH_COUNT(community->edges); + } + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "edges %u\n", + num_edges); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "errors %u\n", + (unsigned int)sss->stats.errors); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_sup %u\n", + (unsigned int)sss->stats.reg_super); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_nak %u\n", + (unsigned int)sss->stats.reg_super_nak); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "fwd %u\n", + (unsigned int)sss->stats.fwd); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "broadcast %u\n", + (unsigned int)sss->stats.broadcast); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last fwd %lu sec ago\n", + (long unsigned int)(now - sss->stats.last_fwd)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last reg %lu sec ago\n", + (long unsigned int)(now - sss->stats.last_reg_super)); + + ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "cur_cmnts %u\n", HASH_COUNT(sss->communities)); + HASH_ITER(hh, sss->communities, community, tmp) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "community: %s\n", community->community); + sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize); + ressize = 0; + + num = 0; + HASH_ITER(hh, community->edges, peer, tmpPeer) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "\t[id: %u][MAC: %s][edge: %s][last seen: %lu sec ago]\n", + ++num, macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), now-peer->last_seen); + + sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize); + ressize = 0; + } + } + + ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize, + "\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize); + + return 0; +} + +static int sendto_mgmt(n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size) +{ + ssize_t r = sendto(sss->mgmt_sock, mgmt_buf, mgmt_size, 0 /*flags*/, + (struct sockaddr *)sender_sock, sizeof (struct sockaddr_in)); + + if (r <= 0) { + ++(sss->stats.errors); + traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (errno)); + return -1; + } + return 0; +} + +/** Examine a datagram and determine what to do with it. + * + */ +static int process_udp(n2n_sn_t * sss, + const struct sockaddr_in * sender_sock, + uint8_t * udp_buf, + size_t udp_size, + time_t now) +{ + n2n_common_t cmn; /* common fields in the packet header */ + size_t rem; + size_t idx; + size_t msg_type; + uint8_t from_supernode; + macstr_t mac_buf; + macstr_t mac_buf2; + n2n_sock_str_t sockbuf; + char buf[32]; + struct sn_community *comm, *tmp; + uint64_t stamp; + + traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]", + udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)), + ntohs(sender_sock->sin_port)); + + /* check if header is unenrypted. the following check is around 99.99962 percent reliable. + * it heavily relies on the structure of packet's common part + * changes to wire.c:encode/decode_common need to go together with this code */ + if (udp_size < 20) { + traceEvent(TRACE_DEBUG, "process_udp dropped a packet too short to be valid."); + return -1; + } + if ( (udp_buf[19] == (uint8_t)0x00) // null terminated community name + && (udp_buf[00] == N2N_PKT_VERSION) // correct packet version + && ((be16toh (*(uint16_t*)&(udp_buf[02])) & N2N_FLAGS_TYPE_MASK ) <= MSG_TYPE_MAX_TYPE ) // message type + && ( be16toh (*(uint16_t*)&(udp_buf[02])) < N2N_FLAGS_OPTIONS) // flags + ) { + /* most probably unencrypted */ + /* make sure, no downgrading happens here and no unencrypted packets can be + * injected in a community which definitely deals with encrypted headers */ + HASH_FIND_COMMUNITY(sss->communities, (char *)&udp_buf[04], comm); + if (comm) { + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + traceEvent(TRACE_DEBUG, "process_udp dropped a packet with unencrypted header " + "addressed to community '%s' which uses encrypted headers.", + comm->community); + return -1; + } + if (comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { + traceEvent (TRACE_INFO, "process_udp locked community '%s' to using " + "unencrypted headers.", comm->community); + /* set 'no encryption' in case it is not set yet */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx = NULL; + } + } + } else { + /* most probably encrypted */ + /* cycle through the known communities (as keys) to eventually decrypt */ + uint32_t ret = 0; + HASH_ITER (hh, sss->communities, comm, tmp) { + /* skip the definitely unencrypted communities */ + if (comm->header_encryption == HEADER_ENCRYPTION_NONE) + continue; + uint16_t checksum = 0; + if ( (ret = packet_header_decrypt (udp_buf, udp_size, comm->community, comm->header_encryption_ctx, + comm->header_iv_ctx, + &stamp, &checksum)) ) { + // time stamp verification follows in the packet specific section as it requires to determine the + // sender from the hash list by its MAC, this all depends on packet type and packet structure + // (MAC is not always in the same place) + if (checksum != pearson_hash_16 (udp_buf, udp_size)) { + traceEvent(TRACE_DEBUG, "process_udp dropped packet due to checksum error."); + return -1; + } + if (comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { + traceEvent (TRACE_INFO, "process_udp locked community '%s' to using " + "encrypted headers.", comm->community); + /* set 'encrypted' in case it is not set yet */ + comm->header_encryption = HEADER_ENCRYPTION_ENABLED; + } + // count the number of encrypted packets for sorting the communities from time to time + // for the HASH_ITER a few lines above gets faster for the more busy communities + (comm->number_enc_packets)++; + // no need to test further communities + break; + } + } + if (!ret) { + // no matching key/community + traceEvent(TRACE_DEBUG, "process_udp dropped a packet with seemingly encrypted header " + "for which no matching community which uses encrypted headers was found."); + return -1; + } + } + + /* Use decode_common() to determine the kind of packet then process it: + * + * REGISTER_SUPER adds an edge and generate a return REGISTER_SUPER_ACK + * + * REGISTER, REGISTER_ACK and PACKET messages are forwarded to their + * destination edge. If the destination is not known then PACKETs are + * broadcast. + */ + + rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + if(decode_common(&cmn, udp_buf, &rem, &idx) < 0) { + traceEvent(TRACE_ERROR, "Failed to decode common section"); + return -1; /* failed to decode packet */ + } + + msg_type = cmn.pc; /* packet code */ + from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; + + if(cmn.ttl < 1) { + traceEvent(TRACE_WARNING, "Expired TTL"); + return 0; /* Don't process further */ + } + + --(cmn.ttl); /* The value copied into all forwarded packets. */ + + switch(msg_type) { + case MSG_TYPE_PACKET: + { + /* PACKET from one edge to another edge via supernode. */ + + /* pkt will be modified in place and recoded to an output of potentially + * different size due to addition of the socket.*/ + n2n_PACKET_t pkt; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "process_udp PACKET with unknown community %s", cmn.community); + return -1; + } + + sss->stats.last_fwd=now; + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); + + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, pkt.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped PACKET due to time stamp error."); + return -1; + } + } + + unicast = (0 == is_multi_broadcast(pkt.dstMac)); + + traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s", + (unicast?"unicast":"multicast"), + macaddr_str(mac_buf, pkt.srcMac), + macaddr_str(mac_buf2, pkt.dstMac), + (from_supernode?"from sn":"local")); + + if(!from_supernode) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + + pkt.sock.family = AF_INET; + pkt.sock.port = ntohs(sender_sock->sin_port); + memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + rec_buf = encbuf; + + /* Re-encode the header. */ + encode_PACKET(encbuf, &encx, &cmn2, &pkt); + uint16_t oldEncx = encx; + + /* Copy the original payload unchanged */ + encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx)); + + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, oldEncx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, encx)); + + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + traceEvent(TRACE_DEBUG, "Rx PACKET fwd unmodified"); + + rec_buf = udp_buf; + encx = udp_size; + + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, idx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, udp_size)); + } + + /* Common section to forward the final product. */ + if(unicast) + try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx); + else + try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx); + break; + } + case MSG_TYPE_REGISTER: + { + /* Forwarding a REGISTER from one edge to the next */ + + n2n_REGISTER_t reg; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "process_udp REGISTER from unknown community %s", cmn.community); + return -1; + } + + sss->stats.last_fwd=now; + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER due to time stamp error."); + return -1; + } + } + + unicast = (0 == is_multi_broadcast(reg.dstMac)); + + if(unicast) { + traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", + macaddr_str(mac_buf, reg.srcMac), + macaddr_str(mac_buf2, reg.dstMac), + ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local")); + + if(0 == (cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + + reg.sock.family = AF_INET; + reg.sock.port = ntohs(sender_sock->sin_port); + memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + rec_buf = encbuf; + + /* Re-encode the header. */ + encode_REGISTER(encbuf, &encx, &cmn2, ®); + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + rec_buf = udp_buf; + encx = udp_size; + } + + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, encx)); + + try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ + } else + traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); + break; + } + case MSG_TYPE_REGISTER_ACK: + traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) Should not be via supernode"); + break; + case MSG_TYPE_REGISTER_SUPER: + { + n2n_REGISTER_SUPER_t reg; + n2n_REGISTER_SUPER_ACK_t ack; + n2n_common_t cmn2; + uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + + /* Edge requesting registration with us. */ + sss->stats.last_reg_super=now; + ++(sss->stats.reg_super); + decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx); + + if (comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error."); + return -1; + } + } + } + + /* + Before we move any further, we need to check if the requested + community is allowed by the supernode. In case it is not we do + not report any message back to the edge to hide the supernode + existance (better from the security standpoint) + */ + if(!comm && !sss->lock_communities) { + comm = calloc(1, sizeof(struct sn_community)); + + if(comm) { + strncpy(comm->community, (char*)cmn.community, N2N_COMMUNITY_SIZE-1); + comm->community[N2N_COMMUNITY_SIZE-1] = '\0'; + /* new communities introduced by REGISTERs could not have had encrypted header */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx = NULL; + comm->number_enc_packets = 0; + HASH_ADD_STR(sss->communities, community, comm); + + traceEvent(TRACE_INFO, "New community: %s", comm->community); + } + } + + if(comm) { + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_register_super_ack; + cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); + + memcpy(&(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t)); + memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t)); + ack.lifetime = reg_lifetime(sss); + + ack.sock.family = AF_INET; + ack.sock.port = ntohs(sender_sock->sin_port); + memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + ack.num_sn=0; /* No backup */ + memset(&(ack.sn_bak), 0, sizeof(n2n_sock_t)); + + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); + + update_edge(sss, reg.edgeMac, comm, &(ack.sock), now); + + encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack); + + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (ackbuf, encx)); + + sendto(sss->sock, ackbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in)); + + traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); + } else + traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", + (char*)cmn.community); + break; + } + case MSG_TYPE_QUERY_PEER: { + n2n_QUERY_PEER_t query; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + n2n_common_t cmn2; + n2n_PEER_INFO_t pi; + + if(!comm) { + traceEvent(TRACE_DEBUG, "process_udp QUERY_PEER from unknown community %s", cmn.community); + return -1; + } + + decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx ); + + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, query.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped QUERY_PEER due to time stamp error."); + return -1; + } + } + + traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", + macaddr_str( mac_buf, query.srcMac ), + macaddr_str( mac_buf2, query.targetMac ) ); + + struct peer_info *scan; + HASH_FIND_PEER(comm->edges, query.targetMac, scan); + + if (scan) { + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_peer_info; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); + + pi.aflags = 0; + memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) ); + pi.sock = scan->sock; + + encode_PEER_INFO( encbuf, &encx, &cmn2, &pi ); + + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (encbuf, encx)); + + sendto( sss->sock, encbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); + + traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", + macaddr_str( mac_buf, query.srcMac ) ); + } else { + traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s", + macaddr_str( mac_buf, query.targetMac ) ); + } + + break; + } + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "Unable to handle packet type %d: ignored", (signed int)msg_type); + } /* switch(msg_type) */ + + return 0; +} + +/** Long lived processing entry point. Split out from main to simply + * daemonisation on some platforms. */ +int run_sn_loop(n2n_sn_t *sss, int *keep_running) +{ + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; + time_t last_purge_edges = 0; + time_t last_sort_communities = 0; + + sss->start_time = time(NULL); + + while (*keep_running) + { + int rc; + ssize_t bread; + int max_sock; + fd_set socket_mask; + struct timeval wait_time; + time_t now = 0; + + FD_ZERO(&socket_mask); + max_sock = MAX(sss->sock, sss->mgmt_sock); + + FD_SET(sss->sock, &socket_mask); + FD_SET(sss->mgmt_sock, &socket_mask); + + wait_time.tv_sec = 10; + wait_time.tv_usec = 0; + rc = select(max_sock + 1, &socket_mask, NULL, NULL, &wait_time); + + now = time(NULL); + + if (rc > 0) + { + if (FD_ISSET(sss->sock, &socket_mask)) + { + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sss->sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if ((bread < 0) +#ifdef WIN32 + && (WSAGetLastError() != WSAECONNRESET) +#endif + ) + { + /* For UDP bread of zero just means no data (unlike TCP). */ + /* The fd is no good now. Maybe we lost our interface. */ + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + *keep_running = 0; + break; + } + + /* We have a datagram to process */ + if (bread > 0) + { + /* And the datagram has data (not just a header) */ + process_udp(sss, &sender_sock, pktbuf, bread, now); + } + } + + if (FD_ISSET(sss->mgmt_sock, &socket_mask)) + { + struct sockaddr_in sender_sock; + size_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if (bread <= 0) + { + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); + *keep_running = 0; + break; + } + + /* We have a datagram to process */ + process_mgmt(sss, &sender_sock, pktbuf, bread, now); + } + } + else + { + traceEvent(TRACE_DEBUG, "timeout"); + } + + purge_expired_communities(sss, &last_purge_edges, now); + sort_communities (sss, &last_sort_communities, now); + } /* while */ + + sn_term(sss); + + return 0; +} diff --git a/bundles/n2n_ntop_v2/src/speck.c b/bundles/n2n_ntop_v2/src/speck.c new file mode 100644 index 00000000..9ca7811c --- /dev/null +++ b/bundles/n2n_ntop_v2/src/speck.c @@ -0,0 +1,883 @@ +// cipher SPECK -- 128 bit block size -- 256 bit key size -- CTR mode +// taken from (and modified: removed pure crypto-stream generation and seperated key expansion) +// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/ + +#include +#include "portable_endian.h" + +#include "speck.h" + +#if defined (__AVX2__) // AVX support ---------------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR _mm256_xor_si256 +#define AND _mm256_and_si256 +#define ADD _mm256_add_epi64 +#define SL _mm256_slli_epi64 +#define SR _mm256_srli_epi64 + +#define _q SET(0x3,0x1,0x2,0x0) +#define _four SET(0x4,0x4,0x4,0x4) + +#define SET _mm256_set_epi64x +#define SET1(X,c) (X=SET(c,c,c,c)) +#define SET4(X,c) (X=SET(c,c,c,c), X=ADD(X,_q)) + +#define LOW _mm256_unpacklo_epi64 +#define HIGH _mm256_unpackhi_epi64 +#define LD(ip) _mm256_loadu_si256((__m256i *)(ip)) +#define ST(ip,X) _mm256_storeu_si256((__m256i *)(ip),X) +#define STORE(out,X,Y) (ST(out,LOW(Y,X)), ST(out+32,HIGH(Y,X))) +#define STORE_ALT(out,X,Y) (ST(out,LOW(X,Y)), ST(out+32,HIGH(X,Y))) +#define XOR_STORE(in,out,X,Y) (ST(out,XOR(LD(in),LOW(Y,X))), ST(out+32,XOR(LD(in+32),HIGH(Y,X)))) +#define XOR_STORE_ALT(in,out,X,Y) (ST(out,XOR(LD(in),LOW(X,Y))), ST(out+32,XOR(LD(in+32),HIGH(X,Y)))) + +#define SHFL _mm256_shuffle_epi8 +#define R8 SET(0x080f0e0d0c0b0a09LL,0x0007060504030201LL,0x080f0e0d0c0b0a09LL,0x0007060504030201LL) +#define L8 SET(0x0e0d0c0b0a09080fLL,0x0605040302010007LL,0x0e0d0c0b0a09080fLL,0x0605040302010007LL) +#define ROL8(X) (SHFL(X,L8)) +#define ROR8(X) (SHFL(X,R8)) +#define ROL(X,r) (XOR(SL(X,r),SR(X,(64-r)))) +#define ROR(X,r) (XOR(SR(X,r),SL(X,(64-r)))) + +#define numrounds 34 +#define numkeywords 4 + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx4(X,Y,k) (R(X[0],Y[0],k)) +#define Rx8(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx12(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) + +#define Rx16(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), \ + X[0]=XOR(X[0],k), X[1]=XOR(X[1],k), X[2]=XOR(X[2],k), X[3]=XOR(X[3],k), \ + Z[0]=Y[0], Z[1]=Y[1], Z[2]=Y[2], Z[3]=Y[3], \ + Z[0]=SL(Z[0],3), Y[0]=SR(Y[0],61), Z[1]=SL(Z[1],3), Y[1]=SR(Y[1],61), \ + Z[2]=SL(Z[2],3), Y[2]=SR(Y[2],61), Z[3]=SL(Z[3],3), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx2(x,y,k) (x[0]=RCS(x[0],8), x[1]=RCS(x[1],8), x[0]+=y[0], x[1]+=y[1], \ + x[0]^=k, x[1]^=k, y[0]=LCS(y[0],3), y[1]=LCS(y[1],3), y[0]^=x[0], y[1]^=x[1]) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) + +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) + +#define Encrypt(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31]), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + +static int speck_encrypt_xor(unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { + + u64 x[2], y[2]; + u256 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + Encrypt (x, y, ctx->key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + if (numbytes == 32) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + x[1] = nonce[1]; y[1] = nonce[0]; nonce[0]++; + Encrypt (x , y, ctx->key, 2); + ((u64 *)out)[1] = x[0] ^ ((u64 *)in)[1]; ((u64 *)out)[0] = y[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[3] = x[1] ^ ((u64 *)in)[3]; ((u64 *)out)[2] = y[1] ^ ((u64 *)in)[2]; + return 0; + } + + SET1 (X[0], nonce[1]); SET4 (Y[0], nonce[0]); + + if (numbytes == 64) + Encrypt (X, Y, ctx->rk, 4); + else { + X[1] = X[0]; + Y[1] = ADD (Y[0], _four); + if (numbytes == 128) + Encrypt (X, Y, ctx->rk, 8); + else { + X[2] = X[0]; + Y[2] = ADD (Y[1], _four); + if (numbytes == 192) + Encrypt (X, Y, ctx->rk, 12); + else { + X[3] = X[0]; + Y[3] = ADD (Y[2], _four); + Encrypt (X, Y, ctx->rk, 16); + } + } + } + + nonce[0] += (numbytes>>4); + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 128) + XOR_STORE (in + 64, out + 64, X[1], Y[1]); + if (numbytes >= 192) + XOR_STORE (in + 128, out + 128, X[2], Y[2]); + if (numbytes >= 256) + XOR_STORE (in + 192, out + 192, X[3], Y[3]); + + return 0; +} + + +int speck_ctr( unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 256) { + speck_encrypt_xor (out, in, nonce, ctx, 256); + in += 256; inlen -= 256; out += 256; + } + + if (inlen >= 192) { + speck_encrypt_xor (out, in, nonce, ctx, 192); + in += 192; inlen -= 192; out += 192; + } + + if (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { + + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; + + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + + return 0; +} + + +#elif defined (__SSE4_2__) // SSE support ------------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR _mm_xor_si128 +#define AND _mm_and_si128 +#define ADD _mm_add_epi64 +#define SL _mm_slli_epi64 +#define SR _mm_srli_epi64 + +#define _q SET(0x1,0x0) +#define _two SET(0x2,0x2) + +#define SET _mm_set_epi64x +#define SET1(X,c) (X=SET(c,c)) +#define SET2(X,c) (X=SET(c,c), X=ADD(X,_q)) + +#define LOW _mm_unpacklo_epi64 +#define HIGH _mm_unpackhi_epi64 +#define LD(ip) _mm_loadu_si128((__m128i *)(ip)) +#define ST(ip,X) _mm_storeu_si128((__m128i *)(ip),X) +#define STORE(out,X,Y) (ST(out,LOW(Y,X)), ST(out+16,HIGH(Y,X))) +#define STORE_ALT(out,X,Y) (ST(out,LOW(X,Y)), ST(out+16,HIGH(X,Y))) +#define XOR_STORE(in,out,X,Y) (ST(out,XOR(LD(in),LOW(Y,X))), ST(out+16,XOR(LD(in+16),HIGH(Y,X)))) +#define XOR_STORE_ALT(in,out,X,Y) (ST(out,XOR(LD(in),LOW(X,Y))), ST(out+16,XOR(LD(in+16),HIGH(X,Y)))) + +#define SHFL _mm_shuffle_epi8 +#define R8 _mm_set_epi64x(0x080f0e0d0c0b0a09LL,0x0007060504030201LL) +#define L8 _mm_set_epi64x(0x0e0d0c0b0a09080fLL,0x0605040302010007LL) +#define ROL8(X) (SHFL(X,L8)) +#define ROR8(X) (SHFL(X,R8)) +#define ROL(X,r) (XOR(SL(X,r),SR(X,(64-r)))) +#define ROR(X,r) (XOR(SR(X,r),SL(X,(64-r)))) + +#define numrounds 34 +#define numkeywords 4 + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx2(X,Y,k) (R(X[0],Y[0],k)) +#define Rx4(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx6(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) + +#define Rx8(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), \ + X[0]=XOR(X[0],k), X[1]=XOR(X[1],k), X[2]=XOR(X[2],k), X[3]=XOR(X[3],k), \ + Z[0]=Y[0], Z[1]=Y[1], Z[2]=Y[2], Z[3]=Y[3], \ + Z[0]=SL(Z[0],3), Y[0]=SR(Y[0],61), Z[1]=SL(Z[1],3), Y[1]=SR(Y[1],61), \ + Z[2]=SL(Z[2],3), Y[2]=SR(Y[2],61), Z[3]=SL(Z[3],3), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) + +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) + +#define Encrypt(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31]), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + + +static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], const speck_context_t ctx, int numbytes) { + + u64 x[2], y[2]; + u128 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; + Encrypt (x, y, ctx.key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); + + if (numbytes == 32) + Encrypt (X, Y, ctx.rk, 2); + else { + X[1] = X[0]; Y[1] = ADD (Y[0], _two); + if (numbytes == 64) + Encrypt (X, Y, ctx.rk, 4); + else { + X[2] = X[0]; Y[2] = ADD (Y[1], _two); + if (numbytes == 96) + Encrypt (X, Y, ctx.rk, 6); + else { + X[3] = X[0]; Y[3] = ADD (Y[2], _two); + Encrypt (X, Y, ctx.rk, 8); + } + } + } + + nonce[0] += (numbytes>>4); + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 64) + XOR_STORE (in + 32, out + 32, X[1], Y[1]); + if (numbytes >= 96) + XOR_STORE (in + 64, out + 64, X[2], Y[2]); + if (numbytes >= 128) + XOR_STORE (in + 96, out + 96, X[3], Y[3]); + + return 0; +} + + +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, const speck_context_t ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 96) { + speck_encrypt_xor (out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { + + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; + + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + + return 0; +} + + +#elif defined (__ARM_NEON) // NEON support ------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR veorq_u64 +#define AND vandq_u64 +#define ADD vaddq_u64 +#define SL vshlq_n_u64 +#define SR vshrq_n_u64 + +#define SET(a,b) vcombine_u64((uint64x1_t)(a),(uint64x1_t)(b)) +#define SET1(X,c) (X=SET(c,c)) +#define SET2(X,c) (SET1(X,c), X=ADD(X,SET(0x1ll,0x0ll)),c+=2) + +#define LOW(Z) vgetq_lane_u64(Z,0) +#define HIGH(Z) vgetq_lane_u64(Z,1) +#define STORE(ip,X,Y) (((u64 *)(ip))[0]=HIGH(Y), ((u64 *)(ip))[1]=HIGH(X), ((u64 *)(ip))[2]=LOW(Y), ((u64 *)(ip))[3]=LOW(X)) +#define XOR_STORE(in,out,X,Y) (Y=XOR(Y,SET(((u64 *)(in))[2],((u64 *)(in))[0])), X=XOR(X,SET(((u64 *)(in))[3],((u64 *)(in))[1])), STORE(out,X,Y)) + +#define ROR(X,r) vsriq_n_u64(SL(X,(64-r)),X,r) +#define ROL(X,r) ROR(X,(64-r)) + +#define tableR vcreate_u8(0x0007060504030201LL) +#define tableL vcreate_u8(0x0605040302010007LL) +#define ROR8(X) SET(vtbl1_u8((uint8x8_t)vget_low_u64(X),tableR), vtbl1_u8((uint8x8_t)vget_high_u64(X),tableR)) +#define ROL8(X) SET(vtbl1_u8((uint8x8_t)vget_low_u64(X),tableL), vtbl1_u8((uint8x8_t)vget_high_u64(X),tableL)) + +#define numrounds 34 +#define numkeywords 4 + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx2(X,Y,k) (R(X[0],Y[0],k)) + +#define Rx4(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx6(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) +#define Rx8(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[0]=XOR(X[0],k), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), X[1]=XOR(X[1],k), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[2]=XOR(X[2],k), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), X[3]=XOR(X[3],k), \ + Z[0]=SL(Y[0],3), Z[1]=SL(Y[1],3), Z[2]=SL(Y[2],3), Z[3]=SL(Y[3],3), \ + Y[0]=SR(Y[0],61), Y[1]=SR(Y[1],61), Y[2]=SR(Y[2],61), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) + +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) + +#define Encrypt(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31]), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + + +static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { + + u64 x[2], y[2]; + u128 X[4], Y[4], Z[4]; + + if (numbytes == 16) { + x[0] = nonce[1]; y[0]=nonce[0]; nonce[0]++; + Encrypt (x, y, ctx->key, 1); + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; + return 0; + } + + SET1 (X[0], nonce[1]); SET2 (Y[0], nonce[0]); + + if (numbytes == 32) + Encrypt (X, Y, ctx->rk, 2); + else { + X[1] = X[0]; SET2 (Y[1], nonce[0]); + if (numbytes == 64) + Encrypt (X, Y, ctx->rk, 4); + else { + X[2] = X[0]; SET2 (Y[2], nonce[0]); + if (numbytes == 96) + Encrypt (X, Y, ctx->rk, 6); + else { + X[3] = X[0]; SET2 (Y[3], nonce[0]); + Encrypt (X, Y, ctx->rk, 8); + } + } + } + + XOR_STORE (in, out, X[0], Y[0]); + if (numbytes >= 64) + XOR_STORE (in + 32, out + 32, X[1], Y[1]); + if (numbytes >= 96) + XOR_STORE (in + 64, out + 64, X[2], Y[2]); + if (numbytes >= 128) + XOR_STORE (in + 96, out + 96, X[3], Y[3]); + + return 0; +} + + +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 *const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while (inlen >= 128) { + speck_encrypt_xor (out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if (inlen >= 96) { + speck_encrypt_xor (out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if (inlen >= 64) { + speck_encrypt_xor (out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if (inlen >= 32) { + speck_encrypt_xor (out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if (inlen >= 16) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if (inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for (i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { + + u64 K[4]; + size_t i; + for (i = 0; i < numkeywords; i++) + K[i] = ((u64 *)k)[i]; + + EK (K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + + return 0; +} + + +#else // plain C ---------------------------------------------------------------- + + +#define ROR(x,r) (((x)>>(r))|((x)<<(64-(r)))) +#define ROL(x,r) (((x)<<(r))|((x)>>(64-(r)))) +#define R(x,y,k) (x=ROR(x,8), x+=y, x^=k, y=ROL(y,3), y^=x) + + +static int speck_encrypt (u64 *u, u64 *v, speck_context_t *ctx) { + + u64 i, x = *u, y = *v; + + for (i = 0; i < 34; i++) + R (x, y, ctx->key[i]); + + *u = x; *v = y; + + return 0; +} + + +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + u64 i, nonce[2], x, y, t; + unsigned char *block = malloc (16); + + if (!inlen) { + free (block); + return 0; + } + nonce[0] = htole64 ( ((u64*)n)[0] ); + nonce[1] = htole64 ( ((u64*)n)[1] ); + + t=0; + while (inlen >= 16) { + x = nonce[1]; y = nonce[0]; nonce[0]++; + speck_encrypt (&x, &y, ctx); + ((u64 *)out)[1+t] = htole64 (x ^ ((u64 *)in)[1+t]); + ((u64 *)out)[0+t] = htole64 (y ^ ((u64 *)in)[0+t]); + t += 2; + inlen -= 16; + } + if (inlen > 0) { + x = nonce[1]; y = nonce[0]; + speck_encrypt (&x, &y, ctx); + ((u64 *)block)[1] = htole64 (x); ((u64 *)block)[0] = htole64 (y); + for (i = 0; i < inlen; i++) + out[i + 8*t] = block[i] ^ in[i + 8*t]; + } + + free (block); + return 0; +} + + +int speck_expand_key (const unsigned char *k, speck_context_t *ctx) { + + u64 K[4]; + u64 i; + + for (i = 0; i < 4; i++) + K[i] = htole64 ( ((u64 *)k)[i] ); + + for (i = 0; i < 33; i += 3) { + ctx->key[i ] = K[0]; + R (K[1], K[0], i ); + ctx->key[i+1] = K[0]; + R (K[2], K[0], i + 1); + ctx->key[i+2] = K[0]; + R (K[3], K[0], i + 2); + } + ctx->key[33] = K[0]; + return 1; +} + + +#endif // AVX, SSE, NEON, plain C ------------------------------------------------ + + +// cipher SPECK -- 128 bit block size -- 128 bit key size -- CTR mode +// used for header encryption, thus the prefix 'he_' +// for now: just plain C -- AVX, SSE, NEON might follow + +#define ROR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) +#define ROL64(x,r) (((x)<<(r))|((x)>>(64-(r)))) +#define R64(x,y,k) (x=ROR64(x,8), x+=y, x^=k, y=ROL64(y,3), y^=x) + + +static int speck_encrypt_he (u64 *u, u64 *v, speck_context_t *ctx) { + + u64 i, x=*u, y=*v; + + for (i = 0; i < 32; i++) + R64 (x, y, ctx->key[i]); + + *u = x; *v = y; + + return 0; +} + + +int speck_he (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + u64 i, nonce[2], x, y, t; + unsigned char *block = malloc(16); + + if (!inlen) { + free (block); + return 0; + } + nonce[0] = htole64 ( ((u64*)n)[0] ); + nonce[1] = htole64 ( ((u64*)n)[1] ); + + t = 0; + while (inlen >= 16) { + x = nonce[1]; y = nonce[0]; nonce[0]++; + speck_encrypt_he (&x, &y, ctx); + ((u64 *)out)[1+t] = htole64 (x ^ ((u64 *)in)[1+t]); + ((u64 *)out)[0+t] = htole64 (y ^ ((u64 *)in)[0+t]); + t += 2; + inlen -= 16; + } + + if (inlen > 0) { + x = nonce[1]; y = nonce[0]; + speck_encrypt_he (&x, &y, ctx); + ((u64 *)block)[1] = htole64 (x); ((u64 *)block)[0] = htole64 (y); + for (i = 0; i < inlen; i++) + out[i+8*t] = block[i] ^ in[i+8*t]; + } + + free(block); + return 0; +} + + +int speck_expand_key_he (const unsigned char *k, speck_context_t *ctx) { + + u64 A, B; + u64 i; + + A = htole64 ( ((u64 *)k)[0] ); + B = htole64 ( ((u64 *)k)[1] ); + + for (i = 0; i < 32; i++) { + ctx->key[i] = A; + R64 ( B, A, i); + } + return 1; +} + + +// ---------------------------------------------------------------------------------------- + + +// cipher SPECK -- 96 bit block size -- 96 bit key size -- ECB mode +// follows endianess rules as used in official implementation guide and NOT as in original 2013 cipher presentation +// used for IV in header encryption, thus the prefix 'he_iv_' +// for now: just plain C -- probably no need for AVX, SSE, NEON + +// prerequisite: lower 16 bit reset +#define ROTL48(x,r) (((((x)<<(r)) | (x>>(48-(r)))) >> 16) << 16) +#define ROTR48(x,r) (((((x)>>(r)) | ((x)<<(48-(r)))) >> 16) << 16) +#define ER96(x,y,k) (x=ROTR48(x,8), x+=y, x^=k, y=ROTL48(y,3), y^=x) +#define DR96(x,y,k) (y^=x, y=ROTR48(y,3), x^=k, x-=y, x=ROTL48(x,8)) + + +int speck_he_iv_encrypt (unsigned char *inout, speck_context_t *ctx) { + + u64 x, y; + int i; + + x = htole64 ( *(u64*)&inout[0] ); x <<= 16; + y = htole64 ( *(u64*)&inout[4] ); y >>= 16; y <<= 16; + + for (i = 0; i < 28; i++) + ER96 (y, x, ctx->key[i]); + + x >>= 16; x |= y << 32; + y >>= 32; + + ((u64*)inout)[0] = le64toh (x); + ((u32*)inout)[2] = le32toh (y); + + return 0; +} + + +int speck_he_iv_decrypt (unsigned char *inout, speck_context_t *ctx) { + + u64 x, y; + int i; + + x = htole64 ( *(u64*)&inout[0] ); x <<= 16; + y = htole64 ( *(u64*)&inout[4] ); y >>= 16; y <<= 16; + + for (i = 27; i >= 0; i--) + DR96 (y, x, ctx->key[i]); + + x >>= 16; x |= y << 32; + y >>= 32; + + ((u64*)inout)[0] = le64toh (x); + ((u32*)inout)[2] = le32toh (y); + + return 0; +} + + +int speck_expand_key_he_iv (const unsigned char *k, speck_context_t *ctx) { + + u64 A, B; + int i; + + A = htole64 ( *(u64 *)&k[0] ); A <<= 16; + B = htole64 ( *(u64 *)&k[4] ); B >>= 16; B <<= 16; + + for (i = 0; i < 28; i++) { + ctx->key[i] = A; + ER96 ( B, A, i << 16); + } + + return 1; +} + + +// ---------------------------------------------------------------------------------------- + +/* +// code for testing -- to be removed when finished +#include // for testing +#include + +int speck_test () { + + uint8_t key[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; + + uint8_t k96[12] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D }; + + uint8_t iv[16] = { 0x70, 0x6f, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x20, + 0x49, 0x6e, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65 }; + + uint8_t xv[16] = { 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x69, 0x74, + 0x20, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c }; + + uint8_t p96[12] = { 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, + 0x2C, 0x20, 0x68, 0x6F, 0x77, 0x65 }; + + uint8_t pt[16] = { 0x00 }; + + // expected outcome (according to pp. 35 & 36 of Implementation Guide 1.1 as of 2019) and + // original cipher presentation as of 2013 in which notably a different endianess is used + uint8_t ct[16] = { 0x43, 0x8f, 0x18, 0x9c, 0x8d, 0xb4, 0xee, 0x4e, + 0x3e, 0xf5, 0xc0, 0x05, 0x04, 0x01, 0x09, 0x41 }; + + uint8_t xt[16] = { 0x18, 0x0d, 0x57, 0x5c, 0xdf, 0xfe, 0x60, 0x78, + 0x65, 0x32, 0x78, 0x79, 0x51, 0x98, 0x5d, 0xa6 }; + + uint8_t x96[12] = { 0xAA, 0x79, 0x8F, 0xDE, 0xBD, 0x62, + 0x78, 0x71, 0xAB, 0x09, 0x4D, 0x9E }; + speck_context_t ctx; + + speck_expand_key (key, &ctx); +#if defined (SPECK_CTX_BYVAL) + speck_ctr (pt, pt, 16, iv, ctx); +#else + speck_ctr (pt, pt, 16, iv, &ctx); +#endif + + u64 i; + fprintf (stderr, "rk00: %016llx\n", ctx.key[0]); + fprintf (stderr, "rk33: %016llx\n", ctx.key[33]); + fprintf (stderr, "out : %016lx\n", *(uint64_t*)pt); + fprintf (stderr, "mem : " ); for (i=0; i < 16; i++) fprintf (stderr, "%02x ", pt[i]); fprintf (stderr, "\n"); + + int ret = 1; + for (i=0; i < 16; i++) + if (pt[i] != ct[i]) ret = 0; + + memset (pt, 0, 16); + speck_expand_key_he (key, &ctx); + speck_he (pt, pt, 16, xv, &ctx); + + fprintf (stderr, "rk00: %016llx\n", ctx.key[0]); + fprintf (stderr, "rk31: %016llx\n", ctx.key[31]); + fprintf (stderr, "out : %016lx\n", *(uint64_t*)pt); + fprintf (stderr, "mem : " ); for (i=0; i < 16; i++) fprintf (stderr, "%02x ", pt[i]); fprintf (stderr, "\n"); + + for (i=0; i < 16; i++) + if (pt[i] != xt[i]) ret = 0; + + speck_expand_key_he_iv (k96, &ctx); + speck_he_iv_encrypt (p96, &ctx); +// speck_he_iv_decrypt (p96, &ctx); +// speck_he_iv_encrypt (p96, &ctx); + + fprintf (stderr, "rk00: %016llx\n", ctx.key[0]); + fprintf (stderr, "rk27: %016llx\n", ctx.key[27]); + fprintf (stderr, "out : %016lx\n", *(uint64_t*)p96); + fprintf (stderr, "mem : " ); for (i=0; i < 12; i++) fprintf (stderr, "%02x ", p96[i]); fprintf (stderr, "\n"); + + for (i=0; i < 12; i++) + if (p96[i] != x96[i]) ret = 0; + + return (ret); +} + + +int main (int argc, char* argv[]) { + + fprintf (stdout, "SPECK SELF TEST RESULT: %u\n", speck_test (0,NULL)); +} + +*/ diff --git a/bundles/n2n_ntop_v2/src/transform_aes.c b/bundles/n2n_ntop_v2/src/transform_aes.c new file mode 100644 index 00000000..27eeaaf9 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/transform_aes.c @@ -0,0 +1,480 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#ifdef N2N_HAVE_AES + +#include +#include +#include +#include + +#define N2N_AES_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_AES_IVEC_SIZE (AES_BLOCK_SIZE) + +#define AES256_KEY_BYTES (256/8) +#define AES192_KEY_BYTES (192/8) +#define AES128_KEY_BYTES (128/8) + +/* AES plaintext preamble */ +#define TRANSOP_AES_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_AES_IV_SEED_SIZE 8 /* size of transmitted random part of IV in bytes; could range + * from 0=lowest security (constant IV) to 16=higest security + * (fully random IV); default=8 */ +#define TRANSOP_AES_IV_PADDING_SIZE (N2N_AES_IVEC_SIZE - TRANSOP_AES_IV_SEED_SIZE) +#define TRANSOP_AES_IV_KEY_BYTES (AES128_KEY_BYTES) /* use AES128 for IV encryption */ +#define TRANSOP_AES_PREAMBLE_SIZE (TRANSOP_AES_VER_SIZE + TRANSOP_AES_IV_SEED_SIZE) + +typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE]; + +typedef struct transop_aes { +#ifdef HAVE_OPENSSL_1_1 + EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption context */ + EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* decryption context */ + const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */ + uint8_t key[32]; /* the pure key data for payload encryption & decryption */ +#else + AES_KEY enc_key; /* tx key */ + AES_KEY dec_key; /* tx key */ +#endif + AES_KEY iv_enc_key; /* key used to encrypt the IV */ + uint8_t iv_pad_val[TRANSOP_AES_IV_PADDING_SIZE]; /* key used to pad the random IV seed to full block size */ +} transop_aes_t; + +/* ****************************************************** */ + +static int transop_deinit_aes(n2n_trans_op_t *arg) { + transop_aes_t *priv = (transop_aes_t *)arg->priv; + +#ifdef HAVE_OPENSSL_1_1 + EVP_CIPHER_CTX_free(priv->enc_ctx); + EVP_CIPHER_CTX_free(priv->dec_ctx); +#endif + + if(priv) + free(priv); + + return 0; +} + +/* ****************************************************** */ + +#ifdef HAVE_OPENSSL_1_1 +/* get any erorr message out of openssl + taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */ +static char *openssl_err_as_string (void) { + BIO *bio = BIO_new (BIO_s_mem ()); + ERR_print_errors (bio); + char *buf = NULL; + size_t len = BIO_get_mem_data (bio, &buf); + char *ret = (char *) calloc (1, 1 + len); + + if(ret) + memcpy (ret, buf, len); + + BIO_free (bio); + return ret; +} +#endif + +/* ****************************************************** */ + +/* convert a given number of bytes from memory to hex string; taken (and modified) from + https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c */ +const char* to_hex(unsigned char * in, size_t insz, char * out, size_t outsz) +{ + unsigned char * pin = in; + const char * hex = "0123456789abcdef"; + char * pout = out; + for(; pin < in+insz; pout +=2, pin++){ + pout[0] = hex[(*pin>>4) & 0xF]; + pout[1] = hex[ *pin & 0xF]; + if (pout + 2 - out > outsz){ + /* Better to truncate output string than overflow buffer */ + /* it would be still better to either return a status */ + /* or ensure the target buffer is large enough and it never happen */ + break; + } + } + pout[2] = 0; + return out; +} + +/* ****************************************************** */ + +static void set_aes_cbc_iv(transop_aes_t *priv, n2n_aes_ivec_t ivec, uint8_t * iv_seed) { + uint8_t iv_full[N2N_AES_IVEC_SIZE]; + + /* Extend the seed to full block size with padding value */ + memcpy(iv_full, priv->iv_pad_val, TRANSOP_AES_IV_PADDING_SIZE); + memcpy(iv_full + TRANSOP_AES_IV_PADDING_SIZE, iv_seed, TRANSOP_AES_IV_SEED_SIZE); + + /* Encrypt the IV with secret key to make it unpredictable. + * As discussed in https://github.com/ntop/n2n/issues/72, it's important to + * have an unpredictable IV since the initial part of the packet plaintext + * can be easily reconstructed from plaintext headers and used by an attacker + * to perform differential analysis. + */ + AES_ecb_encrypt(iv_full, ivec, &priv->iv_enc_key, AES_ENCRYPT); +} + +/* ****************************************************** */ + +/** The aes packet format consists of: + * + * - a 8-bit aes encoding version in clear text + * - a TRANSOP_AES_IV_SEED_SIZE-sized [bytes] random IV seed + * - encrypted payload. + * + * [V|II|DDDDDDDDDDDDDDDDDDDDD] + * |<---- encrypted ---->| + */ +static int transop_encode_aes(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len2=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE] = {0}; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + TRANSOP_AES_PREAMBLE_SIZE) <= out_len) { + int len=-1; + size_t idx=0; + uint8_t iv_seed[TRANSOP_AES_IV_SEED_SIZE]; + uint8_t padding = 0; + n2n_aes_ivec_t enc_ivec = {0}; + + traceEvent(TRACE_DEBUG, "encode_aes %lu", in_len); + + /* Encode the aes format version. */ + encode_uint8(outbuf, &idx, N2N_AES_TRANSFORM_VERSION); + + /* Generate and encode the IV seed using as many calls to n2n_rand() as neccessary. + * Note: ( N2N_AES_IV_SEED_SIZE % sizeof(rand_value) ) not neccessarily equals 0. */ + uint64_t rand_value; + int8_t i; + for (i = TRANSOP_AES_IV_SEED_SIZE; i >= sizeof(rand_value); i -= sizeof(rand_value)) { + rand_value = n2n_rand(); + memcpy(iv_seed + TRANSOP_AES_IV_SEED_SIZE - i, &rand_value, sizeof(rand_value)); + } + /* Are there bytes left to fill? */ + if (i != 0) { + rand_value = n2n_rand(); + memcpy(iv_seed, &rand_value, i); + } + encode_buf(outbuf, &idx, iv_seed, TRANSOP_AES_IV_SEED_SIZE); + + /* Encrypt the assembly contents and write the ciphertext after the iv seed. */ + /* len is set to the length of the cipher plain text to be encrpyted + which is (in this case) identical to original packet lentgh */ + len = in_len; + + /* The assembly buffer is a source for encrypting data. + * The whole contents of assembly are encrypted. */ + memcpy(assembly, inbuf, in_len); + + /* Need at least one encrypted byte at the end for the padding. */ + len2 = ((len / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; /* Round up to next whole AES adding at least one byte. */ + padding = (len2-len); + assembly[len2 - 1] = padding; + + char iv_seed_hex[2 * N2N_AES_IVEC_SIZE + 1]; + traceEvent(TRACE_DEBUG, "padding = %u, seed = 0x%s", padding, to_hex (iv_seed, TRANSOP_AES_IV_SEED_SIZE, iv_seed_hex, 2 * N2N_AES_IVEC_SIZE + 1) ); + + set_aes_cbc_iv(priv, enc_ivec, iv_seed); + +#ifdef HAVE_OPENSSL_1_1 + EVP_CIPHER_CTX *ctx = priv->enc_ctx; + int evp_len; + int evp_ciphertext_len; + + if(1 == EVP_EncryptInit_ex(ctx, priv->cipher, NULL, priv->key, enc_ivec)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { + if(1 == EVP_EncryptUpdate(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE, &evp_len, assembly, len2)) { + evp_ciphertext_len = evp_len; + if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_AES_PREAMBLE_SIZE + evp_len, &evp_len)) { + evp_ciphertext_len += evp_len; + + if(evp_ciphertext_len != len2) + traceEvent(TRACE_ERROR, "encode_aes openssl encryption: encrypted %u bytes where %u were expected.\n", + evp_ciphertext_len, len2); + } else + traceEvent(TRACE_ERROR, "encode_aes openssl final encryption: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_aes openssl encrpytion: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_aes openssl padding setup: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_aes openssl init: %s\n", openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx); +#else + AES_cbc_encrypt(assembly, /* source */ + outbuf + TRANSOP_AES_PREAMBLE_SIZE, /* dest */ + len2, /* enc size */ + &(priv->enc_key), enc_ivec, AES_ENCRYPT); +#endif + + len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */ + } else + traceEvent(TRACE_ERROR, "encode_aes outbuf too small."); + } else + traceEvent(TRACE_ERROR, "encode_aes inbuf too big to encrypt."); + + return len2; +} + +/* ****************************************************** */ + +/* See transop_encode_aes for packet format */ +static int transop_decode_aes(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len=0; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if(((in_len - TRANSOP_AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in assembly */ + && (in_len >= TRANSOP_AES_PREAMBLE_SIZE) /* Has at least version, iv seed */ + ) + { + size_t rem=in_len; + size_t idx=0; + uint8_t aes_enc_ver=0; + uint8_t iv_seed[TRANSOP_AES_IV_SEED_SIZE]; + + /* Get the encoding version to make sure it is supported */ + decode_uint8(&aes_enc_ver, inbuf, &rem, &idx ); + + if(N2N_AES_TRANSFORM_VERSION == aes_enc_ver) { + /* Get the IV seed */ + decode_buf((uint8_t *)&iv_seed, TRANSOP_AES_IV_SEED_SIZE, inbuf, &rem, &idx); + + char iv_seed_hex[2 * N2N_AES_IVEC_SIZE + 1]; + traceEvent(TRACE_DEBUG, "decode_aes %lu with seed 0x%s", in_len, to_hex (iv_seed, TRANSOP_AES_IV_SEED_SIZE, iv_seed_hex, 2 * N2N_AES_IVEC_SIZE + 1) ); + + len = (in_len - TRANSOP_AES_PREAMBLE_SIZE); + + if(0 == (len % AES_BLOCK_SIZE)) { + uint8_t padding; + n2n_aes_ivec_t dec_ivec = {0}; + + set_aes_cbc_iv(priv, dec_ivec, iv_seed); + +#ifdef HAVE_OPENSSL_1_1 + EVP_CIPHER_CTX *ctx = priv->dec_ctx; + int evp_len; + int evp_plaintext_len; + + if(1 == EVP_DecryptInit_ex(ctx, priv->cipher, NULL, priv->key, dec_ivec)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { + if(1 == EVP_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_AES_PREAMBLE_SIZE, len)) { + evp_plaintext_len = evp_len; + if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) { + evp_plaintext_len += evp_len; + + if(evp_plaintext_len != len) + traceEvent(TRACE_ERROR, "decode_aes openssl decryption: decrypted %u bytes where %u were expected.\n", + evp_plaintext_len, len); + } else + traceEvent(TRACE_ERROR, "decode_aes openssl final decryption: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "decode_aes openssl decrpytion: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "decode_aes openssl padding setup: %s\n", openssl_err_as_string()); + + } else + traceEvent(TRACE_ERROR, "decode_aes openssl init: %s\n", openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx); +#else + AES_cbc_encrypt((inbuf + TRANSOP_AES_PREAMBLE_SIZE), + assembly, /* destination */ + len, + &(priv->dec_key), + dec_ivec, AES_DECRYPT); +#endif + /* last byte is how much was padding: max value should be + * AES_BLOCKSIZE-1 */ + padding = assembly[ len-1 ] & 0xff; + + if(len >= padding) { + /* strictly speaking for this to be an ethernet packet + * it is going to need to be even bigger; but this is + * enough to prevent segfaults. */ + traceEvent(TRACE_DEBUG, "padding = %u", padding); + len -= padding; + + memcpy(outbuf, + assembly, + len); + } else + traceEvent(TRACE_WARNING, "UDP payload decryption failed."); + } else { + traceEvent(TRACE_WARNING, "Encrypted length %d is not a multiple of AES_BLOCK_SIZE (%d)", len, AES_BLOCK_SIZE); + len = 0; + } + } else + traceEvent(TRACE_ERROR, "decode_aes unsupported aes version %u.", aes_enc_ver); + } else + traceEvent(TRACE_ERROR, "decode_aes inbuf wrong size (%ul) to decrypt.", in_len); + + return len; +} + +/* ****************************************************** */ + +static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size) { + size_t aes_key_size_bytes; + size_t aes_key_size_bits; + + uint8_t key_mat_buf[SHA512_DIGEST_LENGTH + SHA256_DIGEST_LENGTH]; + size_t key_mat_buf_length; + + /* Clear out any old possibly longer key matter. */ +#ifdef HAVE_OPENSSL_1_1 + memset(&(priv->key), 0, sizeof(priv->key) ); +#else + memset(&(priv->enc_key), 0, sizeof(priv->enc_key) ); + memset(&(priv->dec_key), 0, sizeof(priv->dec_key) ); +#endif + memset(&(priv->iv_enc_key), 0, sizeof(priv->iv_enc_key) ); + memset(&(priv->iv_pad_val), 0, sizeof(priv->iv_pad_val) ); + + /* Let the user choose the degree of encryption: + * Long input keys will pick AES192 or AES256 with more robust but expensive encryption. + * + * The input key always gets hashed to make a more unpredictable use of the key space and + * also to derive some additional material (key for IV encrpytion, IV padding). + * + * The following scheme for key setup was discussed on github: + * https://github.com/ntop/n2n/issues/101 + */ + + /* create a working buffer of maximal occuring hashes size and generate + * the hashes for the aes key material, key_mat_buf_lengh indicates the + * actual "filling level" of the buffer + */ + + if(key_size >= 65) { +#ifdef HAVE_OPENSSL_1_1 + priv->cipher = EVP_aes_256_cbc(); +#endif + aes_key_size_bytes = AES256_KEY_BYTES; + SHA512(key, key_size, key_mat_buf); + key_mat_buf_length = SHA512_DIGEST_LENGTH; + } else if(key_size >= 44) { +#ifdef HAVE_OPENSSL_1_1 + priv->cipher = EVP_aes_192_cbc(); +#endif + aes_key_size_bytes = AES192_KEY_BYTES; + SHA384(key, key_size, key_mat_buf); + /* append a hash of the first hash to create enough material for IV padding */ + SHA256(key_mat_buf, SHA384_DIGEST_LENGTH, key_mat_buf + SHA384_DIGEST_LENGTH); + key_mat_buf_length = SHA384_DIGEST_LENGTH + SHA256_DIGEST_LENGTH; + } else { +#ifdef HAVE_OPENSSL_1_1 + priv->cipher = EVP_aes_128_cbc(); +#endif + aes_key_size_bytes = AES128_KEY_BYTES; + SHA256(key, key_size, key_mat_buf); + /* append a hash of the first hash to create enough material for IV padding */ + SHA256(key_mat_buf, SHA256_DIGEST_LENGTH, key_mat_buf + SHA256_DIGEST_LENGTH); + key_mat_buf_length = 2 * SHA256_DIGEST_LENGTH; + } + + /* is there enough material available? */ + if(key_mat_buf_length < (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE)) { + /* this should never happen */ + traceEvent(TRACE_ERROR, "AES missing %u bits hashed key material\n", + (aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES + TRANSOP_AES_IV_PADDING_SIZE - key_mat_buf_length) * 8); + return(1); + } + + /* setup of key, used for the CBC encryption */ + aes_key_size_bits = 8 * aes_key_size_bytes; + +#ifdef HAVE_OPENSSL_1_1 + memcpy (priv->key, key_mat_buf, aes_key_size_bytes); +#else + AES_set_encrypt_key(key_mat_buf, aes_key_size_bits, &(priv->enc_key)); + AES_set_decrypt_key(key_mat_buf, aes_key_size_bits, &(priv->dec_key)); +#endif + + /* setup of iv_enc_key (AES128 key) and iv_pad_val, used for generating the CBC IV */ + AES_set_encrypt_key(key_mat_buf + aes_key_size_bytes, TRANSOP_AES_IV_KEY_BYTES * 8, &(priv->iv_enc_key)); + memcpy(priv->iv_pad_val, key_mat_buf + aes_key_size_bytes + TRANSOP_AES_IV_KEY_BYTES, TRANSOP_AES_IV_PADDING_SIZE); + + traceEvent(TRACE_DEBUG, "AES %u bits setup completed\n", + aes_key_size_bits); + + return(0); +} + +/* ****************************************************** */ + +static void transop_tick_aes(n2n_trans_op_t * arg, time_t now) { ; } + +/* ****************************************************** */ + +/* AES initialization function */ +int n2n_transop_aes_cbc_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + transop_aes_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + + ttt->tick = transop_tick_aes; + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + priv = (transop_aes_t*) calloc(1, sizeof(transop_aes_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "cannot allocate transop_aes_t memory"); + return(-1); + } + ttt->priv = priv; + +#ifdef HAVE_OPENSSL_1_1 + /* Setup openssl's reusable evp_* contexts for encryption and decryption*/ + if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string()); + return(-1); + } + + if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string()); + return(-1); + } +#endif + + /* Setup the cipher and key */ + return(setup_aes_key(priv, encrypt_key, encrypt_key_len)); +} + +#endif /* N2N_HAVE_AES */ diff --git a/bundles/n2n_ntop_v2/src/transform_cc20.c b/bundles/n2n_ntop_v2/src/transform_cc20.c new file mode 100644 index 00000000..44fd70ba --- /dev/null +++ b/bundles/n2n_ntop_v2/src/transform_cc20.c @@ -0,0 +1,292 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#ifdef HAVE_OPENSSL_1_1 + +#include +#include +#include + +#define N2N_CC20_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_CC20_IVEC_SIZE 16 + +#define CC20_KEY_BYTES (256/8) + +/* ChaCha20 plaintext preamble */ +#define TRANSOP_CC20_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_CC20_PREAMBLE_SIZE (TRANSOP_CC20_VER_SIZE + N2N_CC20_IVEC_SIZE) + +typedef unsigned char n2n_cc20_ivec_t[N2N_CC20_IVEC_SIZE]; + +typedef struct transop_cc20 { + EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* encryption context */ + EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* decryption context */ + const EVP_CIPHER *cipher; /* cipher to use: EVP_chacha20() */ + uint8_t key[32]; /* the pure key data for payload encryption & decryption */ +} transop_cc20_t; + +/* ****************************************************** */ + +static int transop_deinit_cc20(n2n_trans_op_t *arg) { + transop_cc20_t *priv = (transop_cc20_t *)arg->priv; + + EVP_CIPHER_CTX_free(priv->enc_ctx); + EVP_CIPHER_CTX_free(priv->dec_ctx); + + if(priv) + free(priv); + + return 0; +} + +/* ****************************************************** */ + +/* get any erorr message out of openssl + taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling */ +static char *openssl_err_as_string (void) { + BIO *bio = BIO_new (BIO_s_mem ()); + ERR_print_errors (bio); + char *buf = NULL; + size_t len = BIO_get_mem_data (bio, &buf); + char *ret = (char *) calloc (1, 1 + len); + + if(ret) + memcpy (ret, buf, len); + + BIO_free (bio); + return ret; +} + +/* ****************************************************** */ + +static void set_cc20_iv(transop_cc20_t *priv, n2n_cc20_ivec_t ivec) { + // keep in mind the following condition: N2N_CC20_IVEC_SIZE % sizeof(rand_value) == 0 ! + uint64_t rand_value; + for (uint8_t i = 0; i < N2N_CC20_IVEC_SIZE; i += sizeof(rand_value)) { + rand_value = n2n_rand(); + memcpy(ivec + i, &rand_value, sizeof(rand_value)); + } +} + +/* ****************************************************** */ + +/** The ChaCha20 packet format consists of: + * + * - a 8-bit cc20 encoding version in clear text + * - a 128-bit random IV + * - encrypted payload. + * + * [V|IIII|DDDDDDDDDDDDDDDDDDDDD] + * |<---- encrypted ---->| + */ +static int transop_encode_cc20(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len=-1; + transop_cc20_t * priv = (transop_cc20_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE] = {0}; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + TRANSOP_CC20_PREAMBLE_SIZE) <= out_len) { + size_t idx=0; + n2n_cc20_ivec_t enc_ivec = {0}; + + traceEvent(TRACE_DEBUG, "encode_cc20 %lu bytes", in_len); + + /* Encode the ChaCha20 format version. */ + encode_uint8(outbuf, &idx, N2N_CC20_TRANSFORM_VERSION); + + /* Generate and encode the IV. */ + set_cc20_iv(priv, enc_ivec); + encode_buf(outbuf, &idx, &enc_ivec, N2N_CC20_IVEC_SIZE); + + /* Encrypt the assembly contents and write the ciphertext after the iv. */ + /* len is set to the length of the cipher plain text to be encrpyted + which is (in this case) identical to original packet lentgh */ + len = in_len; + + /* The assembly buffer is a source for encrypting data. + * The whole contents of assembly are encrypted. */ + memcpy(assembly, inbuf, in_len); + + EVP_CIPHER_CTX *ctx = priv->enc_ctx; + int evp_len; + int evp_ciphertext_len; + + if(1 == EVP_EncryptInit_ex(ctx, priv->cipher, NULL, priv->key, enc_ivec)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { + if(1 == EVP_EncryptUpdate(ctx, outbuf + TRANSOP_CC20_PREAMBLE_SIZE, &evp_len, assembly, len)) { + evp_ciphertext_len = evp_len; + if(1 == EVP_EncryptFinal_ex(ctx, outbuf + TRANSOP_CC20_PREAMBLE_SIZE + evp_len, &evp_len)) { + evp_ciphertext_len += evp_len; + + if(evp_ciphertext_len != len) + traceEvent(TRACE_ERROR, "encode_cc20 openssl encryption: encrypted %u bytes where %u were expected.\n", + evp_ciphertext_len, len); + } else + traceEvent(TRACE_ERROR, "encode_cc20 openssl final encryption: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_cc20 openssl encrpytion: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_cc20 openssl padding setup: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "encode_cc20 openssl init: %s\n", openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx); + + len += TRANSOP_CC20_PREAMBLE_SIZE; /* size of data carried in UDP. */ + } else + traceEvent(TRACE_ERROR, "encode_cc20 outbuf too small."); + } else + traceEvent(TRACE_ERROR, "encode_cc20 inbuf too big to encrypt."); + + return len; +} + +/* ****************************************************** */ + +/* See transop_encode_cc20 for packet format */ +static int transop_decode_cc20(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len=0; + transop_cc20_t * priv = (transop_cc20_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if(((in_len - TRANSOP_CC20_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in assembly */ + && (in_len >= TRANSOP_CC20_PREAMBLE_SIZE) /* Has at least version, iv */ + ) + { + size_t rem=in_len; + size_t idx=0; + uint8_t cc20_enc_ver=0; + n2n_cc20_ivec_t dec_ivec = {0}; + + /* Get the encoding version to make sure it is supported */ + decode_uint8(&cc20_enc_ver, inbuf, &rem, &idx ); + + if(N2N_CC20_TRANSFORM_VERSION == cc20_enc_ver) { + traceEvent(TRACE_DEBUG, "decode_cc20 %lu bytes", in_len); + len = (in_len - TRANSOP_CC20_PREAMBLE_SIZE); + + /* Get the IV */ + decode_buf((uint8_t *)&dec_ivec, N2N_CC20_IVEC_SIZE, inbuf, &rem, &idx); + + EVP_CIPHER_CTX *ctx = priv->dec_ctx; + int evp_len; + int evp_plaintext_len; + + if(1 == EVP_DecryptInit_ex(ctx, priv->cipher, NULL, priv->key, dec_ivec)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx, 0)) { + if(1 == EVP_DecryptUpdate(ctx, assembly, &evp_len, inbuf + TRANSOP_CC20_PREAMBLE_SIZE, len)) { + evp_plaintext_len = evp_len; + if(1 == EVP_DecryptFinal_ex(ctx, assembly + evp_len, &evp_len)) { + evp_plaintext_len += evp_len; + + if(evp_plaintext_len != len) + traceEvent(TRACE_ERROR, "decode_cc20 openssl decryption: decrypted %u bytes where %u were expected.\n", + evp_plaintext_len, len); + } else + traceEvent(TRACE_ERROR, "decode_cc20 openssl final decryption: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "decode_cc20 openssl decrpytion: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "decode_cc20 openssl padding setup: %s\n", openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "decode_cc20 openssl init: %s\n", openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx); + + memcpy(outbuf, assembly, len); + } else + traceEvent(TRACE_ERROR, "decode_cc20 unsupported ChaCha20 version %u.", cc20_enc_ver); + } else + traceEvent(TRACE_ERROR, "decode_cc20 inbuf wrong size (%ul) to decrypt.", in_len); + + return len; +} + +/* ****************************************************** */ + +static int setup_cc20_key(transop_cc20_t *priv, const uint8_t *key, ssize_t key_size) { + uint8_t key_mat_buf[SHA256_DIGEST_LENGTH]; + + priv->cipher = EVP_chacha20(); + + /* Clear out any old possibly longer key matter. */ + memset(&(priv->key), 0, sizeof(priv->key) ); + /* The input key always gets hashed to make a more unpredictable and more complete use of the key space */ + SHA256(key, key_size, key_mat_buf); + memcpy (priv->key, key_mat_buf, SHA256_DIGEST_LENGTH); + + traceEvent(TRACE_DEBUG, "ChaCha20 key setup completed\n"); + + return(0); +} + +/* ****************************************************** */ + +static void transop_tick_cc20(n2n_trans_op_t * arg, time_t now) { ; } + +/* ****************************************************** */ + +/* ChaCha20 initialization function */ +int n2n_transop_cc20_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + transop_cc20_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_CHACHA20; + + ttt->tick = transop_tick_cc20; + ttt->deinit = transop_deinit_cc20; + ttt->fwd = transop_encode_cc20; + ttt->rev = transop_decode_cc20; + + priv = (transop_cc20_t*) calloc(1, sizeof(transop_cc20_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "cannot allocate transop_cc20_t memory"); + return(-1); + } + ttt->priv = priv; + + /* Setup openssl's reusable evp_* contexts for encryption and decryption*/ + if(!(priv->enc_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "openssl's evp_* encryption context creation: %s\n", openssl_err_as_string()); + return(-1); + } + + if(!(priv->dec_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "openssl's evp_* decryption context creation: %s\n", openssl_err_as_string()); + return(-1); + } + + /* Setup the cipher and key */ + return(setup_cc20_key(priv, encrypt_key, encrypt_key_len)); +} + +#endif /* HAVE_OPENSSL_1_1 */ diff --git a/bundles/n2n_ntop_v2/src/transform_null.c b/bundles/n2n_ntop_v2/src/transform_null.c new file mode 100644 index 00000000..830bcfa2 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/transform_null.c @@ -0,0 +1,87 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" + +static int transop_deinit_null( n2n_trans_op_t * arg ) +{ + /* nothing to deallocate, nothing to release. */ + return 0; +} + +static int transop_encode_null( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int retval = -1; + + traceEvent( TRACE_DEBUG, "encode_null %lu", in_len ); + if ( out_len >= in_len ) + { + memcpy( outbuf, inbuf, in_len ); + retval = in_len; + } + else + { + traceEvent( TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len ); + } + + return retval; +} + +static int transop_decode_null( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int retval = -1; + + traceEvent( TRACE_DEBUG, "decode_null %lu", in_len ); + if ( out_len >= in_len ) + { + memcpy( outbuf, inbuf, in_len ); + retval = in_len; + } + else + { + traceEvent( TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len ); + } + + return retval; +} + +static void transop_tick_null(n2n_trans_op_t * arg, time_t now) {} + +int n2n_transop_null_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + memset(ttt, 0, sizeof(n2n_trans_op_t) ); + + ttt->transform_id = N2N_TRANSFORM_ID_NULL; + ttt->no_encryption = 1; + ttt->deinit = transop_deinit_null; + ttt->tick = transop_tick_null; + ttt->fwd = transop_encode_null; + ttt->rev = transop_decode_null; + + return(0); +} diff --git a/bundles/n2n_ntop_v2/src/transform_speck.c b/bundles/n2n_ntop_v2/src/transform_speck.c new file mode 100644 index 00000000..ede1378c --- /dev/null +++ b/bundles/n2n_ntop_v2/src/transform_speck.c @@ -0,0 +1,218 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#define N2N_SPECK_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_SPECK_IVEC_SIZE 16 + +#define SPECK_KEY_BYTES (256/8) + +/* Speck plaintext preamble */ +#define TRANSOP_SPECK_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_SPECK_PREAMBLE_SIZE (TRANSOP_SPECK_VER_SIZE + N2N_SPECK_IVEC_SIZE) + +typedef unsigned char n2n_speck_ivec_t[N2N_SPECK_IVEC_SIZE]; + +typedef struct transop_speck { + speck_context_t ctx; /* the round keys for payload encryption & decryption */ +} transop_speck_t; + +/* ****************************************************** */ + +static int transop_deinit_speck(n2n_trans_op_t *arg) { + transop_speck_t *priv = (transop_speck_t *)arg->priv; + + if(priv) +#if defined (SPECK_ALIGNED_CTX) + _mm_free (priv); +#else + free (priv); +#endif + return 0; +} + +/* ****************************************************** */ + +static void set_speck_iv(transop_speck_t *priv, n2n_speck_ivec_t ivec) { + // keep in mind the following condition: N2N_SPECK_IVEC_SIZE % sizeof(rand_value) == 0 ! + uint64_t rand_value; + uint8_t i; + + for (i = 0; i < N2N_SPECK_IVEC_SIZE; i += sizeof(rand_value)) { + rand_value = n2n_rand(); + memcpy(ivec + i, &rand_value, sizeof(rand_value)); + } +} + +/* ****************************************************** */ + +/** The Speck packet format consists of: + * + * - a 8-bit speck encoding version in clear text + * - a 128-bit random IV + * - encrypted payload. + * + * [V|IIII|DDDDDDDDDDDDDDDDDDDDD] + * |<---- encrypted ---->| + */ +static int transop_encode_speck(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len=-1; + transop_speck_t * priv = (transop_speck_t *)arg->priv; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) { + size_t idx=0; + n2n_speck_ivec_t enc_ivec = {0}; + + traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len); + + /* Encode the Speck format version. */ + encode_uint8(outbuf, &idx, N2N_SPECK_TRANSFORM_VERSION); + + /* Generate and encode the IV. */ + set_speck_iv(priv, enc_ivec); + encode_buf(outbuf, &idx, &enc_ivec, N2N_SPECK_IVEC_SIZE); + + /* Encrypt the payload and write the ciphertext after the iv. */ + /* len is set to the length of the cipher plain text to be encrpyted + which is (in this case) identical to original packet lentgh */ + len = in_len; + + speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, inbuf, in_len, enc_ivec, +#if defined (SPECK_CTX_BYVAL) + (priv->ctx)); +#else + &(priv->ctx)); +#endif + traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len); + + len += TRANSOP_SPECK_PREAMBLE_SIZE; /* size of data carried in UDP. */ + } else + traceEvent(TRACE_ERROR, "encode_speck outbuf too small."); + } else + traceEvent(TRACE_ERROR, "encode_speck inbuf too big to encrypt."); + + return len; +} + +/* ****************************************************** */ + +/* See transop_encode_speck for packet format */ +static int transop_decode_speck(n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) { + int len=0; + transop_speck_t * priv = (transop_speck_t *)arg->priv; + + if(((in_len - TRANSOP_SPECK_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* Cipher text fits in buffer */ + && (in_len >= TRANSOP_SPECK_PREAMBLE_SIZE) /* Has at least version, iv */ + ) + { + size_t rem=in_len; + size_t idx=0; + uint8_t speck_enc_ver=0; + n2n_speck_ivec_t dec_ivec = {0}; + + /* Get the encoding version to make sure it is supported */ + decode_uint8(&speck_enc_ver, inbuf, &rem, &idx ); + + if(N2N_SPECK_TRANSFORM_VERSION == speck_enc_ver) { + traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len); + len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE); + + /* Get the IV */ + decode_buf((uint8_t *)&dec_ivec, N2N_SPECK_IVEC_SIZE, inbuf, &rem, &idx); + + speck_ctr (outbuf, inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, len, dec_ivec, +#if defined (SPECK_CTX_BYVAL) + (priv->ctx)); +#else + &(priv->ctx)); +#endif + traceEvent(TRACE_DEBUG, "decode_speck: decrypted %u bytes.\n", len); + + } else + traceEvent(TRACE_ERROR, "decode_speck unsupported Speck version %u.", speck_enc_ver); + } else + traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len); + + return len; +} + +/* ****************************************************** */ + +static int setup_speck_key(transop_speck_t *priv, const uint8_t *key, ssize_t key_size) { + + uint8_t key_mat_buf[32] = { 0x00 }; + + /* Clear out any old possibly longer key matter. */ + memset(&(priv->ctx), 0, sizeof(speck_context_t) ); + + /* the input key always gets hashed to make a more unpredictable and more complete use of the key space */ + pearson_hash_256 (key_mat_buf, key, key_size); + + /* expand the key material to the context (= round keys) */ + speck_expand_key (key_mat_buf, &(priv->ctx)); + + traceEvent(TRACE_DEBUG, "Speck key setup completed\n"); + + return(0); +} + +/* ****************************************************** */ + +static void transop_tick_speck(n2n_trans_op_t * arg, time_t now) { ; } + +/* ****************************************************** */ +/* Speck initialization function */ +int n2n_transop_speck_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + transop_speck_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_SPECK; + + ttt->tick = transop_tick_speck; + ttt->deinit = transop_deinit_speck; + ttt->fwd = transop_encode_speck; + ttt->rev = transop_decode_speck; +#if defined (SPECK_ALIGNED_CTX) + priv = (transop_speck_t*) _mm_malloc (sizeof(transop_speck_t), SPECK_ALIGNED_CTX); +#else + priv = (transop_speck_t*) calloc (1, sizeof(transop_speck_t)); +#endif + if(!priv) { + traceEvent(TRACE_ERROR, "cannot allocate transop_speck_t memory"); + return(-1); + } + ttt->priv = priv; + + /* Setup the cipher and key */ + return(setup_speck_key(priv, encrypt_key, encrypt_key_len)); +} + diff --git a/bundles/n2n_ntop_v2/src/transform_tf.c b/bundles/n2n_ntop_v2/src/transform_tf.c new file mode 100644 index 00000000..a630d512 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/transform_tf.c @@ -0,0 +1,212 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#define N2N_TWOFISH_NUM_SA 32 /* space for SAa */ + +#define N2N_TWOFISH_TRANSFORM_VERSION 1 /* version of the transform encoding */ + +typedef struct transop_tf { + TWOFISH* enc_tf; /* tx state */ + TWOFISH* dec_tf; /* rx state */ +} transop_tf_t; + +static int transop_deinit_twofish( n2n_trans_op_t * arg ) { + transop_tf_t *priv = (transop_tf_t *)arg->priv; + + if(priv) { + TwoFishDestroy(priv->enc_tf); /* deallocate TWOFISH */ + TwoFishDestroy(priv->dec_tf); /* deallocate TWOFISH */ + free(priv); + } + + return 0; +} + +#define TRANSOP_TF_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_TF_NONCE_SIZE 4 +#define TRANSOP_TF_SA_SIZE 4 + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) + { + size_t idx=0; + uint32_t sa_id=0; // Not used + + traceEvent(TRACE_DEBUG, "encode_twofish %lu", in_len); + + /* Encode the twofish format version. */ + encode_uint8( outbuf, &idx, N2N_TWOFISH_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa_id ); + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = n2n_rand(); + memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len ); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = TwoFishEncryptRaw( assembly, /* source */ + outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE, + in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */ + priv->enc_tf); + if ( len > 0 ) + { + len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish encryption failed." ); + } + + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." ); + } + + return len; +} + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_decode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=0; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_NONCE_SIZE) ) /* Has at least version, SA and nonce */ + ) { + size_t rem=in_len; + size_t idx=0; + uint8_t tf_enc_ver=0; + uint32_t sa_rx=0; // Not used + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &tf_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_TWOFISH_TRANSFORM_VERSION == tf_enc_ver ) { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + traceEvent(TRACE_DEBUG, "decode_twofish %lu", in_len); + + len = TwoFishDecryptRaw( (void *)(inbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE), + assembly, /* destination */ + (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)), + priv->dec_tf); + + if(len > 0) { + /* Step over 4-byte random nonce value */ + len -= TRANSOP_TF_NONCE_SIZE; /* size of ethernet packet */ + + memcpy( outbuf, + assembly + TRANSOP_TF_NONCE_SIZE, + len ); + } else + traceEvent(TRACE_ERROR, "decode_twofish decryption failed"); + } else + traceEvent( TRACE_ERROR, "decode_twofish unsupported twofish version %u.", tf_enc_ver ); + } else + traceEvent( TRACE_ERROR, "decode_twofish inbuf wrong size (%ul) to decrypt.", in_len ); + + return len; +} + +static void transop_tick_twofish( n2n_trans_op_t * arg, time_t now ) {} + +/* Twofish initialization function */ +int n2n_transop_twofish_init(const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + transop_tf_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + + ttt->tick = transop_tick_twofish; + ttt->deinit = transop_deinit_twofish; + ttt->fwd = transop_encode_twofish; + ttt->rev = transop_decode_twofish; + + priv = (transop_tf_t*) calloc(1, sizeof(transop_tf_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "cannot allocate transop_tf_t memory"); + return(-1); + } + ttt->priv = priv; + + /* This is a preshared key setup. Both Tx and Rx are using the same security association. */ + priv->enc_tf = TwoFishInit(encrypt_key, encrypt_key_len); + priv->dec_tf = TwoFishInit(encrypt_key, encrypt_key_len); + + if((!priv->enc_tf) || (!priv->dec_tf)) { + if(priv->enc_tf) TwoFishDestroy(priv->enc_tf); + if(priv->dec_tf) TwoFishDestroy(priv->dec_tf); + free(priv); + traceEvent(TRACE_ERROR, "TwoFishInit failed"); + return(-2); + } + + return(0); +} diff --git a/bundles/n2n_ntop_v2/src/tuntap_freebsd.c b/bundles/n2n_ntop_v2/src/tuntap_freebsd.c new file mode 100644 index 00000000..d871e895 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/tuntap_freebsd.c @@ -0,0 +1,133 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#ifdef __FreeBSD__ + +void tuntap_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_FREEBSD_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* #ifdef __FreeBSD__ */ diff --git a/bundles/n2n_ntop_v2/src/tuntap_linux.c b/bundles/n2n_ntop_v2/src/tuntap_linux.c new file mode 100644 index 00000000..94b3766d --- /dev/null +++ b/bundles/n2n_ntop_v2/src/tuntap_linux.c @@ -0,0 +1,275 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifdef __linux__ + +#include "n2n.h" + +/* ********************************** */ + +static int setup_ifname(int fd, const char *ifname, const char *ipaddr, + const char *netmask, uint8_t *mac, int mtu) { + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); + + if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); + return(-1); + } + + ifr.ifr_addr.sa_family = AF_INET; + + /* Interface Address */ + inet_pton(AF_INET, ipaddr, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFADDR) failed [%d]: %s", errno, strerror(errno)); + return(-2); + } + + /* Netmask */ + if(netmask && (((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr != 0)) { + inet_pton(AF_INET, netmask, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFNETMASK, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFNETMASK, %s) failed [%d]: %s", netmask, errno, strerror(errno)); + return(-3); + } + } + + /* MTU */ + ifr.ifr_mtu = mtu; + if(ioctl(fd, SIOCSIFMTU, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFMTU) failed [%d]: %s", errno, strerror(errno)); + return(-4); + } + + /* Set up and running */ + if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCGIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return(-5); + } + + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + + if(ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return(-6); + } + + return(0); +} + +/* ********************************** */ + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver and then + * configures it. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open(tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + char *tuntap_device = "/dev/net/tun"; + int ioctl_fd; + struct ifreq ifr; + int rc; + int nl_fd; + char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ + struct iovec iov; + struct sockaddr_nl sa; + int up_and_running = 0; + struct msghdr msg; + + device->fd = open(tuntap_device, O_RDWR); + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "tuntap open() error: %s[%d]. Is the tun kernel module loaded?\n", strerror(errno), errno); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ + strncpy(ifr.ifr_name, dev, IFNAMSIZ-1); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); + + if(rc < 0) { + traceEvent(TRACE_ERROR, "tuntap ioctl(TUNSETIFF, IFF_TAP) error: %s[%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + + /* Store the device name for later reuse */ + strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) ); + + if(device_mac && device_mac[0]) { + /* Use the user-provided MAC */ + str2mac(device->mac_addr, device_mac); + } else { + /* Set an explicit random MAC to know the exact MAC in use. Manually + * reading the MAC address is not safe as it may change internally + * also after the TAP interface UP status has been notified. */ + int i; + + for(i = 0; i < 6; i++) + device->mac_addr[i] = n2n_rand(); + + device->mac_addr[0] &= ~0x01; /* Clear multicast bit */ + device->mac_addr[0] |= 0x02; /* Set locally-assigned bit */ + } + + /* Initialize Netlink socket */ + if((nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + iov.iov_base = nl_buf; + iov.iov_len = sizeof(nl_buf); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_LINK; + sa.nl_pid = getpid(); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + /* Subscribe to interface events */ + if(bind(nl_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + if((ioctl_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + close(nl_fd); + return -1; + } + + if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device->mac_addr, mtu) < 0) { + close(nl_fd); + close(ioctl_fd); + close(device->fd); + return -1; + } + + close(ioctl_fd); + + /* Wait for the up and running notification */ + traceEvent(TRACE_INFO, "Waiting for TAP interface to be up and running..."); + + while(!up_and_running) { + ssize_t len = recvmsg(nl_fd, &msg, 0); + struct nlmsghdr *nh; + + for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { + if(nh->nlmsg_type == NLMSG_ERROR) { + traceEvent(TRACE_DEBUG, "nh->nlmsg_type == NLMSG_ERROR"); + break; + } + + if(nh->nlmsg_type == NLMSG_DONE) + break; + + if(nh->nlmsg_type == NETLINK_GENERIC) { + struct ifinfomsg *ifi = NLMSG_DATA(nh); + + /* NOTE: skipping interface name check, assuming it's our TAP */ + if((ifi->ifi_flags & IFF_UP) && (ifi->ifi_flags & IFF_RUNNING)) { + up_and_running = 1; + traceEvent(TRACE_INFO, "Interface is up and running"); + break; + } + } + } + } + + close(nl_fd); + + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->if_idx = if_nametoindex(dev); + + return(device->fd); +} + +/* *************************************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* *************************************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* *************************************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* *************************************************** */ + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) { + struct ifreq ifr; + int fd; + + if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + return; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, tuntap->dev_name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + if(ioctl(fd, SIOCGIFADDR, &ifr) != -1) + tuntap->ip_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + + close(fd); +} + +#endif /* #ifdef __linux__ */ diff --git a/bundles/n2n_ntop_v2/src/tuntap_netbsd.c b/bundles/n2n_ntop_v2/src/tuntap_netbsd.c new file mode 100644 index 00000000..617e2b26 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/tuntap_netbsd.c @@ -0,0 +1,145 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#ifdef __NetBSD__ + +#include +#include +#include + +void tun_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_NETBSD_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; + struct ifreq req; + + if(dev) { + snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); + device->fd = open(tap_device, O_RDWR); + snprintf(tap_device, sizeof(tap_device), "%s", dev); + } + else { + device->fd = open("/dev/tap", O_RDWR); + if(device->fd >= 0) { + if(ioctl(device->fd, TAPGIFNAME, &req) == -1) { + traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); + close(device->fd); + return(-1); + } + else { + snprintf(tap_device, sizeof(tap_device), req.ifr_name); + } + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); + return(-1); + } else { + char cmd[256]; + FILE *fd; + + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + + device->ip_addr = inet_addr(device_ip); + + if( device_mac && device_mac[0] != '\0') { + /* Set the hw address before bringing the if up. */ + snprintf(cmd, sizeof(cmd), "ifconfig %s link %s active", + tap_device, device_mac); + system(cmd); + } + + snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s mtu %d up", + tap_device, device_ip, device_mask, mtu); + system(cmd); + + traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", + tap_device, device_ip, device_mask); + + /* Read MAC address */ + snprintf(cmd, sizeof(cmd), "ifconfig %s |grep address|cut -c 11-28", tap_device); + /* traceEvent(TRACE_INFO, "%s", cmd); */ + + fd = popen(cmd, "r"); + if(fd < 0) { + tun_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + char buf[256]; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address [%s]", tap_device, cmd); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* #ifdef __NetBSD__ */ diff --git a/bundles/n2n_ntop_v2/src/tuntap_osx.c b/bundles/n2n_ntop_v2/src/tuntap_osx.c new file mode 100644 index 00000000..ef166ff8 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/tuntap_osx.c @@ -0,0 +1,134 @@ +/** + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#ifdef __APPLE__ + +void tun_close(tuntap_dev *device); + +/* ********************************** */ + +#define N2N_OSX_TAPDEVICE_SIZE 32 +int tuntap_open(tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + int i; + char tap_device[N2N_OSX_TAPDEVICE_SIZE]; + + for (i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open any tap devices /dev/tap0 through /dev/tap254. Is this user properly authorized to access those descriptors?"); + traceEvent(TRACE_ERROR, "Please read https://github.com/ntop/n2n/blob/dev/doc/macOS.md"); + return(-1); + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if ( device_mac && device_mac[0] != '\0' ) + { + /* FIXME - This is not tested. Might be wrong syntax for OS X */ + + /* Set the hw address before bringing the if up. */ + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", + i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", + i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", + i, device_ip, device_mask); + + /* Read MAC address */ + + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + /* traceEvent(TRACE_INFO, "%s", buf); */ + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return(-1); + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + /* read_mac(dev, device->mac_addr); */ + return(device->fd); +} + +/* ********************************** */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(read(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { + return(write(tuntap->fd, buf, len)); +} + +/* ********************************** */ + +void tuntap_close(struct tuntap_dev *tuntap) { + close(tuntap->fd); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +#endif /* __APPLE__ */ diff --git a/bundles/n2n_ntop_v2/src/twofish.c b/bundles/n2n_ntop_v2/src/twofish.c new file mode 100644 index 00000000..f1e1fbc1 --- /dev/null +++ b/bundles/n2n_ntop_v2/src/twofish.c @@ -0,0 +1,1015 @@ +/* $Id: twofish.c,v 2.0 2002/08/11 22:32:25 fknobbe Exp $ + * + * + * Copyright (C) 1997-2000 The Cryptix Foundation Limited. + * Copyright (C) 2000 Farm9. + * Copyright (C) 2001 Frank Knobbe. + * All rights reserved. + * + * For Cryptix code: + * Use, modification, copying and distribution of this software is subject + * the terms and conditions of the Cryptix General Licence. You should have + * received a copy of the Cryptix General Licence along with this library; + * if not, you can download a copy from http://www.cryptix.org/ . + * + * For Farm9: + * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and + * ciphertext stealing technique, added AsciiTwofish class for easy encryption + * decryption of text strings + * + * Frank Knobbe : + * --- April 2001, converted from C++ to C, prefixed global variables + * with TwoFish, substituted some defines, changed functions to make use of + * variables supplied in a struct, modified and added routines for modular calls. + * Cleaned up the code so that defines are used instead of fixed 16's and 32's. + * Created two general purpose crypt routines for one block and multiple block + * encryption using Joh's CBC code. + * Added crypt routines that use a header (with a magic and data length). + * (Basically a major rewrite). + * + * Note: Routines labeled _TwoFish are private and should not be used + * (or with extreme caution). + * + */ + +#ifndef __TWOFISH_LIBRARY_SOURCE__ +#define __TWOFISH_LIBRARY_SOURCE__ + +#include "n2n.h" + +/* Fixed 8x8 permutation S-boxes */ +static const uint8_t TwoFish_P[2][256] = + { + { /* p0 */ + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0 + }, + { /* p1 */ + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 + } + }; + +static bool TwoFish_MDSready=FALSE; +static uint32_t TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */ + + +#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0)) +#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0)) + +#define TwoFish_Mx_1(x) ((uint32_t)(x)) /* force result to dword so << will work */ +#define TwoFish_Mx_X(x) ((uint32_t)((x)^TwoFish_LFSR2(x))) /* 5B */ +#define TwoFish_Mx_Y(x) ((uint32_t)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */ +#define TwoFish_RS_rem(x) { uint8_t b=(uint8_t)(x>>24); uint32_t g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; uint32_t g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; } + +/*#define TwoFish__b(x,N) (((uint8_t *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */ + +#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of uint32_t */ +#define TwoFish_b1(x) TwoFish__b(x,1) +#define TwoFish_b2(x) TwoFish__b(x,2) +#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of uint32_t */ + +uint8_t TwoFish__b(uint32_t x,int n) +{ n&=3; + while(n-->0) + x>>=8; + return (uint8_t)x; +} + + +/* TwoFish Initialization + * + * This routine generates a global data structure for use with TwoFish, + * initializes important values (such as subkeys, sBoxes), generates subkeys + * and precomputes the MDS matrix if not already done. + * + * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') + * + * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. + * This pointer is used with all other crypt functions. + */ + +TWOFISH *TwoFishInit(const uint8_t *userkey, uint32_t keysize) +{ TWOFISH *tfdata; + int i,x,m; + uint8_t tkey[TwoFish_KEY_LENGTH+40]; + + memset( tkey, 0, TwoFish_KEY_LENGTH+40 ); + tfdata=(TWOFISH *)malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */ + if(tfdata!=NULL) + { + + /* Changes here prevented a dangerous random key segment for keys of length < TwoFish_KEY_LENGTH */ + if(keysize > 0) + { + memcpy( tkey, userkey, keysize ); /* The rest will be zeros */ + } + else + { + memcpy( tkey, TwoFish_DEFAULT_PW, TwoFish_DEFAULT_PW_LEN ); /* if no key defined, use default password */ + } + + /* This loop is awful - surely a loop on memcpy() would be clearer and more efficient */ + for(i=0,x=0,m=keysize;ikey[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */ + if(x==m) + x=0; + } + + if(!TwoFish_MDSready) + _TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */ + _TwoFish_MakeSubKeys(tfdata); /* generate subkeys */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC */ + tfdata->output=NULL; /* nothing to output yet */ + tfdata->dontflush=FALSE; /* reset decrypt skip block flag */ + } + return tfdata; /* return the data pointer */ +} + + +void TwoFishDestroy(TWOFISH *tfdata) +{ if(tfdata!=NULL) + free(tfdata); +} + + +/* en/decryption with CBC mode */ +uint32_t _TwoFish_CryptRawCBC(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ uint32_t rl; + + rl=len; /* remember how much data to crypt. */ + while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */ + { _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */ + in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */ + out+=TwoFish_BLOCK_SIZE; + len-=TwoFish_BLOCK_SIZE; + } + if(len>0) /* if we have less than a block left... */ + _TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */ + if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */ + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */ + /* ...remaining bytes of the buffer */ + return rl; +} + +/* en/decryption on one block only */ +uint32_t _TwoFish_CryptRaw16(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ /* qBlockPlain already zero'ed through ResetCBC */ + memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */ + _TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */ + memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */ + return TwoFish_BLOCK_SIZE; +} + +/* en/decryption without reset of CBC and output assignment */ +uint32_t _TwoFish_CryptRaw(uint8_t *in,uint8_t *out,uint32_t len,bool decrypt,TWOFISH *tfdata) +{ + if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */ + { if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */ + return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */ + else + return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */ + } + return 0; +} + + +/* TwoFish Raw Encryption + * + * Does not use header, but does use CBC (if more than one block has to be encrypted). + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the buffer receiving the ciphertext. + * The length of the plaintext buffer. + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +uint32_t TwoFishEncryptRaw(uint8_t *in, + uint8_t *out, + uint32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */ +} + +/* TwoFish Raw Decryption + * + * Does not use header, but does use CBC (if more than one block has to be decrypted). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the buffer receiving the plaintext. + * The length of the ciphertext buffer (at least one cipher block). + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +uint32_t TwoFishDecryptRaw(uint8_t *in, + uint8_t *out, + uint32_t len, + TWOFISH *tfdata) +{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ + tfdata->output=out; /* output straight into output buffer. */ + return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */ +} + +/* TwoFish Free + * + * Free's the allocated buffer. + * + * Input: Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishFree(TWOFISH *tfdata) +{ if(tfdata->output!=NULL) /* if a valid buffer is present... */ + { free(tfdata->output); /* ...then we free it for you... */ + tfdata->output=NULL; /* ...and mark as such. */ + } +} + +/* TwoFish Set Output + * + * If you want to allocate the output buffer yourself, + * then you can set it with this function. + * + * Input: Pointer to your output buffer + * Pointer to the TwoFish structure + * + * Output: (none) + */ + +void TwoFishSetOutput(uint8_t *outp,TWOFISH *tfdata) +{ tfdata->output=outp; /* (do we really need a function for this?) */ +} + +/* TwoFish Alloc + * + * Allocates enough memory for the output buffer that would be required + * + * Input: Length of the plaintext. + * Boolean flag for BinHex Output. + * Pointer to the TwoFish structure. + * + * Output: Returns a pointer to the memory allocated. + */ + +void *TwoFishAlloc(uint32_t len,bool binhex,bool decrypt,TWOFISH *tfdata) +{ + /* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */ + if(decrypt) /* if decrypting... */ + { if(binhex) /* ...and input is binhex encoded... */ + len/=2; /* ...use half as much for output. */ + len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */ + } + else + { len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */ + if(binhex) + len*=2; /* ...and doubled if output is to be binhexed. */ + } + tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */ + + return tfdata->output; /* ...and return to caller. */ +} + +/* bin2hex and hex2bin conversion */ +void _TwoFish_BinHex(uint8_t *buf,uint32_t len,bool bintohex) +{ uint8_t *pi,*po,c; + + if(bintohex) + { for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */ + { c=*pi; /* grab value. */ + c&=15; /* use lower 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po--=c; /* set the lower nibble. */ + c=*pi; /* grab value again. */ + c>>=4; /* right shift 4 bits. */ + c&=15; /* make sure we only have 4 bits. */ + if(c>9) /* convert to ascii. */ + c+=('a'-10); + else + c+='0'; + *po=c; /* set the higher nibble. */ + } /* and keep going. */ + } + else + { for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */ + { c=tolower(*pi++)-'0'; /* grab higher nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po=c<<4; /* left shit 4 bits. */ + c=tolower(*pi)-'0'; /* grab lower nibble. */ + if(c>9) /* convert to value. */ + c-=('0'-9); + *po|=c; /* and add to value. */ + } + } +} + + +/* TwoFish Encryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will include a small 'header' + * containing the magic and some salt. That way the decrypt routine can check if the + * packet got decrypted successfully, and return 0 instead of garbage. + * + * Input: Pointer to the buffer of the plaintext to be encrypted. + * Pointer to the pointer to the buffer receiving the ciphertext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the plaintext buffer. + * Can be -1 if the input is a null terminated string, in which case we'll count for you. + * Boolean flag for BinHex Output (if used, output will be twice as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes encrypted if successful, otherwise 0. + */ + +uint32_t TwoFishEncrypt(uint8_t *in, + uint8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ uint32_t ilen,olen; + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { tfdata->output=*out; /* set output buffer. */ + tfdata->header.salt=n2n_rand()*65536+n2n_rand(); /* toss in some salt. */ + tfdata->header.length[0]= (uint8_t)(ilen); + tfdata->header.length[1]= (uint8_t)(ilen>>8); + tfdata->header.length[2]= (uint8_t)(ilen>>16); + tfdata->header.length[3]= (uint8_t)(ilen>>24); + memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */ + olen=TwoFish_BLOCK_SIZE; /* set output counter. */ + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag */ + _TwoFish_BlockCrypt((uint8_t *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */ + olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */ + if(binhex) /* if binhex... */ + { _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */ + olen*=2; /* ...and size twice as large. */ + } + tfdata->output=*out; + return olen; + } + } + return 0; +} + +/* TwoFish Decryption + * + * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, + * this routine will alloc the memory. In addition, it will check the small 'header' + * containing the magic. If magic does not match we return 0. Otherwise we return the + * amount of bytes decrypted (should be the same as the length in the header). + * + * Input: Pointer to the buffer of the ciphertext to be decrypted. + * Pointer to the pointer to the buffer receiving the plaintext. + * The pointer either points to user allocated output buffer space, or to NULL, in which case + * this routine will set the pointer to the buffer allocated through the struct. + * The length of the ciphertext buffer. + * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. + * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). + * Note: BinHex conversion overwrites (converts) input buffer! + * The TwoFish structure. + * + * Output: The amount of bytes decrypted if successful, otherwise 0. + */ + +uint32_t TwoFishDecrypt(uint8_t *in, + uint8_t **out, + signed long len, + bool binhex, + TWOFISH *tfdata) +{ uint32_t ilen,elen,olen; + const uint8_t cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC; + uint8_t *tbuf; + + + +#if 0 +/* This is so broken it doesn't deserve to live. */ + if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ + ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ + else + ilen=len; /* ...otherwise we trust you supply a correct length. */ +#endif + + ilen = len; + + if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ + { if(*out==NULL) /* if OUT points to a NULL pointer... */ + *out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */ + if(*out!=NULL) + { if(binhex) /* if binhex... */ + { _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */ + ilen/=2; /* ...and size half as much. */ + } + _TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */ + + tbuf=(uint8_t *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */ + if(tbuf==NULL) + return 0; + tfdata->output=tbuf; /* set output to temp buffer. */ + + olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */ + memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */ + tfdata->output=*out; + for(elen=0;elenheader.magic[elen]!=cmagic[elen]) + break; + if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */ + { elen=(tfdata->header.length[0]) | + (tfdata->header.length[1])<<8 | + (tfdata->header.length[2])<<16 | + (tfdata->header.length[3])<<24; /* .. we know how much to expect. */ + if(elen>olen) /* adjust if necessary. */ + elen=olen; + memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */ + free(tbuf); + return elen; + } + free(tbuf); + } + } + return 0; +} + +void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */ +{ uint32_t m1[2]; + uint32_t mX[2]; + uint32_t mY[2]; + uint32_t i, j; + + for (i = 0; i < 256; i++) + { j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */ + m1[0] = j; + mX[0] = TwoFish_Mx_X( j ) & 0xFF; + mY[0] = TwoFish_Mx_Y( j ) & 0xFF; + + j = TwoFish_P[1][i] & 0xFF; + m1[1] = j; + mX[1] = TwoFish_Mx_X( j ) & 0xFF; + mY[1] = TwoFish_Mx_Y( j ) & 0xFF; + + TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */ + mX[TwoFish_P_00] << 8 | + mY[TwoFish_P_00] << 16 | + mY[TwoFish_P_00] << 24; + TwoFish_MDS[1][i] = mY[TwoFish_P_10] | + mY[TwoFish_P_10] << 8 | + mX[TwoFish_P_10] << 16 | + m1[TwoFish_P_10] << 24; + TwoFish_MDS[2][i] = mX[TwoFish_P_20] | + mY[TwoFish_P_20] << 8 | + m1[TwoFish_P_20] << 16 | + mY[TwoFish_P_20] << 24; + TwoFish_MDS[3][i] = mX[TwoFish_P_30] | + m1[TwoFish_P_30] << 8 | + mY[TwoFish_P_30] << 16 | + mX[TwoFish_P_30] << 24; + } + TwoFish_MDSready=TRUE; +} + + +void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */ +{ uint32_t k64Cnt = TwoFish_KEY_LENGTH / 8; + uint32_t k32e[4]; /* even 32-bit entities */ + uint32_t k32o[4]; /* odd 32-bit entities */ + uint32_t sBoxKey[4]; + uint32_t offset,i,j; + uint32_t A, B, q=0; + uint32_t k0,k1,k2,k3; + uint32_t b0,b1,b2,b3; + + /* split user key material into even and odd 32-bit entities and */ + /* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */ + + + for (offset=0,i=0,j=k64Cnt-1;i<4 && offsetkey[offset++]; + k32e[i]|= tfdata->key[offset++]<<8; + k32e[i]|= tfdata->key[offset++]<<16; + k32e[i]|= tfdata->key[offset++]<<24; + k32o[i] = tfdata->key[offset++]; + k32o[i]|= tfdata->key[offset++]<<8; + k32o[i]|= tfdata->key[offset++]<<16; + k32o[i]|= tfdata->key[offset++]<<24; + sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */ + } + + /* compute the round decryption subkeys for PHT. these same subkeys */ + /* will be used in encryption but will be applied in reverse order. */ + i=0; + while(i < TwoFish_TOTAL_SUBKEYS) + { A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */ + q += TwoFish_SK_BUMP; + + B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */ + q += TwoFish_SK_BUMP; + + B = B << 8 | B >> 24; + + A += B; + tfdata->subKeys[i++] = A; /* combine with a PHT */ + + A += B; + tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL); + } + + /* fully expand the table for speed */ + k0 = sBoxKey[0]; + k1 = sBoxKey[1]; + k2 = sBoxKey[2]; + k3 = sBoxKey[3]; + + for (i = 0; i < 256; i++) + { b0 = b1 = b2 = b3 = i; + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)]; + tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)]; + tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)]; + tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3); + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys */ + tfdata->sBox[ 2*i ]= + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^ + TwoFish_b0(k1)]) ^ TwoFish_b0(k0)]; + + tfdata->sBox[ 2*i+1]= + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^ + TwoFish_b1(k1)]) ^ TwoFish_b1(k0)]; + + tfdata->sBox[0x200+2*i ]= + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^ + TwoFish_b2(k1)]) ^ TwoFish_b2(k0)]; + + tfdata->sBox[0x200+2*i+1]= + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^ + TwoFish_b3(k1)]) ^ TwoFish_b3(k0)]; + } + } +} + + +/** + * Encrypt or decrypt exactly one block of plaintext in CBC mode. + * Use "ciphertext stealing" technique described on pg. 196 + * of "Applied Cryptography" to encrypt the final partial + * (i.e. <16 byte) block if necessary. + * + * jojo: the "ciphertext stealing" requires we read ahead and have + * special handling for the last two blocks. Because of this, the + * output from the TwoFish algorithm is handled internally here. + * It would be better to have a higher level handle this as well as + * CBC mode. Unfortunately, I've mixed the two together, which is + * pretty crappy... The Java version separates these out correctly. + * + * fknobbe: I have reduced the CBC mode to work on memory buffer only. + * Higher routines should use an intermediate buffer and handle + * their output seperately (mainly so the data can be flushed + * in one chunk, not seperate 16 byte blocks...) + * + * @param in The plaintext. + * @param out The ciphertext + * @param size how much to encrypt + * @param tfdata: Pointer to the global data structure containing session keys. + * @return none + */ +void _TwoFish_BlockCrypt(uint8_t *in,uint8_t *out,uint32_t size,int decrypt,TWOFISH *tfdata) +{ uint8_t PnMinusOne[TwoFish_BLOCK_SIZE]; + uint8_t CnMinusOne[TwoFish_BLOCK_SIZE]; + uint8_t CBCplusCprime[TwoFish_BLOCK_SIZE]; + uint8_t Pn[TwoFish_BLOCK_SIZE]; + uint8_t *p,*pout; + uint32_t i; + + /* here is where we implement CBC mode and cipher block stealing */ + if(size==TwoFish_BLOCK_SIZE) + { /* if we are encrypting, CBC means we XOR the plain text block with the */ + /* previous cipher text block before encrypting */ + if(!decrypt && tfdata->qBlockDefined) + { for(p=in,i=0;iqBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */ + } + else + memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */ + + /* TwoFish block level encryption or decryption */ + _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); + + /* if we are decrypting, CBC means we XOR the result of the decryption */ + /* with the previous cipher text block to get the resulting plain text */ + if(decrypt && tfdata->qBlockDefined) + { for (p=out,i=0;iqBlockPlain[i]; + } + + /* save the input and output blocks, since CBC needs these for XOR */ + /* operations */ + _TwoFish_qBlockPush(Pn,out,tfdata); + } + else + { /* cipher block stealing, we are at Pn, */ + /* but since Cn-1 must now be replaced with CnC' */ + /* we pop it off, and recalculate Cn-1 */ + + if(decrypt) + { /* We are on an odd block, and had to do cipher block stealing, */ + /* so the PnMinusOne has to be derived differently. */ + + /* First we decrypt it into CBC and C' */ + _TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata); + + /* we then xor the first few bytes with the "in" bytes (Cn) */ + /* to recover Pn, which we put in out */ + for(p=in,pout=out,i=0;iprevCipher[i]; + + /* So at this point, out has PnMinusOne */ + _TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata); + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(out,size,tfdata); + } + else + { _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata); + memset(Pn,0,TwoFish_BLOCK_SIZE); + memcpy(Pn,in,size); + for(i=0;iqBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + _TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */ + } + tfdata->qBlockDefined=FALSE; + } +} + +void _TwoFish_qBlockPush(uint8_t *p,uint8_t *c,TWOFISH *tfdata) +{ if(tfdata->qBlockDefined) + _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); + memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE); + memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE); + tfdata->qBlockDefined=TRUE; +} + +void _TwoFish_qBlockPop(uint8_t *p,uint8_t *c,TWOFISH *tfdata) +{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE ); + memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE ); + tfdata->qBlockDefined=FALSE; +} + +/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */ +void _TwoFish_ResetCBC(TWOFISH *tfdata) +{ tfdata->qBlockDefined=FALSE; + memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE); +} + +void _TwoFish_FlushOutput(uint8_t *b,uint32_t len,TWOFISH *tfdata) +{ uint32_t i; + + for(i=0;idontflush;i++) + *tfdata->output++ = *b++; + tfdata->dontflush=FALSE; +} + +void _TwoFish_BlockCrypt16(uint8_t *in,uint8_t *out,bool decrypt,TWOFISH *tfdata) +{ uint32_t x0,x1,x2,x3; + uint32_t k,t0,t1,R; + + + x0=*in++; + x0|=(*in++ << 8 ); + x0|=(*in++ << 16); + x0|=(*in++ << 24); + x1=*in++; + x1|=(*in++ << 8 ); + x1|=(*in++ << 16); + x1|=(*in++ << 24); + x2=*in++; + x2|=(*in++ << 8 ); + x2|=(*in++ << 16); + x2|=(*in++ << 24); + x3=*in++; + x3|=(*in++ << 8 ); + x3|=(*in++ << 16); + x3|=(*in++ << 24); + + if(decrypt) + { x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */ + x1 ^= tfdata->subKeys[5]; + x2 ^= tfdata->subKeys[6]; + x3 ^= tfdata->subKeys[7]; + + k = 7+(TwoFish_ROUNDS*2); + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x3 = x3 >> 1 | x3 << 31; + x2 = x2 << 1 | x2 >> 31; + x2 ^= t0 + t1 + tfdata->subKeys[k--]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; + x1 = x1 >> 1 | x1 << 31; + x0 = x0 << 1 | x0 >> 31; + x0 ^= t0 + t1 + tfdata->subKeys[k--]; + } + + x2 ^= tfdata->subKeys[0]; + x3 ^= tfdata->subKeys[1]; + x0 ^= tfdata->subKeys[2]; + x1 ^= tfdata->subKeys[3]; + } + else + { x0 ^= tfdata->subKeys[0]; + x1 ^= tfdata->subKeys[1]; + x2 ^= tfdata->subKeys[2]; + x3 ^= tfdata->subKeys[3]; + + k = 8; + for (R = 0; R < TwoFish_ROUNDS; R += 2) + { t0 = _TwoFish_Fe320( tfdata->sBox, x0); + t1 = _TwoFish_Fe323( tfdata->sBox, x1); + x2 ^= t0 + t1 + tfdata->subKeys[k++]; + x2 = x2 >> 1 | x2 << 31; + x3 = x3 << 1 | x3 >> 31; + x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + + t0 = _TwoFish_Fe320( tfdata->sBox, x2); + t1 = _TwoFish_Fe323( tfdata->sBox, x3); + x0 ^= t0 + t1 + tfdata->subKeys[k++]; + x0 = x0 >> 1 | x0 << 31; + x1 = x1 << 1 | x1 >> 31; + x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; + } + + x2 ^= tfdata->subKeys[4]; + x3 ^= tfdata->subKeys[5]; + x0 ^= tfdata->subKeys[6]; + x1 ^= tfdata->subKeys[7]; + } + + *out++ = (uint8_t)(x2 ); + *out++ = (uint8_t)(x2 >> 8); + *out++ = (uint8_t)(x2 >> 16); + *out++ = (uint8_t)(x2 >> 24); + + *out++ = (uint8_t)(x3 ); + *out++ = (uint8_t)(x3 >> 8); + *out++ = (uint8_t)(x3 >> 16); + *out++ = (uint8_t)(x3 >> 24); + + *out++ = (uint8_t)(x0 ); + *out++ = (uint8_t)(x0 >> 8); + *out++ = (uint8_t)(x0 >> 16); + *out++ = (uint8_t)(x0 >> 24); + + *out++ = (uint8_t)(x1 ); + *out++ = (uint8_t)(x1 >> 8); + *out++ = (uint8_t)(x1 >> 16); + *out++ = (uint8_t)(x1 >> 24); +} + +/** + * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box + * 32-bit entity from two key material 32-bit entities. + * + * @param k0 1st 32-bit entity. + * @param k1 2nd 32-bit entity. + * @return Remainder polynomial generated using RS code + */ +uint32_t _TwoFish_RS_MDS_Encode(uint32_t k0,uint32_t k1) +{ uint32_t i,r; + + for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */ + TwoFish_RS_rem(r); + r ^= k0; + for(i=0;i<4;i++) + TwoFish_RS_rem(r); + + return r; +} + +uint32_t _TwoFish_F32(uint32_t k64Cnt,uint32_t x,uint32_t *k32) +{ uint8_t b0,b1,b2,b3; + uint32_t k0,k1,k2,k3,result = 0; + + b0=TwoFish_b0(x); + b1=TwoFish_b1(x); + b2=TwoFish_b2(x); + b3=TwoFish_b3(x); + k0=k32[0]; + k1=k32[1]; + k2=k32[2]; + k3=k32[3]; + + switch (k64Cnt & 3) + { case 1: /* 64-bit keys */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)]; + break; + case 0: /* 256-bit keys (same as 4) */ + b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3); + b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3); + b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3); + b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3); + + case 3: /* 192-bit keys */ + b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2); + b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2); + b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2); + b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2); + case 2: /* 128-bit keys (optimize for this case) */ + result = + TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^ + TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^ + TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^ + TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)]; + break; + } + return result; +} + +uint32_t _TwoFish_Fe320(uint32_t *lsBox,uint32_t x) +{ return lsBox[ TwoFish_b0(x)<<1 ]^ + lsBox[ ((TwoFish_b1(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b2(x)<<1) ]^ + lsBox[0x200+((TwoFish_b3(x)<<1)|1)]; +} + +uint32_t _TwoFish_Fe323(uint32_t *lsBox,uint32_t x) +{ return lsBox[ (TwoFish_b3(x)<<1) ]^ + lsBox[ ((TwoFish_b0(x)<<1)|1)]^ + lsBox[0x200+ (TwoFish_b1(x)<<1) ]^ + lsBox[0x200+((TwoFish_b2(x)<<1)|1)]; +} + +uint32_t _TwoFish_Fe32(uint32_t *lsBox,uint32_t x,uint32_t R) +{ return lsBox[ 2*TwoFish__b(x,R ) ]^ + lsBox[ 2*TwoFish__b(x,R+1)+1]^ + lsBox[0x200+2*TwoFish__b(x,R+2) ]^ + lsBox[0x200+2*TwoFish__b(x,R+3)+1]; +} + + +#endif + +/* ******************************************* */ +#if defined TWOFISH_UNIT_TEST +#include + +#define TEST_DATA_SIZE 327 + +int main(int argc, char* argv[]) +{ + int i; + int n; + + char outbuf[4096]; + char * outp = outbuf; + + uint8_t key[] = { 0xfc, 0x77, 0x1a, 0xda, 0xaa }; + TWOFISH *tfa = TwoFishInit( key, 5 ); + TWOFISH *tfb = TwoFishInit( key, 5 ); + + uint8_t out[2048], out2[2048]; + uint8_t in[TEST_DATA_SIZE]; + + for ( i=0; i + * + */ + +/** Routines for encoding and decoding n2n packets on the wire. + * + * encode_X(base,idx,v) prototypes are inspired by the erlang internal + * encoding model. Passing the start of a buffer in base and a pointer to an + * integer (initially set to zero). Each encode routine increases idx by the + * amount written and returns the amount written. In this way complex sequences + * of encodings can be represented cleanly. See encode_register() for an + * example. + */ + +#include "n2n_wire.h" +#include + +int encode_uint8( uint8_t * base, + size_t * idx, + const uint8_t v ) +{ + *(base + (*idx)) = (v & 0xff); + ++(*idx); + return 1; +} + +int decode_uint8( uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 1 ) { return 0; } + + *out = ( base[*idx] & 0xff ); + ++(*idx); + --(*rem); + return 1; +} + +int encode_uint16( uint8_t * base, + size_t * idx, + const uint16_t v ) +{ + *(base + (*idx)) = ( v >> 8) & 0xff; + *(base + (1 + *idx)) = ( v & 0xff ); + *idx += 2; + return 2; +} + +int decode_uint16( uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 2 ) { return 0; } + + *out = ( base[*idx] & 0xff ) << 8; + *out |= ( base[1 + *idx] & 0xff ); + *idx += 2; + *rem -= 2; + return 2; +} + +int encode_uint32( uint8_t * base, + size_t * idx, + const uint32_t v ) +{ + *(base + (0 + *idx)) = ( v >> 24) & 0xff; + *(base + (1 + *idx)) = ( v >> 16) & 0xff; + *(base + (2 + *idx)) = ( v >> 8) & 0xff; + *(base + (3 + *idx)) = ( v & 0xff ); + *idx += 4; + return 4; +} + +int decode_uint32( uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < 4 ) { return 0; } + + *out = ( base[0 + *idx] & 0xff ) << 24; + *out |= ( base[1 + *idx] & 0xff ) << 16; + *out |= ( base[2 + *idx] & 0xff ) << 8; + *out |= ( base[3 + *idx] & 0xff ); + *idx += 4; + *rem -= 4; + return 4; +} + +int encode_buf( uint8_t * base, + size_t * idx, + const void * p, + size_t s) +{ + memcpy( (base + (*idx)), p, s ); + *idx += s; + return s; +} + +/* Copy from base to out of size bufsize */ +int decode_buf( uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + if (*rem < bufsize ) { return 0; } + + memcpy( out, (base + *idx), bufsize ); + *idx += bufsize; + *rem -= bufsize; + return bufsize; +} + + + +int encode_mac( uint8_t * base, + size_t * idx, + const n2n_mac_t m ) +{ + return encode_buf( base, idx, m, N2N_MAC_SIZE ); +} + +int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passing a n2n_mac_t */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + return decode_buf( out, N2N_MAC_SIZE, base, rem, idx ); +} + + + +int encode_common( uint8_t * base, + size_t * idx, + const n2n_common_t * common ) +{ + uint16_t flags=0; + encode_uint8( base, idx, N2N_PKT_VERSION ); + encode_uint8( base, idx, common->ttl ); + + flags = common->pc & N2N_FLAGS_TYPE_MASK; + flags |= common->flags & N2N_FLAGS_BITS_MASK; + + encode_uint16( base, idx, flags ); + encode_buf( base, idx, common->community, N2N_COMMUNITY_SIZE ); + + return -1; +} + +int decode_common( n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t idx0=*idx; + uint8_t dummy=0; + decode_uint8( &dummy, base, rem, idx ); + + if ( N2N_PKT_VERSION != dummy ) + { + return -1; + } + + decode_uint8( &(out->ttl), base, rem, idx ); + decode_uint16( &(out->flags), base, rem, idx ); + out->pc = ( out->flags & N2N_FLAGS_TYPE_MASK ); + out->flags &= N2N_FLAGS_BITS_MASK; + + decode_buf( out->community, N2N_COMMUNITY_SIZE, base, rem, idx ); + + return (*idx - idx0); +} + + +int encode_sock( uint8_t * base, + size_t * idx, + const n2n_sock_t * sock ) +{ + int retval=0; + uint16_t f; + + switch (sock->family) + { + case AF_INET: + { + f = 0; + retval += encode_uint16(base,idx,f); + retval += encode_uint16(base,idx,sock->port); + retval += encode_buf(base,idx,sock->addr.v4,IPV4_SIZE); + break; + } + case AF_INET6: + { + f = 0x8000; + retval += encode_uint16(base,idx,f); + retval += encode_uint16(base,idx,sock->port); + retval += encode_buf(base,idx,sock->addr.v6,IPV6_SIZE); + break; + } + default: + retval=-1; + } + + return retval; +} + + +int decode_sock( n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t * idx0=idx; + uint16_t f=0; + + decode_uint16( &f, base, rem, idx ); + + if( f & 0x8000 ) + { + /* IPv6 */ + sock->family = AF_INET6; + decode_uint16( &(sock->port), base, rem, idx ); + decode_buf( sock->addr.v6, IPV6_SIZE, base, rem, idx ); + } + else + { + /* IPv4 */ + sock->family = AF_INET; + decode_uint16( &(sock->port), base, rem, idx ); + memset( sock->addr.v6, 0, IPV6_SIZE ); /* so memcmp() works for equality. */ + decode_buf( sock->addr.v4, IPV4_SIZE, base, rem, idx ); + } + + return (idx-idx0); +} + +int encode_REGISTER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->srcMac ); + retval += encode_mac( base, idx, reg->dstMac ); + if ( 0 != reg->sock.family ) + { + retval += encode_sock( base, idx, &(reg->sock) ); + } + + return retval; +} + +int decode_REGISTER( n2n_REGISTER_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->srcMac, base, rem, idx ); + retval += decode_mac( reg->dstMac, base, rem, idx ); + + if ( cmn->flags & N2N_FLAGS_SOCKET ) + { + retval += decode_sock( &(reg->sock), base, rem, idx ); + } + + return retval; +} + +int encode_REGISTER_SUPER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->edgeMac ); + retval += encode_uint16( base, idx, 0 ); /* NULL auth scheme */ + retval += encode_uint16( base, idx, 0 ); /* No auth data */ + + return retval; +} + +int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_SUPER_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->edgeMac, base, rem, idx ); + retval += decode_uint16( &(reg->auth.scheme), base, rem, idx ); + retval += decode_uint16( &(reg->auth.toksize), base, rem, idx ); + retval += decode_buf( reg->auth.token, reg->auth.toksize, base, rem, idx ); + return retval; +} + +int encode_REGISTER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_ACK_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->dstMac ); + retval += encode_mac( base, idx, reg->srcMac ); + + /* The socket in REGISTER_ACK is the socket from which the REGISTER + * arrived. This is sent back to the sender so it knows what its public + * socket is. */ + if ( 0 != reg->sock.family ) + { + retval += encode_sock( base, idx, &(reg->sock) ); + } + + return retval; +} + +int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( reg, 0, sizeof(n2n_REGISTER_ACK_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->dstMac, base, rem, idx ); + retval += decode_mac( reg->srcMac, base, rem, idx ); + + /* The socket in REGISTER_ACK is the socket from which the REGISTER + * arrived. This is sent back to the sender so it knows what its public + * socket is. */ + if ( cmn->flags & N2N_FLAGS_SOCKET ) + { + retval += decode_sock( &(reg->sock), base, rem, idx ); + } + + return retval; +} + +int encode_REGISTER_SUPER_ACK( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_ACK_t * reg ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE ); + retval += encode_mac( base, idx, reg->edgeMac ); + retval += encode_uint16( base, idx, reg->lifetime ); + retval += encode_sock( base, idx, &(reg->sock) ); + retval += encode_uint8( base, idx, reg->num_sn ); + if ( reg->num_sn > 0 ) + { + /* We only support 0 or 1 at this stage */ + retval += encode_sock( base, idx, &(reg->sn_bak) ); + } + + return retval; +} + +int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + + memset( reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t) ); + retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx ); + retval += decode_mac( reg->edgeMac, base, rem, idx ); + retval += decode_uint16( &(reg->lifetime), base, rem, idx ); + + /* Socket is mandatory in this message type */ + retval += decode_sock( &(reg->sock), base, rem, idx ); + + /* Following the edge socket are an array of backup supernodes. */ + retval += decode_uint8( &(reg->num_sn), base, rem, idx ); + if ( reg->num_sn > 0 ) + { + /* We only support 0 or 1 at this stage */ + retval += decode_sock( &(reg->sn_bak), base, rem, idx ); + } + + return retval; +} + +int fill_sockaddr( struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock ) +{ + int retval=-1; + + if ( AF_INET == sock->family ) + { + if ( addrlen >= sizeof(struct sockaddr_in) ) + { + struct sockaddr_in * si = (struct sockaddr_in *)addr; + si->sin_family = sock->family; + si->sin_port = htons( sock->port ); + memcpy( &(si->sin_addr.s_addr), sock->addr.v4, IPV4_SIZE ); + retval=0; + } + } + + return retval; +} + + +int encode_PACKET( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_mac( base, idx, pkt->srcMac ); + retval += encode_mac( base, idx, pkt->dstMac ); + if ( 0 != pkt->sock.family ) + { + retval += encode_sock( base, idx, &(pkt->sock) ); + } + retval += encode_uint16( base, idx, pkt->transform ); + + return retval; +} + + +int decode_PACKET( n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( pkt, 0, sizeof(n2n_PACKET_t) ); + retval += decode_mac( pkt->srcMac, base, rem, idx ); + retval += decode_mac( pkt->dstMac, base, rem, idx ); + + if ( cmn->flags & N2N_FLAGS_SOCKET ) + { + retval += decode_sock( &(pkt->sock), base, rem, idx ); + } + + retval += decode_uint16( &(pkt->transform), base, rem, idx ); + + return retval; +} + +int encode_PEER_INFO( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PEER_INFO_t * pkt ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_uint16( base, idx, pkt->aflags ); + retval += encode_mac( base, idx, pkt->mac ); + retval += encode_sock( base, idx, &pkt->sock ); + + return retval; +} + +int decode_PEER_INFO( n2n_PEER_INFO_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( pkt, 0, sizeof(n2n_PEER_INFO_t) ); + retval += decode_uint16( &(pkt->aflags), base, rem, idx ); + retval += decode_mac( pkt->mac, base, rem, idx ); + retval += decode_sock( &pkt->sock, base, rem, idx ); + + return retval; +} + +int encode_QUERY_PEER( uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * pkt ) +{ + int retval=0; + retval += encode_common( base, idx, common ); + retval += encode_mac( base, idx, pkt->srcMac ); + retval += encode_mac( base, idx, pkt->targetMac ); + + return retval; +} + +int decode_QUERY_PEER( n2n_QUERY_PEER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx ) +{ + size_t retval=0; + memset( pkt, 0, sizeof(n2n_QUERY_PEER_t) ); + retval += decode_mac( pkt->srcMac, base, rem, idx ); + retval += decode_mac( pkt->targetMac, base, rem, idx ); + + return retval; +} diff --git a/bundles/n2n_ntop_v2/supernode.1 b/bundles/n2n_ntop_v2/supernode.1 new file mode 100644 index 00000000..26b1f70f --- /dev/null +++ b/bundles/n2n_ntop_v2/supernode.1 @@ -0,0 +1,43 @@ +.TH supernode 1 "Jan 3, 2009" "revision 3679" "USER COMMANDS" +.SH NAME +supernode \- n2n supernode daemon +.SH SYNOPSIS +.B supernode \-l [\-v] +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Supernode is a node introduction registry, +broadcast conduit and packet relay node for the n2n system. On startup supernode +begins listening on the specified UDP port for node registrations, and other +packets to route. The supernode can service any number of communities and routes +packets only between members of the same community. The supernode does not hold +the community encryption key and so cannot snoop or inject packets into the +community. +.PP +Supernode can service a number of n2n communities concurrently. Traffic does not +cross between communities. +.PP +All logging goes to stdout. +.SH OPTIONS +.TP +\-l +listen on the given UDP port +.TP +\-v +use verbose logging +.TP +\-f +disable daemon mode (UNIX) and run in foreground. +.SH EXAMPLES +.TP +.B supernode -l 7654 -v +Start supernode listening on UDP port 7654 with verbose output. +.PP +.SH RESTART +When suprenode restarts it loses all registration information from associated +edge nodes. It can take up to five minutes for the edge nodes to re-register and +normal traffic flow to resume. +.SH EXIT STATUS +supernode is a daemon and any exit is an error +.SH AUTHOR +Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner +.SH SEE ALSO +ifconfig(8) edge(8) diff --git a/bundles/n2n_ntop_v2/tools/Makefile.in b/bundles/n2n_ntop_v2/tools/Makefile.in new file mode 100644 index 00000000..631d5d95 --- /dev/null +++ b/bundles/n2n_ntop_v2/tools/Makefile.in @@ -0,0 +1,46 @@ +CC?=gcc +DEBUG?=-g3 +OPTIMIZATION?=-O2 #-march=native +WARN?=-Wall + +INSTALL=install +INSTALL_PROG=$(INSTALL) -m755 +MKDIR=mkdir -p + +PREFIX?=$(DESTDIR)/usr +ifeq ($(OS),Darwin) +SBINDIR=$(PREFIX)/local/sbin +else +SBINDIR=$(PREFIX)/sbin +endif + +LIBS_EDGE_OPT=@N2N_LIBS@ +LIBS_EDGE+=$(LIBS_EDGE_OPT) +HEADERS=$(wildcard include/*.h) +CFLAGS+=-I../include @CFLAGS@ +LDFLAGS+=-L.. +CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) +LDFLAGS=@LDFLAGS@ + +N2N_LIB=../libn2n.a + +TOOLS=n2n-benchmark +TOOLS+=@ADDITIONAL_TOOLS@ + +.PHONY: all clean install +all: $(TOOLS) + +n2n-benchmark: benchmark.c $(N2N_LIB) $(HEADERS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -o $@ + +n2n-decode: n2n_decode.c $(N2N_LIB) $(HEADERS) + $(CC) $(CFLAGS) $< $(LDFLAGS) $(N2N_LIB) $(LIBS_EDGE) -lpcap -o $@ + +.c.o: $(HEADERS) ../Makefile Makefile + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -rf $(TOOLS) *.o *.dSYM *~ + +install: $(TOOLS) + $(INSTALL_PROG) $(TOOLS) $(SBINDIR)/ diff --git a/bundles/n2n_ntop_v2/tools/benchmark.c b/bundles/n2n_ntop_v2/tools/benchmark.c new file mode 100644 index 00000000..e1d36446 --- /dev/null +++ b/bundles/n2n_ntop_v2/tools/benchmark.c @@ -0,0 +1,199 @@ +/* + * (C) 2007-20 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include "n2n.h" + + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; + +/* Prototypes */ +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ); +static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf); +static int perform_decryption = 0; + +static void usage() { + fprintf(stderr, "Usage: benchmark [-d]\n" + " -d\t\tEnable decryption. Default: only encryption is performed\n"); + exit(1); +} + +static void parseArgs(int argc, char * argv[]) { + if((argc != 1) && (argc != 2)) + usage(); + + if(argc == 2) { + if(strcmp(argv[1], "-d") != 0) + usage(); + + perform_decryption = 1; + } +} + +int main(int argc, char * argv[]) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + n2n_trans_op_t transop_null, transop_twofish; +#ifdef N2N_HAVE_AES + n2n_trans_op_t transop_aes_cbc; +#endif +#ifdef HAVE_OPENSSL_1_1 + n2n_trans_op_t transop_cc20; +#endif + + n2n_trans_op_t transop_speck; + n2n_edge_conf_t conf; + + parseArgs(argc, argv); + + /* Init configuration */ + edge_init_conf_defaults(&conf); + strncpy((char*)conf.community_name, "abc123def456", sizeof(conf.community_name)); + conf.encrypt_key = "SoMEVer!S$cUREPassWORD"; + + /* Init transopts */ + n2n_transop_null_init(&conf, &transop_null); + n2n_transop_twofish_init(&conf, &transop_twofish); +#ifdef N2N_HAVE_AES + n2n_transop_aes_cbc_init(&conf, &transop_aes_cbc); +#endif +#ifdef HAVE_OPENSSL_1_1 + n2n_transop_cc20_init(&conf, &transop_cc20); +#endif + n2n_transop_speck_init(&conf, &transop_speck); + + /* Run the tests */ + run_transop_benchmark("transop_null", &transop_null, &conf, pktbuf); + run_transop_benchmark("transop_twofish", &transop_twofish, &conf, pktbuf); +#ifdef N2N_HAVE_AES + run_transop_benchmark("transop_aes", &transop_aes_cbc, &conf, pktbuf); +#endif +#ifdef HAVE_OPENSSL_1_1 + run_transop_benchmark("transop_cc20", &transop_cc20, &conf, pktbuf); +#endif + run_transop_benchmark("transop_speck", &transop_speck, &conf, pktbuf); + + /* Cleanup */ + transop_null.deinit(&transop_null); + transop_twofish.deinit(&transop_twofish); +#ifdef N2N_HAVE_AES + transop_aes_cbc.deinit(&transop_aes_cbc); +#endif +#ifdef HAVE_OPENSSL_1_1 + transop_cc20.deinit(&transop_cc20); +#endif + transop_speck.deinit(&transop_speck); + + return 0; +} + +static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) { + n2n_common_t cmn; + n2n_PACKET_t pkt; + n2n_mac_t mac_buf; + const int target_sec = 3; + struct timeval t1; + struct timeval t2; + size_t idx; + size_t rem; + ssize_t nw; + ssize_t target_usec = target_sec * 1e6; + ssize_t tdiff = 0; // microseconds + size_t num_packets = 0; + + printf("Run %s[%s] for %us (%u bytes): ", perform_decryption ? "enc/dec" : "enc", + op_name, target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + + memset(mac_buf, 0, sizeof(mac_buf)); + gettimeofday( &t1, NULL ); + + while(tdiff < target_usec) { + nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, conf->community_name); + + nw += op_fn->fwd(op_fn, + pktbuf+nw, N2N_PKT_BUF_SIZE-nw, + PKT_CONTENT, sizeof(PKT_CONTENT), mac_buf); + + idx=0; + rem=nw; + + decode_common( &cmn, pktbuf, &rem, &idx); + decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx ); + + if(perform_decryption) { + uint8_t decodebuf[N2N_PKT_BUF_SIZE]; + + op_fn->rev(op_fn, decodebuf, N2N_PKT_BUF_SIZE, pktbuf+idx, rem, 0); + + if(memcmp(decodebuf, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) + fprintf(stderr, "Payload decryption failed!\n"); + } + + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + num_packets++; + } + + float mpps = num_packets / (tdiff / 1e6) / 1e6; + + printf("\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); +} + +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) +{ + n2n_mac_t destMac={0,1,2,3,4,5}; + n2n_common_t cmn; + n2n_PACKET_t pkt; + size_t idx; + + + memset( &cmn, 0, sizeof(cmn) ); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy( cmn.community, c, N2N_COMMUNITY_SIZE ); + + memset( &pkt, 0, sizeof(pkt) ); + memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE); + memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE); + + pkt.sock.family=0; /* do not encode sock */ + + idx=0; + encode_PACKET( pktbuf, &idx, &cmn, &pkt ); + traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx ); + + return idx; +} + diff --git a/bundles/n2n_ntop_v2/tools/n2n_decode.c b/bundles/n2n_ntop_v2/tools/n2n_decode.c new file mode 100644 index 00000000..ec3869bc --- /dev/null +++ b/bundles/n2n_ntop_v2/tools/n2n_decode.c @@ -0,0 +1,371 @@ +/** + * (C) 2019 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include +#include "n2n.h" + +#define SNAPLEN 1500 +#define TIMEOUT 200 + +/* *************************************************** */ + +static int aes_mode = 0; +static int running = 1; +static char *ifname = NULL; +static n2n_edge_conf_t conf; +static n2n_trans_op_t transop; +static pcap_t *handle; +static pcap_dumper_t *dumper; + +/* *************************************************** */ + +static void help() { + fprintf(stderr, "n2n-decode -i ifname -k key -c community [-B bpf] [-w fname] [-v]" +#ifdef N2N_HAVE_AES + " [-A]" +#endif + "\n"); + fprintf(stderr, "-i | Specify the capture interface name.\n"); + fprintf(stderr, "-c | Specify the community.\n"); + fprintf(stderr, "-k | Specify the encryption key.\n"); +#ifdef N2N_HAVE_AES + fprintf(stderr, "-A | Use AES CBC decryption (default=use twofish).\n"); +#endif + fprintf(stderr, "-B | Use set a BPF filter for the capture.\n"); + fprintf(stderr, "-w | Write decoded PCAP to file.\n"); + fprintf(stderr, "-v | Increase verbosity level.\n"); + + exit(0); +} + +/* *************************************************** */ + +#ifdef WIN32 +BOOL WINAPI term_handler(DWORD sig) +#else +static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "Ok I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "Shutting down..."); + called = 1; + } + + running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} + +/* *************************************************** */ + +static void write_packet(const u_char *packet, struct pcap_pkthdr *hdr) { + pcap_dump((unsigned char*)dumper, hdr, packet); + pcap_dump_flush(dumper); +} + +/* *************************************************** */ + +static int decode_encrypted_packet(const u_char *packet, struct pcap_pkthdr *header, + n2n_PACKET_t *pkt, int encrypted_offset) { + uint8_t decoded_packet[encrypted_offset + N2N_PKT_BUF_SIZE]; + int decoded_eth_size; + int transop_shift; + + switch(pkt->transform) { + case N2N_TRANSFORM_ID_NULL: + /* Not encrypted, dump it */ + write_packet(packet, header); + break; + case N2N_TRANSFORM_ID_TWOFISH: + if(aes_mode) { + traceEvent(TRACE_INFO, "Skipping twofish encrypted packet"); + return(-1); + } + break; + case N2N_TRANSFORM_ID_AESCBC: + if(!aes_mode) { + traceEvent(TRACE_INFO, "Skipping AES encrypted packet"); + return(-1); + } + break; + default: + traceEvent(TRACE_INFO, "Skipping unknown transform packet: %d", pkt->transform); + return(-2); + } + + decoded_eth_size = transop.rev(&transop, decoded_packet+encrypted_offset, N2N_PKT_BUF_SIZE, packet + encrypted_offset, + header->caplen - encrypted_offset, pkt->srcMac); + + transop_shift = (header->caplen - encrypted_offset) - decoded_eth_size; + + if(transop_shift >= 0) { + int transform_id_offset = encrypted_offset - 2; + + /* Copy the initial part of the packet */ + memcpy(decoded_packet, packet, encrypted_offset); + + /* Change the packet transform to NULL as there is now plaintext data */ + *((u_int16_t*)(decoded_packet + transform_id_offset)) = htons(N2N_TRANSFORM_ID_NULL); + + // TODO fix IP and UDP chechsums + write_packet(decoded_packet, header); + return(0); + } + + traceEvent(TRACE_INFO, "Something was wrong in the decoding"); + return(-3); +} + +/* *************************************************** */ + +#define ETH_SIZE 14 +#define UDP_SIZE 8 +#define MIN_IP_SIZE 20 +#define MIN_LEN (ETH_SIZE + UDP_SIZE + MIN_IP_SIZE + sizeof(n2n_common_t)) + +static int run_packet_loop() { + struct pcap_pkthdr header; + const u_char *packet; + + traceEvent(TRACE_NORMAL, "Capturing packets on %s...", ifname); + + while(running) { + n2n_common_t common; + n2n_PACKET_t pkt; + uint ipsize, common_offset; + size_t idx, rem; + + memset(&common, 0, sizeof(common)); + memset(&pkt, 0, sizeof(pkt)); + + packet = pcap_next(handle, &header); + + if(!packet) + continue; + + if(header.caplen < MIN_LEN) { + traceEvent(TRACE_INFO, "Skipping packet too small: size=%d", header.caplen); + continue; + } + + if(ntohs(*(uint16_t*)(packet + 12)) != 0x0800) { + traceEvent(TRACE_INFO, "Skipping non IPv4 packet"); + continue; + } + + if(packet[ETH_SIZE + 9] != IPPROTO_UDP) { + traceEvent(TRACE_INFO, "Skipping non UDP packet"); + continue; + } + + ipsize = (packet[ETH_SIZE] & 0x0F) * 4; + common_offset = ETH_SIZE + ipsize + UDP_SIZE; + + idx = common_offset; + rem = header.caplen - idx; + + if(decode_common(&common, packet, &rem, &idx) == -1) { + traceEvent(TRACE_INFO, "Skipping packet, decode common failed"); + continue; + } + + if(strncmp((char*)conf.community_name, (char*)common.community, N2N_COMMUNITY_SIZE) != 0) { + traceEvent(TRACE_INFO, "Skipping packet with non-matching community"); + continue; + } + + switch(common.pc) { + case n2n_ping: + case n2n_register: + case n2n_deregister: + case n2n_register_ack: + case n2n_register_super: + case n2n_register_super_ack: + case n2n_register_super_nak: + case n2n_federation: + case n2n_peer_info: + case n2n_query_peer: + write_packet(packet, &header); + break; + case n2n_packet: + decode_PACKET(&pkt, &common, packet, &rem, &idx); + decode_encrypted_packet(packet, &header, &pkt, idx); + break; + default: + traceEvent(TRACE_INFO, "Skipping packet with unknown type: %d", common.pc); + continue; + } + } + + return(0); +} + +/* *************************************************** */ + +int main(int argc, char* argv[]) { + u_char c; + struct bpf_program fcode; + char *bpf_filter = NULL, *out_fname = NULL; + char errbuf[PCAP_ERRBUF_SIZE]; + int rv = 0; + FILE *outf = stdout; + + /* Trace to stderr to leave stdout for the PCAP dump if "-w -" is used */ + setTraceFile(stderr); + + /* Init configuration */ + edge_init_conf_defaults(&conf); + + while((c = getopt(argc, argv, + "k:i:B:w:c:v" +#ifdef N2N_HAVE_AES + "A" +#endif + )) != '?') { + if(c == 255) break; + + switch(c) { + case 'c': + strncpy((char*)conf.community_name, optarg, sizeof(conf.community_name)-1); + break; + case 'i': + ifname = strdup(optarg); + break; + case 'k': + conf.encrypt_key = strdup(optarg); + break; + case 'B': + bpf_filter = strdup(optarg); + break; +#ifdef N2N_HAVE_AES + case 'A': + aes_mode = 1; + break; +#endif + case 'w': + if(strcmp(optarg, "-") != 0) + out_fname = strdup(optarg); + break; + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + default: + help(); + } + } + + if((ifname == NULL) || (conf.encrypt_key == NULL) || (conf.community_name[0] == '\0')) + help(); + +#ifdef N2N_HAVE_AES + if(aes_mode) + n2n_transop_aes_cbc_init(&conf, &transop); + else +#endif + n2n_transop_twofish_init(&conf, &transop); + + if((handle = pcap_create(ifname, errbuf)) == NULL) { + traceEvent(TRACE_ERROR, "Cannot open device %s: %s", ifname, errbuf); + return(1); + } + + if((pcap_set_timeout(handle, TIMEOUT) != 0) || + (pcap_set_snaplen(handle, SNAPLEN) != 0)) { + traceEvent(TRACE_ERROR, "Error while setting timeout/snaplen"); + return(1); + } + +#ifdef HAVE_PCAP_IMMEDIATE_MODE + /* The timeout is not honored unless immediate mode is set. + * See https://github.com/mfontanini/libtins/issues/180 */ + if(pcap_set_immediate_mode(handle, 1) != 0) { + traceEvent(TRACE_ERROR, "Could not set PCAP immediate mode"); + return(1); + } +#endif + + if(pcap_activate(handle) != 0) { + traceEvent(TRACE_ERROR, "pcap_activate failed: %s", pcap_geterr(handle)); + } + + if(pcap_datalink(handle) != DLT_EN10MB) { + traceEvent(TRACE_ERROR, "Device %s doesn't provide Ethernet headers - not supported", ifname); + return(2); + } + + if(bpf_filter) { + bpf_u_int32 net, mask; + + if(pcap_lookupnet(ifname, &net, &mask, errbuf) == -1) { + traceEvent(TRACE_WARNING, "Couldn't get netmask for device %s: %s", ifname, errbuf); + net = 0; + mask = 0; + } + + if((pcap_compile(handle, &fcode, bpf_filter, 1, net) < 0) + || (pcap_setfilter(handle, &fcode) < 0)) { + traceEvent(TRACE_ERROR, "Could not set BPF filter: %s", pcap_geterr(handle)); + return(3); + } + } + + if(out_fname) { + outf = fopen(out_fname, "wb"); + + if(outf == NULL) { + traceEvent(TRACE_ERROR, "Could not open %s for write[%d]: %s", errno, strerror(errno)); + return(4); + } + } + + dumper = pcap_dump_fopen(handle, outf); + + if(dumper == NULL) { + traceEvent(TRACE_ERROR, "Could dump file: %s", pcap_geterr(handle)); + return(5); + } + +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#else + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); +#endif + + rv = run_packet_loop(); + + /* Cleanup */ + pcap_close(handle); + + if(conf.encrypt_key) free(conf.encrypt_key); + if(bpf_filter) free(bpf_filter); + if(ifname) free(ifname); + + if(out_fname) { + fclose(outf); + free(out_fname); + } + + return(rv); +} diff --git a/bundles/n2n_ntop_v2/win32/CMakeLists.txt b/bundles/n2n_ntop_v2/win32/CMakeLists.txt new file mode 100644 index 00000000..2e96b181 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(n2n_win32 + getopt1.c + getopt.c + wintap.c) +target_link_libraries(n2n_win32 PUBLIC ws2_32.lib) diff --git a/bundles/n2n_ntop_v2/win32/DotNet/n2n.sln b/bundles/n2n_ntop_v2/win32/DotNet/n2n.sln new file mode 100644 index 00000000..95698872 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/DotNet/n2n.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge", "n2n.vcproj", "{4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "supernode", "supernode.vcproj", "{BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.Build.0 = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.ActiveCfg = Release|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.Build.0 = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.ActiveCfg = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.Build.0 = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.ActiveCfg = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bundles/n2n_ntop_v2/win32/DotNet/n2n.suo b/bundles/n2n_ntop_v2/win32/DotNet/n2n.suo new file mode 100644 index 0000000000000000000000000000000000000000..aae212bdc7603fcc776941462dec540d87901d0e GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/bundles/n2n_ntop_v2/win32/DotNet/n2n.vcproj b/bundles/n2n_ntop_v2/win32/DotNet/n2n.vcproj new file mode 100644 index 00000000..d62381d2 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/DotNet/n2n.vcproj @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_ntop_v2/win32/DotNet/supernode.vcproj b/bundles/n2n_ntop_v2/win32/DotNet/supernode.vcproj new file mode 100644 index 00000000..e6a9e0d1 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/DotNet/supernode.vcproj @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_ntop_v2/win32/getopt.c b/bundles/n2n_ntop_v2/win32/getopt.c new file mode 100644 index 00000000..6bbb735a --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/getopt.c @@ -0,0 +1,1074 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include +#ifdef WIN32 +#include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT<_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +#ifndef DARWIN +char *optarg; +#endif + + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +#ifndef DARWIN +int optind = 1; +#endif + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +#ifndef DARWIN +#ifdef WIN32 +int opterr = 0; +#else +int opterr = 1; +#endif +#endif + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ +#ifndef DARWIN +int optopt = '?'; +#endif + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +#ifndef WIN32 +# if HAVE_STRING_H +# include +# else +# include +# endif +#endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt____ (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ + diff --git a/bundles/n2n_ntop_v2/win32/getopt.h b/bundles/n2n_ntop_v2/win32/getopt.h new file mode 100644 index 00000000..b0147e9d --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/bundles/n2n_ntop_v2/win32/getopt1.c b/bundles/n2n_ntop_v2/win32/getopt1.c new file mode 100644 index 00000000..3d264f2d --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/getopt1.c @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/bundles/n2n_ntop_v2/win32/n2n_win32.h b/bundles/n2n_ntop_v2/win32/n2n_win32.h new file mode 100644 index 00000000..81b5bdc7 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/n2n_win32.h @@ -0,0 +1,113 @@ +/* + + (C) 2007-09 - Luca Deri + +*/ + +#ifndef _N2N_WIN32_H_ +#define _N2N_WIN32_H_ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#define WIN32_LEAN_AND_MEAN + +#if defined(__MINGW32__) +/* should be defined here and before winsock gets included */ +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x501 //Otherwise the linker doesnt find getaddrinfo +#endif /* #ifndef _WIN32_WINNT */ +#include +#endif /* #if defined(__MINGW32__) */ + +#include +#include +#include + + +#include "wintap.h" + +#ifdef _MSC_VER +#include "getopt.h" + +/* Other Win environments are expected to support stdint.h */ + +/* stdint.h typedefs (C99) (not present in Visual Studio) */ +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* sys/types.h typedefs (not present in Visual Studio) */ +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +typedef unsigned char u_int8_t; + +typedef int ssize_t; +#endif /* #ifdef _MSC_VER */ + +typedef unsigned long in_addr_t; + +#undef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define MAX(a,b) (a > b ? a : b) +#define MIN(a,b) (a < b ? a : b) + +#define snprintf _snprintf +#define strdup _strdup + +#define socklen_t int + +#define ETH_ADDR_LEN 6 +/* + * Structure of a 10Mb/s Ethernet header. + */ +struct ether_hdr +{ + uint8_t dhost[ETH_ADDR_LEN]; + uint8_t shost[ETH_ADDR_LEN]; + uint16_t type; /* higher layer protocol encapsulated */ +}; + +typedef struct ether_hdr ether_hdr_t; + +/* ************************************* */ + +struct ip { +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#else + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif + u_char ip_tos; /* type of service */ + short ip_len; /* total length */ + u_short ip_id; /* identification */ + short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + + +/* ************************************* */ + +typedef struct tuntap_dev { + HANDLE device_handle; + char *device_name; + char *ifName; + OVERLAPPED overlap_read, overlap_write; + uint8_t mac_addr[6]; + uint32_t ip_addr, device_mask; + unsigned int mtu; +} tuntap_dev; + +#define index(a, b) strchr(a, b) +#define sleep(x) Sleep(x * 1000) + +#endif diff --git a/bundles/n2n_ntop_v2/win32/version-msvc.c b/bundles/n2n_ntop_v2/win32/version-msvc.c new file mode 100644 index 00000000..92cce068 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/version-msvc.c @@ -0,0 +1,3 @@ +const char * n2n_sw_version = "2.0.0"; +const char * n2n_sw_osName = "Win32"; +const char * n2n_sw_buildDate = __DATE__ " " __TIME__; diff --git a/bundles/n2n_ntop_v2/win32/winconfig.h b/bundles/n2n_ntop_v2/win32/winconfig.h new file mode 100644 index 00000000..3a8cea06 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/winconfig.h @@ -0,0 +1,8 @@ +/* winconfig.h. Win32 replacement for file generated from config.h.in by configure. */ + +/* OS name */ +#define PACKAGE_OSNAME N2N_OSNAME + +/* Define to the version of this package. */ +#define PACKAGE_VERSION N2N_VERSION +#define GIT_RELEASE N2N_VERSION diff --git a/bundles/n2n_ntop_v2/win32/wintap.c b/bundles/n2n_ntop_v2/win32/wintap.c new file mode 100644 index 00000000..85f455c1 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/wintap.c @@ -0,0 +1,433 @@ +/* + (C) 2007-09 - Luca Deri +*/ + +#include "n2n.h" +#include "n2n_win32.h" + +/* ***************************************************** */ + +void initWin32() { + WSADATA wsaData; + int err; + + err = WSAStartup(MAKEWORD(2, 2), &wsaData ); + if( err != 0 ) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("FATAL ERROR: unable to initialise Winsock 2.x."); + exit(EXIT_FAILURE); + } +} + +struct win_adapter_info { + HANDLE handle; + char adapterid[1024]; + char adaptername[1024]; +}; + +/* ***************************************************** */ + +static HANDLE open_tap_device(const char *adapterid) { + char tapname[1024]; + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + + return(CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, + 0, /* Don't let other processes share or open + the resource until the handle's been closed */ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0)); +} + +/* ***************************************************** */ + +static void iterate_win_network_adapters( + int (*callback)(struct win_adapter_info*, struct tuntap_dev *), + void *userdata) { + HKEY key, key2; + char regpath[1024]; + long len, rc; + int found = 0; + int err, i; + struct win_adapter_info adapter; + + /* Open registry and look for network adapters */ + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: [rc=%d]\n", rc); + exit(EXIT_FAILURE); + /* MSVC Note: If you keep getting rc=2 errors, make sure you set: + Project -> Properties -> Configuration Properties -> General -> Character set + to: "Use Multi-Byte Character Set" + */ + } + + for (i = 0; ; i++) { + len = sizeof(adapter.adapterid); + if(RegEnumKeyEx(key, i, (LPTSTR)adapter.adapterid, &len, 0, 0, 0, NULL)) + break; + + /* Find out more about this adapter */ + + _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapter.adapterid); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adapter.adaptername); + err = RegQueryValueEx(key2, "Name", 0, 0, adapter.adaptername, &len); + + RegCloseKey(key2); + + if(err) + continue; + + + adapter.handle = open_tap_device(adapter.adapterid); + + if(adapter.handle != INVALID_HANDLE_VALUE) { + /* Valid device, use the callback */ + if(!callback(&adapter, userdata)) + break; + else + CloseHandle(adapter.handle); + /* continue */ + } + } + + RegCloseKey(key); +} + +/* ***************************************************** */ + +static int print_adapter_callback(struct win_adapter_info *adapter, struct tuntap_dev *device) { + printf(" %s - %s\n", adapter->adapterid, adapter->adaptername); + + /* continue */ + return(1); +} + +void win_print_available_adapters() { + iterate_win_network_adapters(print_adapter_callback, NULL); +} + +/* ***************************************************** */ + +static int lookup_adapter_info_reg(const char *target_adapter, char *regpath, size_t regpath_size) { + HKEY key, key2; + long len, rc; + char index[16]; + int err, i; + char adapter_name[N2N_IFNAMSIZ]; + int rv = 0; + + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_INFO_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: %s, [rc=%d]\n", ADAPTER_INFO_KEY, rc); + exit(EXIT_FAILURE); + } + + for(i = 0; ; i++) { + len = sizeof(index); + if(RegEnumKeyEx(key, i, (LPTSTR)index, &len, 0, 0, 0, NULL)) + break; + + _snprintf(regpath, regpath_size, "%s\\%s", ADAPTER_INFO_KEY, index); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adapter_name); + err = RegQueryValueEx(key2, "NetCfgInstanceId", 0, 0, adapter_name, &len); + + RegCloseKey(key2); + + if(err) + continue; + + if(!strcmp(adapter_name, target_adapter)) { + rv = 1; + break; + } + } + + RegCloseKey(key); + return(rv); +} + +/* ***************************************************** */ + +static void set_interface_mac(struct tuntap_dev *device, const char *mac_str) { + char cmd[256]; + char mac_buf[18]; + char adapter_info_reg[1024]; + + uint64_t mac = 0; + uint8_t *ptr = (uint8_t*)&mac; + + if(strlen(mac_str) != 17) { + printf("Invalid MAC: %s\n", mac_str); + exit(EXIT_FAILURE); + } + + /* Remove the colons */ + for(int i=0; i<6; i++) { + mac_buf[i*2] = mac_str[2*i + i]; + mac_buf[i*2+1] = mac_str[2*i + i + 1]; + } + mac_buf[12] = '\0'; + + if(!lookup_adapter_info_reg(device->device_name, adapter_info_reg, sizeof(adapter_info_reg))) { + printf("Could not determine adapter MAC registry key\n"); + exit(EXIT_FAILURE); + } + + _snprintf(cmd, sizeof(cmd), + "reg add HKEY_LOCAL_MACHINE\\%s /v MAC /d %s /f > nul", adapter_info_reg, mac_buf); + system(cmd); + + /* Put down then up again to apply */ + CloseHandle(device->device_handle); + _snprintf(cmd, sizeof(cmd), "netsh interface set interface \"%s\" disabled > nul", device->ifName); + system(cmd); + _snprintf(cmd, sizeof(cmd), "netsh interface set interface \"%s\" enabled > nul", device->ifName); + system(cmd); + + device->device_handle = open_tap_device(device->device_name); + if(device->device_handle == INVALID_HANDLE_VALUE) { + printf("Reopening TAP device \"%s\" failed\n", device->device_name); + exit(EXIT_FAILURE); + } +} + +/* ***************************************************** */ + +static int choose_adapter_callback(struct win_adapter_info *adapter, struct tuntap_dev *device) { + if(device->device_name) { + /* A device name filter was set, name must match */ + if(strcmp(device->device_name, adapter->adapterid) && + strcmp(device->device_name, adapter->adaptername)) { + /* Not found, continue */ + return(1); + } + } /* otherwise just pick the first available adapter */ + + /* Adapter found, break */ + device->device_handle = adapter->handle; + if(device->device_name) free(device->device_name); + device->device_name = _strdup(adapter->adapterid); + device->ifName = _strdup(adapter->adaptername); + return(0); +} + +/* ***************************************************** */ + +int open_wintap(struct tuntap_dev *device, + const char * devname, + const char * address_mode, /* "static" or "dhcp" */ + char *device_ip, + char *device_mask, + const char *device_mac, + int mtu) { + char cmd[256]; + DWORD len; + ULONG status = TRUE; + + memset(device, 0, sizeof(struct tuntap_dev)); + device->device_handle = INVALID_HANDLE_VALUE; + device->device_name = devname[0] ? _strdup(devname) : NULL; + device->ifName = NULL; + device->ip_addr = inet_addr(device_ip); + + iterate_win_network_adapters(choose_adapter_callback, device); + + if(device->device_handle == INVALID_HANDLE_VALUE) { + if(!devname[0]) + printf("No Windows tap devices found, did you run tapinstall.exe?\n"); + else + printf("Cannot find tap device \"%s\"\n", devname); + return -1; + } + + /* ************************************** */ + + if(device_mac[0]) + set_interface_mac(device, device_mac); + + /* Get MAC address from tap device->device_name */ + + if(!DeviceIoControl(device->device_handle, TAP_IOCTL_GET_MAC, + device->mac_addr, sizeof(device->mac_addr), + device->mac_addr, sizeof(device->mac_addr), &len, 0)) { + printf("Could not get MAC address from Windows tap %s (%s)\n", + device->device_name, device->ifName); + return -1; + } + + device->mtu = mtu; + + printf("Open device [name=%s][ip=%s][ifName=%s][MTU=%d][mac=%02X:%02X:%02X:%02X:%02X:%02X]\n", + device->device_name, device_ip, device->ifName, device->mtu, + device->mac_addr[0] & 0xFF, + device->mac_addr[1] & 0xFF, + device->mac_addr[2] & 0xFF, + device->mac_addr[3] & 0xFF, + device->mac_addr[4] & 0xFF, + device->mac_addr[5] & 0xFF); + + /* ****************** */ + + if ( 0 == strcmp("dhcp", address_mode) ) + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" dhcp > nul", + device->ifName); + } + else + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" static %s %s > nul", + device->ifName, device_ip, device_mask); + } + + if(system(cmd) == 0) { + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + } else + printf("WARNING: Unable to set device %s IP address [%s]\n", + device->ifName, cmd); + + /* ****************** */ + + /* MTU */ + _snprintf(cmd, sizeof(cmd), + "netsh interface ipv4 set subinterface \"%s\" mtu=%d store=persistent > nul", + device->ifName, mtu); + + if(system(cmd) != 0) + printf("WARNING: Unable to set device %s MTU [%s]\n", + device->ifName, cmd); + + /* set driver media status to 'connected' (i.e. set the interface up) */ + if (!DeviceIoControl (device->device_handle, TAP_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), + &status, sizeof (status), &len, NULL)) + printf("WARNING: Unable to enable TAP adapter\n"); + + /* + * Initialize overlapped structures + */ + device->overlap_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device->overlap_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!device->overlap_read.hEvent || !device->overlap_write.hEvent) { + return -1; + } + + return(0); +} + +/* ************************************************ */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD read_size, last_err; + + ResetEvent(tuntap->overlap_read.hEvent); + if (ReadFile(tuntap->device_handle, buf, len, &read_size, &tuntap->overlap_read)) { + //printf("tun_read(len=%d)\n", read_size); + return read_size; + } + switch (last_err = GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_read.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_read, &read_size, FALSE); + return read_size; + break; + default: + printf("GetLastError() returned %d\n", last_err); + break; + } + + return -1; +} +/* ************************************************ */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD write_size; + + //printf("tun_write(len=%d)\n", len); + + ResetEvent(tuntap->overlap_write.hEvent); + if (WriteFile(tuntap->device_handle, + buf, + len, + &write_size, + &tuntap->overlap_write)) { + //printf("DONE tun_write(len=%d)\n", write_size); + return write_size; + } + switch (GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_write.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_write, + &write_size, FALSE); + return write_size; + break; + default: + break; + } + + return -1; +} + +/* ************************************************ */ + +int tuntap_open(struct tuntap_dev *device, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + return(open_wintap(device, dev, address_mode, device_ip, device_mask, device_mac, mtu)); +} + +/* ************************************************ */ + +void tuntap_close(struct tuntap_dev *tuntap) { + CloseHandle(tuntap->device_handle); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +/* ************************************************ */ + +#if 0 +int main(int argc, char* argv[]) { + struct tuntap_dev tuntap; + int i; + int mtu = 1400; + + printf("Welcome to n2n\n"); + initWin32(); + open_wintap(&tuntap, "static", "1.2.3.20", "255.255.255.0", mtu); + + for(i=0; i<10; i++) { + u_char buf[MTU]; + int rc; + + rc = tun_read(&tuntap, buf, sizeof(buf)); + buf[0]=2; + buf[1]=3; + buf[2]=4; + + printf("tun_read returned %d\n", rc); + rc = tun_write(&tuntap, buf, rc); + printf("tun_write returned %d\n", rc); + } + // rc = tun_open (device->device_name, IF_MODE_TUN); + WSACleanup (); + return(0); +} + +#endif diff --git a/bundles/n2n_ntop_v2/win32/wintap.h b/bundles/n2n_ntop_v2/win32/wintap.h new file mode 100644 index 00000000..9c557140 --- /dev/null +++ b/bundles/n2n_ntop_v2/win32/wintap.h @@ -0,0 +1,69 @@ +/* + (C) 2007 - Luca Deri +*/ + +#ifndef _WINTAP_H_ +#define _WINTAP_H_ + +#undef UNICODE +#undef _UNICODE +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include + + + +//=============================================== +// This file is included both by OpenVPN and +// the TAP-Win32 driver and contains definitions +// common to both. +//=============================================== + +//============= +// TAP IOCTLs +//============= + +#define TAP_CONTROL_CODE(request,method) \ + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + +#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) +#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) +#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) +#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) +#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) +#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) + +//================= +// Registry keys +//================= + +#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define ADAPTER_INFO_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +//====================== +// Filesystem prefixes +//====================== + +#define USERMODEDEVICEDIR "\\\\.\\Global\\" +#define SYSDEVICEDIR "\\Device\\" +#define USERDEVICEDIR "\\DosDevices\\Global\\" +#define TAPSUFFIX ".tap" + +//========================================================= +// TAP_COMPONENT_ID -- This string defines the TAP driver +// type -- different component IDs can reside in the system +// simultaneously. +//========================================================= + +#define TAP_COMPONENT_ID "tap0801" + +extern void initWin32(); +extern void win_print_available_adapters(); + +#endif \ No newline at end of file diff --git a/bundles/n2n_ntop_v2/wireshark/README.md b/bundles/n2n_ntop_v2/wireshark/README.md new file mode 100644 index 00000000..4c0b6fdd --- /dev/null +++ b/bundles/n2n_ntop_v2/wireshark/README.md @@ -0,0 +1,9 @@ +Wireshark Lua plugin to dissect n2n traffic. + +Quick load: + +``` + wireshark -X lua_script:n2n.lua +``` + +NOTE: the dissector only decodes traffic on UDP port 50001. In order to decode n2n traffic on another UDP port you can use the "Decode As..." function of wireshark. diff --git a/bundles/n2n_ntop_v2/wireshark/n2n.lua b/bundles/n2n_ntop_v2/wireshark/n2n.lua new file mode 100644 index 00000000..ff453410 --- /dev/null +++ b/bundles/n2n_ntop_v2/wireshark/n2n.lua @@ -0,0 +1,316 @@ +-- (C) 2019 - ntop.org and contributors + +n2n = Proto("n2n", "n2n Protocol") + +-- ############################################# + +PKT_TYPE_PING = 0 +PKT_TYPE_REGISTER = 1 +PKT_TYPE_DEREGISTER = 2 +PKT_TYPE_PACKET = 3 +PKT_TYPE_REGISTER_ACK = 4 +PKT_TYPE_REGISTER_SUPER = 5 +PKT_TYPE_REGISTER_SUPER_ACK = 6 +PKT_TYPE_REGISTER_SUPER_NAK = 7 +PKT_TYPE_FEDERATION = 8 +PKT_TYPE_PEER_INFO = 9 +PKT_TYPE_QUERY_PEER = 10 + +PKT_TRANSFORM_NULL = 1 +PKT_TRANSFORM_TWOFISH = 2 +PKT_TRANSFORM_AESCBC = 3 + +FLAG_FROM_SUPERNODE = 0x0020 +FLAG_SOCKET = 0x0040 +FLAG_OPTIONS = 0x0080 + +SOCKET_FAMILY_AF_INET = 0x0000 +SOCKET_FAMILY_AF_INET6 = 0x8000 + +-- ############################################# + +version = ProtoField.uint8("n2n.version", "version", base.DEC) +ttl = ProtoField.uint8("n2n.ttl", "ttl", base.DEC) + +packet_type_mask = 0x001f +pkt_type_2_str = { + [PKT_TYPE_PING] = "ping", + [PKT_TYPE_REGISTER] = "register", + [PKT_TYPE_DEREGISTER] = "deregister", + [PKT_TYPE_PACKET] = "packet", + [PKT_TYPE_REGISTER_ACK] = "register_ack", + [PKT_TYPE_REGISTER_SUPER] = "register_super", + [PKT_TYPE_REGISTER_SUPER_ACK] = "register_super_ack", + [PKT_TYPE_REGISTER_SUPER_NAK] = "register_super_nak", + [PKT_TYPE_FEDERATION] = "federation", + [PKT_TYPE_PEER_INFO] = "peer_info", + [PKT_TYPE_QUERY_PEER] = "query_peer", +} +packet_type = ProtoField.uint8("n2n.packet_type", "packetType", base.HEX, pkt_type_2_str, packet_type_mask) + +flags_mask = 0xffe0 +flags = ProtoField.uint16("n2n.flags", "Flags", base.HEX, nil, flags_mask) +from_supernode_flag = ProtoField.uint16("n2n.flags.from_supernode", "from_supernode", base.BOOLEAN, nil, FLAG_FROM_SUPERNODE) +socket_flag = ProtoField.uint16("n2n.flags.socket", "socket", base.BOOLEAN, nil, FLAG_SOCKET) +options_flag = ProtoField.uint16("n2n.flags.options", "options", base.BOOLEAN, nil, FLAG_OPTIONS) +community = ProtoField.string("n2n.community", "Community", base.ASCII) + +-- ############################################# + +src_mac = ProtoField.ether("n2n.src_mac", "Source") +dst_mac = ProtoField.ether("n2n.dst_mac", "Destination") +socket_info = ProtoField.none("n2n.socket", "Socket Info") +socket_family = ProtoField.uint16("n2n.socket.family", "Family", base.HEX, { + [0] = "AF_INET", +}) +socket_port = ProtoField.uint16("n2n.socket.port", "Port") +socket_ipv4 = ProtoField.ipv4("n2n.socket.ipv4", "IPv4") +socket_ipv6 = ProtoField.ipv6("n2n.socket.ipv6", "IPv6") + +-- ############################################# + +peer_info_field = ProtoField.none("n2n.peer_info", "PeerInfo") +peer_info_flags = ProtoField.uint16("n2n.peer_info.flags", "Flags") +peer_info_mac = ProtoField.ether("n2n.peer_info.query_mac", "Query") + +query_peer_field = ProtoField.none("n2n.query_peer", "QueryPeer") + +-- ############################################# + + + +packet_field = ProtoField.none("n2n.packet", "Packet") +packet_transform = ProtoField.uint16("n2n.packet.transform", "Transform", base.HEX, { + [PKT_TRANSFORM_NULL] = "Plaintext", + [PKT_TRANSFORM_TWOFISH] = "TwoFish", + [PKT_TRANSFORM_AESCBC] = "AES CBC", +}) +packet_payload = ProtoField.bytes("n2n.packet.payload", "Payload") + +-- ############################################# + +register_field = ProtoField.none("n2n.register", "Register") +register_cookie = ProtoField.uint32("n2n.register.cookie", "Cookie", base.HEX) + +register_ack_field = ProtoField.none("n2n.register_ack", "RegisterACK") +register_ack_cookie = ProtoField.uint32("n2n.register_ack.cookie", "Cookie", base.HEX) + +register_super_field = ProtoField.none("n2n.register_super", "RegisterSuper") +register_super_cookie = ProtoField.uint32("n2n.register_super.cookie", "Cookie", base.HEX) +register_super_auth_schema = ProtoField.uint16("n2n.register_super.auth.schema", "AuthSchema", base.HEX) +register_super_auth_data = ProtoField.uint16("n2n.register_super.auth.data", "AuthData", base.HEX) + +register_super_ack_field = ProtoField.none("n2n.register_super_ack", "RegisterSuperACK") +register_super_ack_cookie = ProtoField.uint32("n2n.register_super_ack.cookie", "Cookie", base.HEX) +register_super_ack_lifetime = ProtoField.uint16("n2n.register_super_ack.lifetime", "Registration Lifetime", base.DEC) +register_super_ack_num_sn = ProtoField.uint8("n2n.register_super_ack.num_sn", "Num Supernodes", base.DEC) + +-- ############################################# + +n2n.fields = { + version, ttl, packet_type, + flags, from_supernode_flag, socket_flag, options_flag, + community, + + -- Generic + src_mac, dst_mac, + socket_info, socket_family, socket_port, socket_ipv4, socket_ipv6, + + -- PKT_TYPE_REGISTER + register_field, register_cookie, + -- PKT_TYPE_PACKET + packet_field, packet_transform, packet_payload, + -- PKT_TYPE_REGISTER_ACK + register_ack_field, register_ack_cookie, + -- PKT_TYPE_REGISTER_SUPER + register_super_field, register_super_cookie, register_super_auth_schema, register_super_auth_data, + -- PKT_TYPE_REGISTER_SUPER_ACK + register_super_ack_field, register_super_ack_cookie, register_super_ack_lifetime, register_super_ack_num_sn, + -- PKT_TYPE_PEER_INFO + peer_info_field, peer_info_flags, peer_info_mac, + -- PKT_TYPE_QUERY_PEER + query_peer_field, +} + +-- ############################################# + +function dissect_socket(subtree, buffer, offset) + local sock_baselen = 4 + local sock_protolen = 0 + buffer = buffer(offset) + local sock_family = bit.band(buffer(0,4):uint(), 0xFFFF0000) + + if(sock_family == SOCKET_FAMILY_AF_INET) then + sock_protolen = 4 + elseif(sock_family == SOCKET_FAMILY_AF_INET6) then + sock_protolen = 16 + end + + local totlen = sock_baselen + sock_protolen + local socktree = subtree:add(socket_info, buffer(0, totlen)) + + socktree:add(socket_family, buffer(0, 2)) + socktree:add(socket_port, buffer(2, 2)) + + if(sock_family == SOCKET_FAMILY_AF_INET) then + socktree:add(socket_ipv4, buffer(4, sock_protolen)) + elseif(sock_family == SOCKET_FAMILY_AF_INET6) then + socktree:add(socket_ipv6, buffer(4, sock_protolen)) + end + + return offset+totlen, socktree +end + +-- ############################################# + +function dissect_register(subtree, buffer, flags) + local regtree = subtree:add(register_field, buffer) + + regtree:add(register_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(dst_mac, buffer(10,6)) + + if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then + dissect_socket(regtree, buffer, 16) + end + + return regtree +end + +-- ############################################# + +function dissect_register_ack(subtree, buffer, flags) + local regtree = subtree:add(register_ack_field, buffer) + + regtree:add(register_ack_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(dst_mac, buffer(10,6)) + + return regtree +end + +-- ############################################# + +function dissect_packet(subtree, buffer, flags, pinfo) + local pktree = subtree:add(packet_field, buffer) + + pktree:add(src_mac, buffer(0,6)) + pktree:add(dst_mac, buffer(6,6)) + + if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then + idx = dissect_socket(pktree, buffer, 12) + else + idx = 12 + end + + pktree:add(packet_transform, buffer(idx,2)) + local payload = pktree:add(packet_payload, buffer(idx+2)) + local transform = buffer(idx,2):uint() + + -- Can only dissect unencrypted data + if(transform == PKT_TRANSFORM_NULL) then + Dissector.get("eth_withoutfcs"):call(buffer(idx+2):tvb(), pinfo, payload) + end + + return pktree +end + +-- ############################################# + +function dissect_register_super(subtree, buffer, flags) + local regtree = subtree:add(register_super_field, buffer) + + regtree:add(register_super_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(register_super_auth_schema, buffer(10,2)) + regtree:add(register_super_auth_data, buffer(12,2)) + + return regtree +end + +-- ############################################# + +function dissect_register_super_ack(subtree, buffer, flags) + local regtree = subtree:add(register_super_ack_field, buffer) + + regtree:add(register_super_ack_cookie, buffer(0,4)) + regtree:add(dst_mac, buffer(4,6)) + regtree:add(register_super_ack_lifetime, buffer(10,2)) + local idx = dissect_socket(regtree, buffer, 12) + regtree:add(register_super_ack_num_sn, buffer(idx, 1)) + + return regtree +end + +-- ############################################# + +function dissect_peer_info(subtree, buffer, flags) + local peertree = subtree:add(peer_info_field, buffer) + + peertree:add(peer_info_flags, buffer(0,2)) + peertree:add(peer_info_mac, buffer(2,6)) + dissect_socket(peertree, buffer, 8) + + return peertree +end + +-- ############################################# + +function dissect_query_peer(subtree, buffer, flags) + local peertree = subtree:add(query_peer_field, buffer) + + peertree:add(src_mac, buffer(0,6)) + peertree:add(dst_mac, buffer(6,6)) + + return peertree +end + +-- ############################################# + +function n2n.dissector(buffer, pinfo, tree) + local length = buffer:len() + if length < 20 then return end + + pinfo.cols.protocol = n2n.name + + local pkt_type = bit.band(buffer(2,2):uint(), packet_type_mask) + local subtree = tree:add(n2n, buffer(), string.format("n2n Protocol, Type: %s", pkt_type_2_str[pkt_type] or "Unknown")) + + -- Common + subtree:add(version, buffer(0,1)) + subtree:add(ttl, buffer(1,1)) + subtree:add(packet_type, buffer(2,2)) + local flags_buffer = buffer(2,2) + local flags_tree = subtree:add(flags, flags_buffer) + subtree:add(community, buffer(4,16)) + + -- Flags + flags_tree:add(from_supernode_flag, flags_buffer) + flags_tree:add(socket_flag, flags_buffer) + flags_tree:add(options_flag, flags_buffer) + + -- Packet specific + local flags = bit.band(buffer(2,2):uint(), flags_mask) + local typebuf = buffer(20) + + if(pkt_type == PKT_TYPE_REGISTER) then + dissect_register(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_REGISTER) then + dissect_register_ack(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_PACKET) then + dissect_packet(subtree, typebuf, flags, pinfo) + elseif(pkt_type == PKT_TYPE_REGISTER_SUPER) then + dissect_register_super(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_REGISTER_SUPER_ACK) then + dissect_register_super_ack(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_PEER_INFO) then + dissect_peer_info(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_QUERY_PEER) then + dissect_query_peer(subtree, typebuf, flags) + end +end + +-- ############################################# + +local udp_port = DissectorTable.get("udp.port") +udp_port:add(50001, n2n) diff --git a/bundles/n2n_ntop_v3/.ci/build-project.ps1 b/bundles/n2n_ntop_v3/.ci/build-project.ps1 new file mode 100644 index 00000000..b0d76432 --- /dev/null +++ b/bundles/n2n_ntop_v3/.ci/build-project.ps1 @@ -0,0 +1,45 @@ +# Build project. +# +# The script assumes that it will be called from inside the project directory. +# +# Usage: .ci\build-project.ps1 [vcpkg-directory [build-directory-name]] +# - vcpkg-directory: Optional full path to Vcpkg directory. Default: $HOME\vcpkg +# - build-directory-name: Optional name of build directory. Default: build. +# Can only be set of vcpkg-directory is set as well. +# +# Example 1: .ci\build-project.ps1 +# Example 2: .ci\build-project.ps1 $HOME\vcpkg-clang +# Example 3: .ci\build-project.ps1 $HOME\vcpkg-clang build-clang + +$ErrorActionPreference="Stop" + +$VCPKG_DIR=$args[0] +$BUILD_DIR=$args[1] + +if ($null -eq $VCPKG_DIR) { $VCPKG_DIR="$HOME\vcpkg" } +if ($null -eq $BUILD_DIR) { $BUILD_DIR="build" } + +# only pass toolchain file to CMake if Vcpkg is installed +if (Test-Path "$VCPKG_DIR" -PathType Container) { + $TOOLCHAIN="$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake" +} else { + $TOOLCHAIN="False" +} + +Write-Host "---- build-project.ps1 ----" +Write-Host "VCPKG_DIR: $VCPKG_DIR" +Write-Host "BUILD_DIR: $BUILD_DIR" +Write-Host "CMAKE_TOOLCHAIN_FILE: $TOOLCHAIN" +Write-Host "---------------------------" + +if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) { + New-Alias -Name cmake -Value "$Env:ProgramFiles\CMake\bin\cmake.exe" +} + +New-Item -Name $BUILD_DIR -ItemType Directory +Push-Location $BUILD_DIR +$ErrorActionPreference = "Stop"; +cmake -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" .. +cmake --build . --config Release +if ($LASTEXITCODE) { Throw "BUILD FAILED!" } +Pop-Location \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/.ci/install-vcpkg.ps1 b/bundles/n2n_ntop_v3/.ci/install-vcpkg.ps1 new file mode 100644 index 00000000..a9f4bc1e --- /dev/null +++ b/bundles/n2n_ntop_v3/.ci/install-vcpkg.ps1 @@ -0,0 +1,38 @@ + +# Build Vcpkg and install dependency packages. +# +# Usage: .ci\install-vcpkg.ps1 [vcpkg directory name] +# - project directory: Path to the project sources where the .vcpkg file is located. +# - vcpkg directory name: optional name of directory where Vcpkg will be clone'd into +# +# Example 1: .ci\install-vcpkg.ps1 $Env:GITHUB_WORKSPACE +# Example 2: .ci\install-vcpkg.ps1 $Env:APPVEYOR_BUILD_FOLDER vcpkg-msvc + +$ErrorActionPreference="Stop" + +if ($args.Count -lt 1) { Exit 1 } + +$PROJECT_DIR=$args[0] +$VCPKG_DIR=$args[1] + +if ($null -eq $VCPKG_DIR) { $VCPKG_DIR="vcpkg" } + +# do nothing if .vcpkg file doesn't exist +if (-not (Test-Path "$PROJECT_DIR\.vcpkg" -PathType Leaf)) { Write-Host ".vcpkg file does not exist, skipping Vcpkg installation."; Exit 0 } + +Write-Host "---- install-vcpkg.ps1 ----" +Write-Host "PROJECT_DIR: $PROJECT_DIR" +Write-Host "VCPKG_DIR: $VCPKG_DIR" +Write-Host "---------------------------" + +if (-not (Get-Command git -ErrorAction SilentlyContinue)) { + New-Alias -Name git -Value "$Env:ProgramFiles\Git\bin\git.exe" +} + +Push-Location "$HOME" +git clone --quiet --depth 1 https://github.com/Microsoft/vcpkg.git $VCPKG_DIR +Set-Location $VCPKG_DIR +.\bootstrap-vcpkg.bat -disableMetrics +$packages = Get-Content "$PROJECT_DIR\.vcpkg" +.\vcpkg.exe install --triplet x64-windows $packages +Pop-Location \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/.github/workflows/cmake-linux.yml b/bundles/n2n_ntop_v3/.github/workflows/cmake-linux.yml new file mode 100644 index 00000000..a018a58d --- /dev/null +++ b/bundles/n2n_ntop_v3/.github/workflows/cmake-linux.yml @@ -0,0 +1,59 @@ +--- +name: CMake + +# yamllint disable-line rule:truthy +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should + # work equally well on Windows or Mac. You can convert this to a matrix + # build if you need cross-platform coverage. + # yamllint disable-line rule:line-length + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + - os: windows-latest + - os: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate + # build directory. We'll use this as our working directory for all + # subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment + # variable access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to + # specify source and build directories, but this is only available + # with CMake 3.13 and higher. The CMake binaries on the Github Actions + # machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target + # with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Test + working-directory: ${{github.workspace}}/build + shell: bash + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more + # detail + run: ctest -C $BUILD_TYPE diff --git a/bundles/n2n_ntop_v3/.github/workflows/tests.yml b/bundles/n2n_ntop_v3/.github/workflows/tests.yml new file mode 100644 index 00000000..8b8e8e06 --- /dev/null +++ b/bundles/n2n_ntop_v3/.github/workflows/tests.yml @@ -0,0 +1,558 @@ +--- +name: Testing + +# yamllint disable-line rule:truthy +on: + push: + pull_request: + +jobs: + smoketest: + name: Smoke test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Run minimal test set + run: | + ./autogen.sh + ./configure + make test + + lint: + name: Code syntax + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Make the makefiles + run: | + ./autogen.sh + ./configure + + - name: Install essential + run: | + make build-dep + + - name: Run the lint tools + run: | + make lint + + test_linux: + needs: smoketest + name: Test Linux + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: + - ubuntu-20.04 + - ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + + - name: Install essential + run: | + sudo apt-get update + sudo apt-get install build-essential + + - name: generate a makefile and use it to install more packages + run: | + ./autogen.sh + ./configure + make build-dep + shell: bash + + - name: Run the real configure step + run: | + export CFLAGS="-fprofile-arcs -ftest-coverage" + export LDFLAGS="--coverage" + ./configure --with-zstd + shell: bash + + - name: Run embedded tests + run: make test + shell: bash + + - if: ${{ always() }} + name: Move test outputs to an arch specific location + shell: bash + run: | + mkdir -p tests/${{ matrix.os }} + mv tests/*.out tests/${{ matrix.os }} + + - if: ${{ always() }} + name: Upload tests output + uses: actions/upload-artifact@v2 + with: + name: tests-out + path: tests + + - name: Generate coverage reports + run: | + make gcov + make cover COVERAGEDIR=coverage/${{ matrix.os }} + shell: bash + + - name: Upload gcovr report artifact + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage + + - name: Upload data to codecov + uses: codecov/codecov-action@v2 + + test_macos: + needs: smoketest + name: Test MacOS + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: + - macos-10.15 + - macos-11 + + steps: + - uses: actions/checkout@v2 + + - name: Install packages + run: | + brew install automake + + - name: generate a makefile and use it to install more packages + run: | + ./autogen.sh + ./configure + make build-dep + shell: bash + + - name: Run the real configure step + run: | + export CFLAGS="-fprofile-arcs -ftest-coverage" + export LDFLAGS="--coverage" + ./configure --with-zstd + shell: bash + + - name: Run embedded tests + run: make test + shell: bash + + - if: ${{ always() }} + name: Move test outputs to an arch specific location + shell: bash + run: | + mkdir -p tests/${{ matrix.os }} + mv tests/*.out tests/${{ matrix.os }} + + - if: ${{ always() }} + name: Upload tests output + uses: actions/upload-artifact@v2 + with: + name: tests-out + path: tests + + - name: Generate coverage reports + run: | + make gcov + # This was working fine for tens of jobs, up until + # 2021-10-19T18:53+0100 and it still works fine when run from my + # personal github actions. The next run at 2021-10-19T19:08+0100 + # didnt work. + # Assume that they changed something on the runner - I cannot debug + # it as I do not have a Mac. + # + # make cover COVERAGEDIR=coverage/${{ matrix.os }} + shell: bash + + # - name: Upload gcovr report artifact + # uses: actions/upload-artifact@v2 + # with: + # name: coverage + # path: coverage + + - name: Upload data to codecov + uses: codecov/codecov-action@v2 + + test_windows: + needs: smoketest + name: Test Windows + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + os: + - windows-2016 + - windows-2019 + - windows-2022 + + steps: + - uses: actions/checkout@v2 + + - name: generate a makefile and use it to install more packages + run: | + # This is a pretty big hammer, but gets the windows compile moving + ./scripts/hack_fakeautoconf.sh + make build-dep + shell: bash + + - name: Run a configure step + run: | + export CFLAGS="-fprofile-arcs -ftest-coverage" + export LDFLAGS="--coverage" + ./scripts/hack_fakeautoconf.sh + shell: bash + + - name: Run embedded tests + run: make test + shell: bash + + - if: ${{ always() }} + name: Move test outputs to an arch specific location + shell: bash + run: | + mkdir -p tests/${{ matrix.os }} + mv tests/*.out tests/${{ matrix.os }} + + - if: ${{ always() }} + name: Upload tests output + uses: actions/upload-artifact@v2 + with: + name: tests-out + path: tests + + - name: Generate coverage data + run: | + make gcov + shell: bash + + - name: Upload data to codecov + uses: codecov/codecov-action@v2 + + package_dpkg: + name: Package for Debian/Ubuntu + needs: + - test_linux + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + arch: + - amd64 + - arm64 + - armhf + - i386 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Install packages needed for build + run: | + sudo apt-get update + sudo apt-get install debhelper build-essential \ + crossbuild-essential-${{ matrix.arch }} + + - name: Configure + # The HOST_TRIPLET line is not easily foldable + # yamllint disable rule:line-length + run: | + # This will warn about CC, but we cannot set CC until we run it :-S + HOST_TRIPLET=$(dpkg-architecture -a${{ matrix.arch }} -q DEB_HOST_GNU_TYPE) + export CC=$HOST_TRIPLET-gcc + export AR=$HOST_TRIPLET-ar + ./autogen.sh + ./configure --host $HOST_TRIPLET + cd packages/debian/ + ./configure EXTN=${{ matrix.arch }} + # yamllint enable rule:line-length + + - name: Build + run: | + cd packages/debian/ + make + + - name: Upload dpkg + uses: actions/upload-artifact@v2 + with: + name: packages-dpkg + path: packages/debian/*.deb + + package_rpm: + name: Package for Redhat/RPM + needs: + - test_linux + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Install packages needed for build + run: | + sudo apt-get install rpm + + - name: Configure + run: | + ./autogen.sh + ./configure + cd packages/rpm/ + ./configure + + - name: Build + run: | + make + HOME=$(pwd)/../ + cd packages/rpm/ + make + cd ../../ + mv ../rpmbuild ./ + + - name: Upload rpm + uses: actions/upload-artifact@v2 + with: + name: packages-rpm + path: rpmbuild/RPMS/x86_64/*.rpm + + binaries_windows: + name: Binaries for Windows (x86_64-pc-mingw64) + needs: + - test_windows + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Configure and Build + shell: bash + run: | + ./scripts/hack_fakeautoconf.sh + make + + - name: Create binary dir + shell: bash + run: | + make install DESTDIR=binaries/x86_64-pc-mingw64 + + - name: Upload binary artifacts + uses: actions/upload-artifact@v2 + with: + name: binaries + path: binaries + + binaries_macos: + name: Binaries for MacOS + needs: + - test_macos + runs-on: macos-latest + strategy: + fail-fast: true + matrix: + arch: + - x86_64-apple-macos + - arm64-apple-macos + + steps: + - uses: actions/checkout@v2 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Install packages needed for build + run: | + brew install automake + + - name: Configure and Build + shell: bash + run: | + # this is a hack! it assumes the default SDK is the 'right' one + export SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk + ./autogen.sh + export CC=clang + export CFLAGS="-target ${{ matrix.arch }}" + export LDFLAGS="-target ${{ matrix.arch }}" + ./configure --host=${{ matrix.arch }} + make + + - if: ${{ failure() }} + name: Upload config.log output + uses: actions/upload-artifact@v2 + with: + name: config-log-${{ matrix.arch }} + path: config.log + + - name: Create binary dir + shell: bash + run: | + make install DESTDIR=binaries/${{ matrix.arch }} + + - name: Upload binary artifacts + uses: actions/upload-artifact@v2 + with: + name: binaries + path: binaries + + binaries_macos_universal: + name: Binaries for MacOS (universal arch) + needs: + - test_macos + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Install packages needed for build + run: | + brew install automake + + - name: Configure and Build + shell: bash + run: | + # this is a hack! it assumes the default SDK is the 'right' one + export SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk + ./autogen.sh + export CC=clang + export CFLAGS="-arch x86_64 -arch arm64" + export LDFLAGS="-arch x86_64 -arch arm64" + ./configure + make + + - name: Create binary dir + shell: bash + run: | + make install DESTDIR=binaries/universal-apple-darwin + + - name: Upload binary artifacts + uses: actions/upload-artifact@v2 + with: + name: binaries + path: binaries + + binaries_linux_crosscompile: + name: Binaries for linux + needs: + - test_linux + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + arch: + - arm-linux-gnueabi + + # I assume these architectures produce working code, but this has + # not been directly confirmed. + # They are compiled dynamically against normal libc, so will not + # work on openwrt. + - aarch64-linux-gnu + - mips-linux-gnu + - mipsel-linux-gnu + + steps: + - uses: actions/checkout@v2 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Install cross compiler + run: | + sudo apt-get update + sudo apt-get install \ + binutils-${{ matrix.arch }} \ + gcc-${{ matrix.arch }} + + - name: Configure and Build + shell: bash + run: | + ./autogen.sh + export CC=${{ matrix.arch }}-gcc + export AR=${{ matrix.arch }}-ar + ./configure --host ${{ matrix.arch }} + make + + - name: Create binary dir + shell: bash + run: | + make install DESTDIR=binaries/${{ matrix.arch }} + + - name: Upload binary artifacts + uses: actions/upload-artifact@v2 + with: + name: binaries + path: binaries + + # Given the clearly documented use of annotated tags to signal releases, + # it seems strange that there is no simple way to trigger actions if the + # tag is annotated. So we need to jump through some extra hoops. + # + # Looking at https://github.com/actions/checkout/issues/290 seems to show + # that github just doesnt care about how git expects annotated tags to be + # used. + # + # This workflow has added a `git fetch --force --tags` to every job that + # needs to have working tags + + upload_release: + name: Upload Release Assets + if: startsWith(github.ref, 'refs/tags/') + needs: + - package_dpkg + - package_rpm + - binaries_windows + - binaries_macos + - binaries_macos_universal + - binaries_linux_crosscompile + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Fix Checkout + run: | + git fetch --force --tags + + - name: Get Tag Type + id: get_tagtype + run: | + TYPE=$(git cat-file -t $GITHUB_REF) + echo "::set-output name=TAGTYPE::$TYPE" + echo ========== + echo REF=$GITHUB_REF + echo TAGTYPE=$TYPE + + - name: Fetch all Artifacts + if: steps.get_tagtype.outputs.TAGTYPE == 'tag' + uses: actions/download-artifact@v2 + with: + path: artifacts + + - name: Upload Assets to Release + if: steps.get_tagtype.outputs.TAGTYPE == 'tag' + uses: softprops/action-gh-release@v1 + with: + prerelease: true + files: | + artifacts/packages-dpkg/*.deb + artifacts/packages-rpm/*.rpm diff --git a/bundles/n2n_ntop_v3/.gitignore b/bundles/n2n_ntop_v3/.gitignore new file mode 100644 index 00000000..ae2b1427 --- /dev/null +++ b/bundles/n2n_ntop_v3/.gitignore @@ -0,0 +1,52 @@ +*.o +*.a +*.gz +configure +configure.ac +config.* +/Makefile +tools/Makefile +autom4te.cache +edge +example_edge_embed_quick_edge_init +example_edge_embed +example_sn_embed +supernode +tools/n2n-benchmark +tools/n2n-decode +tools/n2n-keygen +build +.idea +cmake-build-default +packages/debian/debian/changelog +packages/debian/debian/control +packages/debian/debian/files +packages/debian/debian/rules +packages/etc/systemd/system/edge-ntopng@.service +packages/etc/systemd/system/edge.service +packages/etc/systemd/system/edge@.service +packages/etc/systemd/system/supernode.service +*dSYM* + +cmake-build-*/ + +# Binaries built to run tests +tools/tests-compress +tools/tests-elliptic +tools/tests-hashing +tools/tests-transform +tools/tests-wire + +# Files generated while running tests +tests/*.out + +# Files generated while running coverage reports +*.gcno +*.gcda +*.gcov +coverage/ + +# Files generated while running linting +*.indent +*.unc-backup.md5~ +*.unc-backup~ diff --git a/bundles/n2n_ntop_v3/.travis.yml b/bundles/n2n_ntop_v3/.travis.yml new file mode 100644 index 00000000..08d9211d --- /dev/null +++ b/bundles/n2n_ntop_v3/.travis.yml @@ -0,0 +1,26 @@ +--- +language: c++ +dist: xenial + +compiler: + - clang + - gcc + +install: + - sudo apt-get update || true + - sudo apt-get install build-essential + +before_script: + - git clone https://github.com/ntop/n2n.git; cd n2n; ./autogen.sh; make; cd .. + - ./autogen.sh + +script: + - ./configure + - make + +notifications: + email: + recipients: + - deri@ntop.org + on_success: never + on_failure: always diff --git a/bundles/n2n_ntop_v3/.yamllint.yml b/bundles/n2n_ntop_v3/.yamllint.yml new file mode 100644 index 00000000..b54dd76d --- /dev/null +++ b/bundles/n2n_ntop_v3/.yamllint.yml @@ -0,0 +1,8 @@ +--- +extends: default + +rules: + # 80 chars should be enough, but don't fail if a line is longer + line-length: + max: 80 + level: warning diff --git a/bundles/n2n_ntop_v3/CHANGELOG.md b/bundles/n2n_ntop_v3/CHANGELOG.md new file mode 100644 index 00000000..3893fcc0 --- /dev/null +++ b/bundles/n2n_ntop_v3/CHANGELOG.md @@ -0,0 +1,89 @@ +# Changelog + +## n2n 2.8 (August 2020) + +This release brings significant new features to n2n's crypto world and offers +some compression opportunities. The added support for routing table manipulation +might increase comfort. Besides further honing existing features, this release +addresses some bugs. + +### New Features + +* Two lightweight stream ciphers: ChaCha20 (optional, through OpenSSL) & SPECK (integrated) +* Full Header Encryption (including packet checksumming as well as replay protection) +* A callback interface to better integrate n2n in third party software (you can still use it stand-alone) +* Enable the integrated LZO1x compression +* Add optional ZSTD compression (through zstdlib) +* Support for changing system routes at program start and end +* User and group id parameter for supernode +* Application of cryptography in n2n is seperately documented +* Add a new pseudo random number generator with higher periodicity seeded with more entropy if available + +### Improvements + +* Have AES and ChaCha20 use OpenSSL's `evp_*` interface to make better use of available hardware acceleration +* Fix invalid sendto when supernode name resolution fails +* Update to supernode's purge logic +* Extended management supernode's port output +* Fix read tap device failed when OS wakes up from sleep +* Free choice of supernode's management UDP port (for multiple supernodes on one machine) +* Additional trace messages to better indicate established connections and connection type +* Fix edge's register-to-supernode loop +* Remove redundant code +* Restructure the code in directories +* Clean-up platform-dependant code +* Compile fixes for Windows +* Fix build warnings +* …and many more under-the-hood fixes and tunings + +## n2n 2.6 (March 2020) + +The 2.6 release is mostly a maintenance release to address the issues +of 2.4 that has been the first release since a long time of silence. + +### New Features + +* AES encryption that features an overall speed bump (12x speed) and security with respect to Twofish used in the previous n2n version +* Add ability to specify a whitelist of allowed communities on the supernode +* Implement local peers discovery via multicast +* Full peer-to-peer topology support. +* Add support for multiple edge systemd services +* Add benchmark tool for the encryption throughput +* Implement packet stats for P2P vs supernode communication +* Automatically drop privileges to user n2n +* Add support for ARM64 build +* More options to control MTU, P2P connections, TOS and log verbosity +* Implement a wireshark dissector for the n2n protocol +* Implement n2n-decode utility to decode and dump traffic to PCAP + + +### Improvements +* Extensive Windows and OpenWRT support. +* Windows compilation fixes and instructions +* Instructions and makefile file to build n2n on OpenWRT +* MacOS compilation fixes and instructions +* Improve the connection stability and the chances to establish a P2P connection +* Stable and more resilient connection. +* Remove keyschedule support to simplify the encryption code +* Replace peers linked list with hash table for faster lookup in big networks +* Integrate the changes made in the meyerd fork of n2n +* Remove calls to system() in tuntap_linux and use netlink instead +* n2n version improvements + +## n2n 2.4 (August 2018) + +This is the first release after 2012 and thus it is focusing mainly +on making it work on current operating system versions, so that the +next release will be based on modern code. + +### New Features +* Added deb/rpm packages +* Added systemd configuration files +* Added ability to read configuration files instead of using only the CLI (needed for packaging) +* Added n2n Android app +* Implemented simple API to embed n2n in applications (in addition to use it stand-alone) + +### Improvements +* Major code cleanup +* Fixed compilation issues on MacOS +* Fixed Linux segmentation fault diff --git a/bundles/n2n_ntop_v3/CMakeLists.txt b/bundles/n2n_ntop_v3/CMakeLists.txt new file mode 100644 index 00000000..f7249740 --- /dev/null +++ b/bundles/n2n_ntop_v3/CMakeLists.txt @@ -0,0 +1,276 @@ +project(n2n) +cmake_minimum_required(VERSION 2.6) +include(CheckFunctionExists) +SET(CMAKE_VERBOSE_MAKEFILE ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# N2n release information +set(N2N_VERSION "3.0.0") +set(N2N_OSNAME ${CMAKE_SYSTEM_NAME}) +execute_process( + COMMAND git status + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_OUTPUT + RESULT_VARIABLE GIT_ERROR_CODE +) +if (GIT_ERROR_CODE EQUAL 0) +execute_process( + COMMAND git rev-list --count HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_REV +) +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_ID +) +string(REGEX REPLACE "\n$" "" GIT_REV "${GIT_REV}") +string(REGEX REPLACE "\n$" "" GIT_ID "${GIT_ID}") +set(N2N_VERSION "${N2N_VERSION}.r${GIT_REV}.${GIT_ID}") +MESSAGE(STATUS "Build from git rev: ${N2N_VERSION}") +endif (GIT_ERROR_CODE EQUAL 0) + +add_definitions(-DCMAKE_BUILD) +add_definitions(-DGIT_RELEASE="${N2N_VERSION}" -DPACKAGE_VERSION="${N2N_VERSION}" -DPACKAGE_OSNAME="${N2N_OSNAME}") +add_definitions(-DN2N_VERSION="${N2N_VERSION}" -DN2N_OSNAME="${N2N_OSNAME}") + + +# Build information +OPTION(BUILD_SHARED_LIBS "BUILD Shared Library" OFF) + +# N2n specific params +OPTION(N2N_OPTION_USE_PTHREAD "USE PTHREAD Library" ON) +OPTION(N2N_OPTION_USE_OPENSSL "USE OPENSSL Library" OFF) +OPTION(N2N_OPTION_USE_PCAPLIB "USE PCAP Library" OFF) +OPTION(N2N_OPTION_USE_ZSTD "USE ZSTD Library" OFF) + + +if(N2N_OPTION_USE_PTHREAD) + find_library(PTHREAD_LIB pthread) + if(PTHREAD_LIB) + ADD_DEFINITIONS("-DHAVE_PTHREAD") + else() + MESSAGE(WARNING "libpthread not found.") + set(N2N_OPTION_USE_PTHREAD OFF) + endif(PTHREAD_LIB) +endif(N2N_OPTION_USE_PTHREAD) + +if(NOT DEFINED N2N_OPTION_USE_OPENSSL) +set(N2N_OPTION_USE_OPENSSL OFF) +endif(NOT DEFINED N2N_OPTION_USE_OPENSSL) + +if(N2N_OPTION_USE_OPENSSL) + find_package(OpenSSL QUIET) + if(NOT OPENSSL_FOUND) + MESSAGE(WARNING "OpenSSL not found, Use built-in AES.") + set(N2N_OPTION_USE_OPENSSL OFF) + else() + MESSAGE(STATUS "Found OpenSSL ${OPENSSL_VERSION}") + string(COMPARE GREATER "${OPENSSL_VERSION}" "1.1" OPENSSL_V11) + if(OPENSSL_V11) + MESSAGE(STATUS "Use OpenSSL With -DHAVE_OPENSSL_1_1") + include_directories(${OPENSSL_INCLUDE_DIR}) + add_definitions(-DHAVE_OPENSSL_1_1) + endif() + endif(NOT OPENSSL_FOUND) +endif(N2N_OPTION_USE_OPENSSL) + +if(N2N_OPTION_USE_ZSTD) + add_definitions(-DN2N_HAVE_ZSTD) +endif(N2N_OPTION_USE_ZSTD) + +if(NOT DEFINED CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE None) +endif(NOT DEFINED CMAKE_BUILD_TYPE) +#set(CMAKE_BUILD_TYPE Debug) +#set(CMAKE_BUILD_TYPE Release) + +if (DEFINED UNIX) +# None +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") +set(CMAKE_CXX_FLAGS "-Wall -Wshadow -Wpointer-arith -Wmissing-declarations -Wnested-externs") +# Debug +set(CMAKE_C_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +# Release +set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") +endif(DEFINED UNIX) + +# Static target. +#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static") + + +INCLUDE_DIRECTORIES(.) +INCLUDE_DIRECTORIES(include) +if(DEFINED WIN32) + INCLUDE_DIRECTORIES(win32) +# Customize include. +# INCLUDE_DIRECTORIES("D:/Program Files/MinGW/opt/include/" "D:/Program Files/MinGW/x86_64-w64-mingw32/include/") +# Customize library. +# LINK_DIRECTORIES("D:/Program Files/MinGW/opt/lib/" "D:/Program Files/MinGW/x86_64-w64-mingw32/lib/") +endif(DEFINED WIN32) + + +#aux_source_directory(./src N2N_DIR_SRCS) +#add_library(n2n STATIC ${N2N_DIR_SRCS}) +add_library(n2n STATIC + src/n2n.c + src/edge_management.c + src/edge_utils.c + src/sn_management.c + src/sn_utils.c + src/wire.c + src/hexdump.c + src/minilzo.c + src/tf.c + src/cc20.c + src/transform_null.c + src/transform_tf.c + src/transform_aes.c + src/transform_cc20.c + src/transform_speck.c + src/aes.c + src/speck.c + src/random_numbers.c + src/pearson.c + src/header_encryption.c + src/tuntap_freebsd.c + src/tuntap_netbsd.c + src/tuntap_linux.c + src/tuntap_osx.c + src/n2n_regex.c + src/network_traffic_filter.c + src/sn_selection.c + src/auth.c + src/curve25519.c) + + +if(N2N_OPTION_USE_PTHREAD) + target_link_libraries(n2n pthread) +endif(N2N_OPTION_USE_PTHREAD) + +if(N2N_OPTION_USE_OPENSSL) +# target_link_libraries(n2n crypto) + target_link_libraries(n2n ${OPENSSL_LIBRARIES}) +endif(N2N_OPTION_USE_OPENSSL) + +if(N2N_OPTION_USE_ZSTD) + target_link_libraries(n2n zstd) +endif(N2N_OPTION_USE_ZSTD) + +if(DEFINED WIN32) + add_library(edge_utils_win32 src/edge_utils_win32.c) + add_subdirectory(win32) + target_link_libraries(n2n edge_utils_win32 n2n_win32 iphlpapi) +endif(DEFINED WIN32) + +add_executable(edge src/edge.c) +target_link_libraries(edge n2n) + +add_executable(supernode src/supernode.c) +target_link_libraries(supernode n2n) + +add_executable(example_edge_embed_quick_edge_init src/example_edge_embed_quick_edge_init.c) +target_link_libraries(example_edge_embed_quick_edge_init n2n) + +add_executable(example_edge_embed src/example_edge_embed.c) +target_link_libraries(example_edge_embed n2n) + +add_executable(example_sn_embed src/example_sn_embed.c) +target_link_libraries(example_sn_embed n2n) + +if(N2N_OPTION_USE_PCAPLIB AND (NOT DEFINED WIN32)) + # Linux Capabilities + find_library(CAP_LIB cap) + if(CAP_LIB) + target_link_libraries(edge cap.a) + set(CMAKE_REQUIRED_LIBRARIES ${CAP_LIB}) + ADD_DEFINITIONS("-DHAVE_LIBCAP") + endif() +endif(N2N_OPTION_USE_PCAPLIB AND (NOT DEFINED WIN32)) + +install(TARGETS edge supernode + RUNTIME DESTINATION sbin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + + +# Tools +add_executable(n2n-benchmark tools/n2n-benchmark.c) +target_link_libraries(n2n-benchmark n2n) +add_executable(n2n-keygen tools/n2n-keygen.c) +target_link_libraries(n2n-keygen n2n) + +add_executable(tests-compress tools/tests-compress.c) +target_link_libraries(tests-compress n2n) +add_executable(tests-elliptic tools/tests-elliptic.c) +target_link_libraries(tests-elliptic n2n) +add_executable(tests-hashing tools/tests-hashing.c) +target_link_libraries(tests-hashing n2n) +add_executable(tests-transform tools/tests-transform.c) +target_link_libraries(tests-transform n2n) +add_executable(tests-wire tools/tests-wire.c) +target_link_libraries(tests-wire n2n) + +if(N2N_OPTION_USE_PCAPLIB) + find_library(PCAP_LIB pcap) + if(PCAP_LIB) + add_executable(n2n-decode tools/n2n-decode.c) + target_link_libraries(n2n-decode n2n pcap) + install(TARGETS n2n-decode RUNTIME DESTINATION bin) + + set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIB}) + check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE) + IF(HAVE_PCAP_IMMEDIATE_MODE) + ADD_DEFINITIONS("-DHAVE_PCAP_IMMEDIATE_MODE") + ENDIF(HAVE_PCAP_IMMEDIATE_MODE) + endif(PCAP_LIB) +endif(N2N_OPTION_USE_PCAPLIB) + +install(TARGETS n2n-benchmark RUNTIME DESTINATION bin) + +# Documentation +if(DEFINED UNIX) +add_dependencies(n2n doc) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/doc) +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/edge.8.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/edge.8 > ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DEPENDS ${PROJECT_SOURCE_DIR}/edge.8 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/supernode.1 > ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DEPENDS ${PROJECT_SOURCE_DIR}/supernode.1 + ) + +add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + COMMAND gzip -c ${PROJECT_SOURCE_DIR}/n2n.7 > ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + DEPENDS ${PROJECT_SOURCE_DIR}/n2n.7 + ) + +add_custom_target(doc DEPENDS ${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + ) + +set_source_files_properties(${PROJECT_BINARY_DIR}/doc/edge.8.gz + ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + PROPERTIES GENERATED 1) + +install(FILES ${PROJECT_BINARY_DIR}/doc/edge.8.gz + DESTINATION /usr/share/man/man8) +install(FILES ${PROJECT_BINARY_DIR}/doc/supernode.1.gz + DESTINATION /usr/share/man/man1) +install(FILES ${PROJECT_BINARY_DIR}/doc/n2n.7.gz + DESTINATION /usr/share/man/man7) + +# TODO: +# - Add the right dependancy so that the tests binaries get built first +enable_testing() +add_test(tests ${PROJECT_SOURCE_DIR}/scripts/test_harness.sh ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/tests) + +endif(DEFINED UNIX) diff --git a/bundles/n2n_ntop_v3/COPYING b/bundles/n2n_ntop_v3/COPYING new file mode 100644 index 00000000..b33b35d0 --- /dev/null +++ b/bundles/n2n_ntop_v3/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + n2n Copyright (C) 2007-08 Luca Deri + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v3/INSTALL b/bundles/n2n_ntop_v3/INSTALL new file mode 100644 index 00000000..22000326 --- /dev/null +++ b/bundles/n2n_ntop_v3/INSTALL @@ -0,0 +1,50 @@ +INSTALL + +To build the programs: + +$ make + +To install the programs and man pages: + +$ make install + +or + +$ make PREFIX=/usr/local install + + +RPM Package +----------- + +These steps should work with RPM based Linux distributions since rpmbuild was +split from the rpm utility (c RedHat 9). + + +To build an RPM the easy way follow these steps. + +1. Build SRPM + +$ cd n2n +$ scripts/mk_SRPM.sh + +Look for where the src.rpm file was put ( "Wrote:" ). + +2. Build binary RPM from SRPM + +$ rpm -i path/to/n2n-.src.rpm +$ rpmbuild -bb n2n.spec + + +All this can be done as non-root user if you have a ~/.rpmmacros file with this +line in it: + +%_topdir /home/username/rpmtopdir + + +To build an RPM the hard way follow these steps. + +$ cp -a n2ndir n2n-2.0 +$ tar czf n2n-2.0.tar.gz n2n-2.0 +$ mv n2n-2.0.tar.gz /usr/src/redhat/SOURCES +$ cp n2ndir/n2n.spec /usr/src/redhat/SPECS +$ rpmbuild -bb n2n.spec diff --git a/bundles/n2n_ntop_v3/LICENSE b/bundles/n2n_ntop_v3/LICENSE new file mode 100644 index 00000000..9cecc1d4 --- /dev/null +++ b/bundles/n2n_ntop_v3/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v3/Makefile.in b/bundles/n2n_ntop_v3/Makefile.in new file mode 100644 index 00000000..61d16273 --- /dev/null +++ b/bundles/n2n_ntop_v3/Makefile.in @@ -0,0 +1,284 @@ + +# NOTE: these are needed by the configure.in inside the packages folder +N2N_VERSION_SHORT=@N2N_VERSION_SHORT@ +GIT_COMMITS=@GIT_COMMITS@ +GIT_DESCRIBE=$(shell git describe --always --dirty) + +######## + +export CC +export AR +CC=@CC@ +AR=@AR@ + +#Ultrasparc64 users experiencing SIGBUS should try the following gcc options +#(thanks to Robert Gibbon) +PLATOPTS_SPARC64=-mcpu=ultrasparc -pipe -fomit-frame-pointer -ffast-math -finline-functions -fweb -frename-registers -mapp-regs + +export CFLAGS +export LDFLAGS + +CFLAGS=@CFLAGS@ -I ./include +LDFLAGS=@LDFLAGS@ -L . + +OPENSSL_CFLAGS=$(shell pkg-config openssl; echo $$?) +ifeq ($(OPENSSL_CFLAGS), 0) + CFLAGS+=$(shell pkg-config --cflags-only-I openssl) +endif + +WARN=-Wall +CFLAGS+=$(DEBUG) $(OPTIMIZATION) $(WARN) $(OPTIONS) $(PLATOPTS) + +# Quick sanity check on our build environment +UNAME_S := $(shell uname -s) +ifndef UNAME_S +# This could happen if the Makefile is unable to run "uname", which can +# happen if the shell has a bad path (or is the wrong shell) +$(error Could not run uname command, cannot continue) +endif + +# Any compile environment that needs different flags, libraries, includes or +# other settings will get its own CONFIG_TARGET value. For cross compiling, +# this might be set externally to the Makefile, but if not set we try to +# set a reasonable default. + +export CONFIG_TARGET +ifndef CONFIG_TARGET +ifeq ($(shell uname -o),Msys) +CONFIG_TARGET=mingw +else ifeq ($(shell uname -s),Darwin) +CONFIG_TARGET=darwin +else ifeq ($(shell uname), SunOS) +CONFIG_TARGET=sunos +else +CONFIG_TARGET=generic +endif +endif + +export MKDIR +export INSTALL +export INSTALL_PROG +export INSTALL_DOC +export SBINDIR + +MKDIR=mkdir -p +INSTALL=install +INSTALL_PROG=$(INSTALL) -m755 +INSTALL_DOC=$(INSTALL) -m644 + +# DESTDIR set in debian make system +PREFIX?=$(DESTDIR)/usr +ifeq ($(CONFIG_TARGET),darwin) +SBINDIR=$(PREFIX)/local/sbin +else +SBINDIR=$(PREFIX)/sbin +endif + +MANDIR?=$(PREFIX)/share/man +MAN1DIR=$(MANDIR)/man1 +MAN7DIR=$(MANDIR)/man7 +MAN8DIR=$(MANDIR)/man8 + +N2N_LIB=libn2n.a +N2N_OBJS=$(patsubst src/%.c, src/%.o, $(wildcard src/*.c)) +N2N_DEPS=$(wildcard include/*.h) $(wildcard src/*.c) Makefile + +# As source files pass the linter, they can be added here (If all the source +# is passing the linter tests, this can be refactored) +LINT_CCODE=\ + include/edge_utils_win32.h \ + include/n2n_define.h \ + include/pearson.h \ + include/speck.h \ + src/edge_utils_win32.c \ + src/example_edge_embed_quick_edge_init.c \ + src/header_encryption.c \ + src/sn_selection.c \ + src/transform_cc20.c \ + src/tuntap_linux.c \ + src/wire.c \ + tools/tests-compress.c \ + tools/tests-elliptic.c \ + tools/tests-hashing.c \ + tools/tests-transform.c \ + tools/tests-wire.c \ + +export LDLIBS + +LDLIBS+=-ln2n +LDLIBS+=@N2N_LIBS@ + +#For OpenSolaris (Solaris too?) +ifeq ($(CONFIG_TARGET), sunos) +LDLIBS+=-lsocket -lnsl +endif + +ifeq ($(CONFIG_TARGET),mingw) +CFLAGS+=-I. -I./win32 -DWIN32 +LDLIBS+=$(abspath win32/n2n_win32.a) +LDLIBS+=-lws2_32 -liphlpapi +N2N_DEPS+=win32/n2n_win32.a +SUBDIRS+=win32 +endif + +APPS=edge +APPS+=supernode +APPS+=example_edge_embed_quick_edge_init +APPS+=example_edge_embed +APPS+=example_sn_embed + +DOCS=edge.8.gz supernode.1.gz n2n.7.gz + +# This is the superset of all packages that might be needed during the build. +# Mostly of use in automated build systems. +BUILD_DEP:=\ + autoconf \ + build-essential \ + flake8 \ + gcovr \ + libcap-dev \ + libzstd-dev \ + shellcheck \ + uncrustify \ + yamllint \ + +SUBDIRS+=tools + +COVERAGEDIR?=coverage + +.PHONY: $(SUBDIRS) +.PHONY: steps build push all clean distclean install test cover gcov build-dep +.PHONY: lint lint.python lint.ccode lint.shell lint.yaml + +all: $(APPS) $(DOCS) $(SUBDIRS) + +tools: $(N2N_LIB) + $(MAKE) -C $@ + +win32: + $(MAKE) -C $@ + +src/edge.o: $(N2N_DEPS) +src/supernode.o: $(N2N_DEPS) +src/example_edge_embed_quick_edge_init.o: $(N2N_DEPS) +src/example_sn_embed.o: $(N2N_DEPS) +src/example_edge_embed.o: $(N2N_DEPS) + +src/edge: $(N2N_LIB) +src/supernode: $(N2N_LIB) +src/example_edge_embed_quick_edge_init: $(N2N_LIB) +src/example_sn_embed: $(N2N_LIB) +src/example_edge_embed: $(N2N_LIB) + +%: src/% + cp $< $@ + +%.gz : % + gzip -c $< > $@ + +$(N2N_LIB): $(N2N_OBJS) + $(AR) rcs $(N2N_LIB) $(N2N_OBJS) +# $(RANLIB) $@ + +win32/n2n_win32.a: win32 + +test: tools + scripts/test_harness.sh + +lint: lint.python lint.ccode lint.shell lint.yaml + +lint.python: + flake8 scripts/n2n-ctl scripts/n2n-httpd + +lint.ccode: + scripts/indent.sh $(LINT_CCODE) + +lint.shell: + shellcheck scripts/*.sh + +lint.yaml: + yamllint . + +# To generate coverage information, run configure with +# CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="--coverage" +# and run the desired tests. Ensure that package gcovr is installed +# and then run "make cover" +cover: + mkdir -p $(COVERAGEDIR) + gcovr -s --html --html-details --output=$(COVERAGEDIR)/index.html + +# Use coverage data to generate gcov text report files. +# Unfortunately, these end up in the wrong directory due to the +# makefile layout +# The steps to use this are similar to the "make cover" above +gcov: + gcov $(N2N_OBJS) + $(MAKE) -C tools gcov + +# This is a convinent target to use during development or from a CI/CD system +build-dep: +ifeq ($(CONFIG_TARGET),generic) + sudo apt install $(BUILD_DEP) +else ifeq ($(CONFIG_TARGET),darwin) + brew install automake gcovr +else + echo Not attempting to install dependancies for system $(CONFIG_TARGET) +endif + +clean: + rm -rf $(N2N_OBJS) $(N2N_LIB) $(APPS) $(DOCS) $(COVERAGEDIR)/ *.dSYM *~ + rm -f tests/*.out src/*.gcno src/*.gcda + for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean; done + +distclean: + rm -f tests/*.out src/*.gcno src/*.gcda src/*.indent src/*.unc-backup* + rm -rf autom4te.cache/ + rm -f config.log config.status configure configure.ac Makefile tools/Makefile include/config.h include/config.h.in + rm -f doc/edge.8.gz doc/n2n.7.gz doc/supernode.1.gz + rm -f $(addprefix src/,$(APPS)) + +install: edge supernode edge.8.gz supernode.1.gz n2n.7.gz + echo "MANDIR=$(MANDIR)" + $(MKDIR) $(SBINDIR) $(MAN1DIR) $(MAN7DIR) $(MAN8DIR) + $(INSTALL_PROG) supernode $(SBINDIR)/ + $(INSTALL_PROG) edge $(SBINDIR)/ + $(INSTALL_DOC) edge.8.gz $(MAN8DIR)/ + $(INSTALL_DOC) supernode.1.gz $(MAN1DIR)/ + $(INSTALL_DOC) n2n.7.gz $(MAN7DIR)/ + $(MAKE) -C tools install SBINDIR=$(abspath $(SBINDIR)) + +# Docker builder section +DOCKER_IMAGE_NAME=ntop/supernode +DOCKER_IMAGE_VERSION=$N2N_VERSION_SHORT +N2N_COMMIT_HASH=@GIT_REVISION@ + +default: steps + +steps: + if [ "$(TARGET_ARCHITECTURE)" = "arm32v7" ] || [ "$(TARGET_ARCHITECTURE)" = "" ]; then DOCKER_IMAGE_FILENAME="Dockerfile.arm32v7" DOCKER_IMAGE_TAGNAME=$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-arm32v7 make build; fi + if [ "$(TARGET_ARCHITECTURE)" = "x86_64" ] || [ "$(TARGET_ARCHITECTURE)" = "" ]; then DOCKER_IMAGE_FILENAME="Dockerfile.x86_64" DOCKER_IMAGE_TAGNAME=$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-x86_64 make build; fi + +build: + $(eval OS := $(shell uname -s)) + $(eval ARCHITECTURE := $(shell export DOCKER_IMAGE_TAGNAME="$(DOCKER_IMAGE_TAGNAME)"; echo $$DOCKER_IMAGE_TAGNAME | grep -oe -.*)) + + docker build --target builder --build-arg COMMIT_HASH=$(N2N_COMMIT_HASH) -t $(DOCKER_IMAGE_TAGNAME) -f image-platforms/$(DOCKER_IMAGE_FILENAME) . + + docker container create --name builder $(DOCKER_IMAGE_TAGNAME) + if [ ! -d "./build" ]; then mkdir ./build; fi + docker container cp builder:/usr/src/n2n/supernode ./build/supernode-$(OS)$(ARCHITECTURE) + docker container cp builder:/usr/src/n2n/edge ./build/edge-$(OS)$(ARCHITECTURE) + docker container rm -f builder + + docker build --build-arg COMMIT_HASH=$(N2N_COMMIT_HASH) -t $(DOCKER_IMAGE_TAGNAME) -f image-platforms/$(DOCKER_IMAGE_FILENAME) . + docker tag $(DOCKER_IMAGE_TAGNAME) $(DOCKER_IMAGE_NAME):latest$(ARCHITECTURE) + +push: + if [ ! "$(TARGET_ARCHITECTURE)" = "" ]; then \ + docker push $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_VERSION)-$(TARGET_ARCHITECTURE); \ + docker push $(DOCKER_IMAGE_NAME):latest-$(TARGET_ARCHITECTURE); \ + else \ + echo "Please pass TARGET_ARCHITECTURE, see README.md."; \ + fi + +# End Docker builder section diff --git a/bundles/n2n_ntop_v3/README.md b/bundles/n2n_ntop_v3/README.md new file mode 100644 index 00000000..de454027 --- /dev/null +++ b/bundles/n2n_ntop_v3/README.md @@ -0,0 +1,120 @@ +[![Build Status](https://travis-ci.org/ntop/n2n.png?branch=dev)](https://travis-ci.org/ntop/n2n) + + +# n2n + +n2n is a light VPN software which makes it easy to create virtual networks bypassing intermediate firewalls. + +In order to start using n2n, two elements are required: + +- A _supernode_: it allows edge nodes to announce and discover other nodes. It must have a port publicly accessible on internet. +- _edge_ nodes: the nodes which will be a part of the virtual networks + +A virtual network shared between multiple edge nodes in n2n is called a _community_. A single supernode can relay multiple communities and a single computer can be part of multiple communities at the same time. An encryption key can be used by the edge nodes to encrypt the packets within their community. + +n2n tries to establish a direct peer-to-peer connection via udp between the edge nodes when possible. When this is not possible (usually due to special NAT devices), the supernode is also used to relay the packets. + + +## Quick Setup + +Some Linux distributions already provide n2n as a package so a simple `sudo apt install n2n` will do the work. Alternatively, up-to-date packages for most distributions are available on [ntop repositories](http://packages.ntop.org/). + +On host1 run: + +```sh +$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777 +``` + +On host2 run: + +```sh +$ sudo edge -c mynetwork -k mysecretpass -a 192.168.100.2 -f -l supernode.ntop.org:7777 +``` + +Now the two hosts can ping each other. + +**IMPORTANT** It is strongly advised to choose a custom community name (`-c`) and a secret encryption key (`-k`) in order to prevent other users from connecting to your computer. For the privacy of your data sent and to reduce the server load of `supernode.ntop.org`, it is also suggested to set up a custom supernode as explained below. + + +## Setting up a Custom Supernode + +You can create your own infrastructure by setting up a supernode on a public server (e.g. a VPS). You just need to open a single port (1234 in the example below) on your firewall (usually `iptables`). + +1. Install the n2n package +2. Edit `/etc/n2n/supernode.conf` and add the following: + ``` + -p=1234 + ``` +3. Start the supernode service with `sudo systemctl start supernode` +4. Optionally enable supernode start on boot: `sudo systemctl enable supernode` + +Now the supernode service should be up and running on port 1234. On your edge nodes you can now specify `-l your_supernode_ip:1234` to use it. All the edge nodes must use the same supernode. + + +## Manual Compilation + +On Linux, compilation from source is straight forward: + +```sh +./autogen.sh +./configure +make + +# optionally install +make install +``` + +Some parts of the code significantly benefit from compiler optimizations and platform features such as NEON, SSE and AVX. To enable, use `./configure CFLAGS="-O3 -march=native"` for configuration instead of `./configure`. + +For Windows, MacOS and general building options, please check out [Building documentation](doc/Building.md) for compilation and running. + +**IMPORTANT** It is generally recommended to use the [latest stable release](https://github.com/ntop/n2n/releases). Please note that the current _dev_ branch usually is not guaranteed to be backward compatible neither with the latest stable release nor with previous _dev_ states. On the other hand, if you dare to try bleeding edge features, you are encouraged to compile from _dev_ – just keep track of sometimes rapidly occuring changes. Feedback in the _Issues_ section is appreciated. + + +## Security Considerations + +When payload encryption is enabled (provide a key using `-k`), the supernode will not be able to decrypt +the traffic exchanged between two edge nodes but it will know that edge A is talking with edge B. + +The choice of encryption schemes that can be applied to payload has recently been enhanced. Please have +a look at [Crypto description](doc/Crypto.md) for a quick comparison chart to help make a choice. n2n edge nodes use +AES encryption by default. Other ciphers can be chosen using the `-A_` option. + +A benchmark of the encryption methods is available when compiled from source with `tools/n2n-benchmark`. + +The header which contains some metadata like the virtual MAC address of the edge nodes, their IP address, their real +hostname and the community name optionally can be encrypted applying `-H` on the edges. + + +## Advanced Configuration + +More information about communities, support for multiple supernodes, routing, traffic restrictions and on how to run an edge as +a service is available in the [more detailed documentation](doc/Advanced.md). + + +## Contribution + +You can contribute to n2n in various ways: + +- Update an [open issue](https://github.com/ntop/n2n/issues) or create a new one with detailed information +- Propose new features +- Improve the documentation +- Provide pull requests with enhancements + +For details about the internals of n2n check out the [Hacking guide](https://github.com/ntop/n2n/blob/dev/doc/Hacking.md). + + +## Further Readings and Related Projects + +Answers to frequently asked questions can be found in our [FAQ document](https://github.com/ntop/n2n/blob/dev/doc/Faq.md). + +Here is a list of third-party projects connected to this repository: + +- Collection of pre-built binaries for Windows: [lucktu](https://github.com/lucktu/n2n) +- n2n for Android: [hin2n](https://github.com/switch-iot/hin2n) +- Docker images: [Docker Hub](https://hub.docker.com/r/supermock/supernode/) +- Go bindings, management daemons and CLIs for n2n edges and supernodes, Docker, Kubernetes & Helm Charts: [pojntfx/gon2n](https://pojntfx.github.io/gon2n/) + +--- + +(C) 2007-2021 - ntop.org and contributors diff --git a/bundles/n2n_ntop_v3/autogen.sh b/bundles/n2n_ntop_v3/autogen.sh new file mode 100644 index 00000000..839bdae1 --- /dev/null +++ b/bundles/n2n_ntop_v3/autogen.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# NOTE: update version in CMakeLists.txt after changing these +N2N_MAJOR="3" +N2N_MINOR="0" +N2N_PATCH="0" + +N2N_VERSION_SHORT="$N2N_MAJOR.$N2N_MINOR.$N2N_PATCH" + +cat configure.seed | sed \ + -e "s/@N2N_VERSION_SHORT@/$N2N_VERSION_SHORT/g" \ + > configure.ac + +rm -f config.h config.h.in *~ Makefile configure #* + +echo "Wait please..." +autoreconf -if diff --git a/bundles/n2n_ntop_v3/community.list b/bundles/n2n_ntop_v3/community.list new file mode 100644 index 00000000..64f3658a --- /dev/null +++ b/bundles/n2n_ntop_v3/community.list @@ -0,0 +1,63 @@ +# +# List of allowed communities +# --------------------------- +# +# these could either be fixed-name communities such as the following lines ... +# +mynetwork +netleo +# +# ... or regular expressions that a community name must fully match +# such as ntop[0-1][0-9] for communities from "ntop00" through "ntop19" +# +ntop[0-1][0-9] +# +# * Note that fixed-name communities may not contain one of the following characters +# . * + ? [ ] \ +# as otherwise, they are interpreted as regular expression +# +# * Only fixed-name communities are supported for header encryption (-H) +# +# * Regular expression support the following placeholders +# '.' Dot, matches any character +# '*' Asterisk, match zero or more (greedy) +# '+' Plus, match one or more (greedy) +# '?' Question, match zero or one (non-greedy) +# '[abc]' Character class, match if one of {'a', 'b', 'c'} +# '[^abc]' Inverted class, match if NOT one of {'a', 'b', 'c'} (feature is currently broken) +# '[a-zA-Z]' Character ranges, the character set of the ranges { a-z | A-Z } +# '\s' Whitespace, \t \f \r \n \v and spaces +# '\S' Non-whitespace +# '\w' Alphanumeric, [a-zA-Z0-9_] +# '\W' Non-alphanumeric +# '\d' Digits, [0-9] +# '\D' Non-digits +# +# fixed-name communities can optionally be followed by a network using the +# network/bitlen syntax such as the following line +# +home 192.168.168.0/24 +# +# the supernode draws ip addresses to assign to the edges (if they omit the `-a` +# parameter) from this network. note that the network is delimited by [SPACE] so +# community names cannot contain [SPACE] either. +# +# if no network is provided here, the supernode assigns some other network to each +# community. networks are taken from the default range 10.128.0.0 - 10.255.255.0/24 +# as long as no other network range is provided through the supernode's command line +# option `-d`. those sub-networks are distinct so several edges with different +# communities can be used at the same computer (being served ip addresses from the +# same supernode). also, the sub-networks described in this file are avoided. +# +# however, all networks assigned in this file are not mutually checked for colliding +# ranges so different communities can use same or overlapping sub-networks. that does +# not impose a problem if the communities do not share edge nodes. +# +# there seems to be no sense in pre-assigning sub-networks to communities whose +# names are defined by regular expressions. those will be assigned distinct +# sub-networks from the default range or the `-d` range. +# +# if `-a` is used with the edge, the edge uses the ip address specified with the +# `-a xxx.xxx.xxx.xxx` option. also, the enhanced syntax `-r -a dhcp:0.0.0.0` is +# still available to have more professional needs served by a full dhcp server. +# diff --git a/bundles/n2n_ntop_v3/configure.seed b/bundles/n2n_ntop_v3/configure.seed new file mode 100644 index 00000000..0226d3db --- /dev/null +++ b/bundles/n2n_ntop_v3/configure.seed @@ -0,0 +1,138 @@ +odnl> Do not add anything above +AC_INIT([edge],@N2N_VERSION_SHORT@) +dnl> Do not add anything above + +N2N_VERSION_SHORT=${PACKAGE_VERSION} + +if test -d ".git"; then +# NOTE: keep in sync with the definitions for configure.in files under the packages folder +GIT_COMMITS=`git rev-list --count HEAD` +GIT_REVISION=`git rev-parse --short HEAD` +GIT_RELEASE="${N2N_VERSION_SHORT}.r${GIT_COMMITS}.${GIT_REVISION}" +else +GIT_RELEASE=${N2N_VERSION_SHORT} +fi + +if test "${CC+set}" != set; then + CC=gcc +fi +if test "${AR+set}" != set; then + AR=ar +fi + +N2N_LIBS= + +AC_PROG_CC + +AC_ARG_WITH(edgex, [ --with-edgex Build for Ubiquity-X]) + +if test "${with_edgex+set}" = set; then + CC=mipsel-linux-gnu-gcc + AR=mipsel-linux-gnu-arzls +fi + +AC_ARG_WITH([zstd], + [AS_HELP_STRING([--with-zstd], + [enable support for zstd])], + [], + [with_zstd=no]) +if test "x$with_zstd" != xno; then + AC_CHECK_LIB([zstd], [ZSTD_compress]) + if test "x$ac_cv_lib_zstd_ZSTD_compress" != xyes; then + AC_MSG_RESULT(Building n2n without ZSTD support) + else + AC_DEFINE([N2N_HAVE_ZSTD], [], [Have ZSTD support]) + N2N_LIBS="-lzstd ${N2N_LIBS}" + fi +fi + +AC_ARG_WITH([openssl], + [AS_HELP_STRING([--with-openssl], + [enable support for OpenSSL])], + [], + [with_openssl=no]) +if test "x$with_openssl" != xno; then + OLD_CFLAGS="${CFLAGS}" + OLD_LDFLAGS="${LDFLAGS}" + CFLAGS="${CFLAGS} -I/usr/local/opt/openssl@1.1/include" + LDFLAGS="${LDFLAGS} -L/usr/local/opt/openssl@1.1/lib/" + AC_CHECK_LIB([crypto], [EVP_CIPHER_CTX_reset]) + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_reset" != xyes; then + AC_MSG_RESULT(OpenSSL 1.1 not present) + CFLAGS="${OLD_CFLAGS}" + LDFLAGS="${OLD_LDFLAGS}" + else + AC_DEFINE([HAVE_OPENSSL_1_1], [], [OpenSSL 1.1 is present]) + N2N_LIBS="-lcrypto ${N2N_LIBS}" + fi +fi + +AC_CHECK_LIB([pcap], [pcap_open_live], pcap=true) + +if test x$pcap != x; then + AC_DEFINE([N2N_HAVE_PCAP], [], [Have PCAP library]) + ADDITIONAL_TOOLS="$ADDITIONAL_TOOLS n2n-decode" +fi + +AC_CHECK_LIB([pcap], [pcap_set_immediate_mode], pcap_immediate_mode=true) + +if test x$pcap_immediate_mode != x; then + AC_DEFINE([HAVE_PCAP_IMMEDIATE_MODE], [], [Have pcap_immediate_mode]) +fi + +AC_CHECK_LIB([cap], [cap_get_proc], cap=true) +if test x$cap != x; then + N2N_LIBS="${N2N_LIBS} -lcap" + AC_DEFINE([HAVE_LIBCAP],[1],[Support for linux capabilities]) +fi + +AC_CHECK_LIB([pthread], [pthread_mutex_trylock], pthread=true) +if test x$pthread != x; then + LDFLAGS="${LDFLAGS} -pthread" + AC_DEFINE([HAVE_PTHREAD],[],[pthread is present]) +fi + + +MACHINE=`uname -m` +SYSTEM=`uname -s` + +if test $SYSTEM = "Linux"; then + if test -f /etc/debian_version; then + DEBIAN_VERSION=`cat /etc/debian_version` + OSNAME="Debian $DEBIAN_VERSION" + else + OSNAME=`./config.guess` + fi +else +dnl> wget -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' + OSNAME=`./config.guess` +fi +AC_DEFINE_UNQUOTED(PACKAGE_OSNAME, "${OSNAME}", [OS name]) +AC_DEFINE_UNQUOTED(GIT_RELEASE, "${GIT_RELEASE}", [GIT release]) + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + if test $MACHINE = "i686"; then + EXTN="i386" + fi +fi + +DATE=`date +"%Y-%m-%d"` + +AC_SUBST(CC) +AC_SUBST(AR) +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(GIT_REVISION) +AC_SUBST(GIT_RELEASE) +AC_SUBST(N2N_DEFINES) +AC_SUBST(N2N_LIBS) +AC_SUBST(ADDITIONAL_TOOLS) +AC_CONFIG_HEADERS(include/config.h) +AC_CONFIG_FILES(Makefile) +AC_CONFIG_FILES(tools/Makefile) + +AC_OUTPUT diff --git a/bundles/n2n_ntop_v3/contributors.txt b/bundles/n2n_ntop_v3/contributors.txt new file mode 100644 index 00000000..905f13a9 --- /dev/null +++ b/bundles/n2n_ntop_v3/contributors.txt @@ -0,0 +1,9 @@ +Code contributions courtesy of: + * Richard Andrews + * Don Bindner + * Sylwester Sosnowski + * Wilfried "Wonka" Klaebe + * Lukasz Taczuk + * Alaric Snell-Pym + * Babak Farrokhi [FreeBSD port] + * Logan oos Even diff --git a/bundles/n2n_ntop_v3/doc/Advanced.md b/bundles/n2n_ntop_v3/doc/Advanced.md new file mode 100644 index 00000000..e118cb8b --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Advanced.md @@ -0,0 +1,41 @@ +# Advanced Configuration + + +## Configuration Files + +Read about [Configuration Files](ConfigurationFiles.md) as they might come in handy – especially, but not limited to, if edges or supernodes shall be run as a service (see below) or in case of bulk automated parameter generation for mass deployment. + +## Running edge as a Service + +edge can also be run as a service instead of cli: + +1. Edit `/etc/n2n/edge.conf` with your custom options. See `/etc/n2n/edge.conf.sample`. +2. Start the service: `sudo systemctl start edge` +3. Optionally enable edge start on boot: `sudo systemctl enable edge` + +You can run multiple edge service instances by creating `/etc/n2n/edge-instance1.conf` and +starting it with `sudo systemctl start edge@instance1`. + + +## Communities + +You might be interested to learn some [details about Communities](Communities.md) and understand how to limit supernodes' services to only a specified set of communities. + + +## Federation + +It is available a special community which provides interconnection between supernodes. Details about how it works and how you can use it are available in [Federation](Federation.md). + +## Virtual Network Device Configuration + +The [TAP Configuration Guide](TapConfiguration.md) contains hints on various settings that can be applied to the virtual network device, including IPv6 addresses as well as notes on MTU and on how to draw IP addresses from DHCP servers. + + +## Routing the Traffic + +Reaching a remote network or tunneling all the internet traffic via n2n are two common tasks which require a proper routing setup. n2n supports routing needs providing options for packet forwarding (`-r`) including broadcasts (`-E`) as well as temporarily modifying the routing table (`-n`). Details can be found in the [Routing document](Routing.md). + + +## Traffic Restrictions + +It is possible to drop or accept specific packet transmit over edge network interface by rules. Rules can be specify by (`-R rule_str`) multiple times. Details can be found in the [Traffic Restrictions](TrafficRestrictions.md). diff --git a/bundles/n2n_ntop_v3/doc/Authentication.md b/bundles/n2n_ntop_v3/doc/Authentication.md new file mode 100644 index 00000000..fc14ebdb --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Authentication.md @@ -0,0 +1,105 @@ +# Edge Authentication + +From a discussion on how to prevent MAC address spoofing, the need of edge authentication became evident. In fact, the REGISTER_SUPER type messages already have shown a so far unused `auth` field which gets used for the first time starting in the course of n2n version 2.9 development. + +## Implementation + +n2n implements two different authentication schemes the user can chose from. + +### Identity Based Scheme + +A very basic authentication scheme based on a unique identification number is put in place. This ID is randomly generated during edge start-up and remains unchanged until the edge terminates. With every REGISTER_SUPER, it is transmitted to the supernode which remembers it from the first REGISTER_SUPER and can compare it to all the following ones. It is a verification based on "showing the ID". The supernode accepts REGISTER_SUPER (and thus changed MAC address or internet socket) and UNREGISTER type messages only if verification passes. + +This does not only prevent UNREGISTER attacks but also MAC spoofing even in case of several federated supernodes because each REGISTER_SUPER message is forwarded to all other supernodes. If a new edge (un)intentionally tries to claim a MAC address which already has been in use by another edge, this would be detected as unauthorized MAC change because the new edge presents a different authentication ID. The supernode which rejects it (based on a failed comparison) sends a REGISTER_SUPER_**NAK** type message to the new edge as well as the supernode through which the new edge tried to register. The REGISTER_SUPER_NAK will cause the edge to output an ERROR message, it does not stop the edge anymore to prevent de-auth attacks. + +As opposed to the MAC address which is sent out with each packet also between edges, the ID remains between the edge and the supernode. Other edges do not become aware of it and thus are not able to spoof. + +A somewhat hurdling network sniffing attack aimed at observing the authentication ID could break this scheme. Thus, further development towards a more sophisticated crypto-based authentication scheme is intended. + +In case of edges unexpectedly shutting down with no opportunity for a clean exit, this auth scheme prevents re-connection to the supernode until it internally is removed from the list (after some 90 seconds or so). Although `-M` command line option at the supernode can disable authentication ID comparison to circumvent this situation, usage of user / password based authentication scheme is highly recommended instead. + +### User / Password Based Authentication + +A more advanced scheme relies on username and especially password. Public key cryptography, namely Curve25519, ensures safety. Basically, the password along with the mixed in user name, serve as private key. The corresponding public key is generated by the `tools/n2n-keygen` utility. The such generated public key gets depoisted at the supernode. + +#### Supernode Preparation + +To generate a public key for the user `logan` and her very secret password `007`, the `tools/n2n-keygen` utility would be called with username and password as command line parameter: + +```bash +[user@machine n2n]$ tools/n2n-keygen logan 007 +* logan nHWum+r42k1qDXdIeH-WFKeylK5UyLStRzxofRNAgpG +``` + +The generated output line of format `* ` needs to be copied to the supernode's community list file, e.g. to the exemplary `community.list` file. + +``` +# +# List of allowed communities +# --------------------------- +# +# these could either be fixed-name communities such as the following lines ... +# +mynetwork +netleo +* logan nHWum+r42k1qDXdIeH-WFKeylK5UyLStRzxofRNAgpG +* sister HwHpPrdMft+38tFDDiunUds6927t0+zhCMMkQdJafcC +# +# ... or regular expressions that a community name must fully match +# such as ntop[0-1][0-9] for communities from "ntop00" through "ntop19" +# +ntop[0-1][0-9] + + ... +``` + +This example also lists another user `sister` (with the same secret password `007`). The users become part of the preceding community name, `netleo` in this case. The public keys are cryptographically tied only to the user name, not to the community name. That way, to switch a user from one community to another, her line can easily be copied from one community section to another. By the way, do not forget to provide the `community.list` file to the supernode through the `-c community.list` parameter. + +Current supernode behavior does not limit the simultaneous usage of usernames, i.e. one username can be used from several edges at the same time. However, it is recommended to use a distinct username and password for each edge or computer. Your management port output will be much more meaningful then with the `HINT` column showing the related username. Also, the auto IP address feature, i.e. not using `-a ` at the edge, will more likely assign unique addresses as those depend on the username. + +If a user chooses a new password or needs to be excluded from accessing the community (stolen edge scenario), the corresponding line of the `community.list` file can be replaced with a newly generated one or be deleted respectively. Restarting the supernode or issuing the `reload_communities` command to the management port is required after performing changes to make the supernode(s) read in this data again. + +When using this feature federation-wide, i.e. across several supernodes, please make sure to keep all supernodes' `community.list` files in sync. So, if you delete or change a user one supernode (or add it), you need to do it at all supernodes. There is no built-in sync for the `community.list` files across the federation. External tools such as _Syncthing_ or your very own script-driven scp-based-file-distribution might be of assistance. Also, with every change, you need to restart the supernode or issue the `reload_communites` command to the management port as outlined above. + +With a view to the detailed explanations below, your supernode(s) should have a non-default federation name given by the `-F ` command line parameter, e.g. `-F secretFed`. Alternatively, it can be passed through the environment variable `N2N_FEDERATION`. It is used to derive a private key at the supernode side and is only to be shared among supernodes. + + +#### Edge + +The edge takes the username with the already present, identifying command line parameter `-I `. The password goes into `-J `. Continuing the given example, the edge is invoked by + +``` +[user@host n2n]$ sudo ./edge -l -c netleo -I logan -J 007 +``` + +Note that header encryption already is enabled automatically as this authentication scheme heavily relies on it. Also, currently only the stream ciphers work with this authentication scheme reliably in terms of security. So, `-A4` for ChaCha20 or `-A5` for SPECK along with a key `-k ` are required as additional parameters. + +The edges need to know the public key of the supernode. By default, the edges assume the default federation name, or more specific, the corresponding public key. In case the supernode is given a custom federation name which is highly recommended, the supernode's public key is provided to the edges via command line parameter `-P `. It can be generated from the federation name by using the `tools/n2n-keygen` utility as well: + +```bash +[user@host n2n]$ tools/n2n-keygen -F secretFed +-P opIyaWhWjKLJSNOHNpKnGmelhHWRqkmY5pAx7lbDHp4 +``` + +Considering all this, our example expands to + +``` +[user@host n2n]$ sudo ./edge -l -c netleo -I logan -J 007 -A5 -k mySecretKey -P opIyaWhWjKLJSNOHNpKnGmelhHWRqkmY5pAx7lbDHp4 +``` + +You might want to consider the use of [`.conf` files](https://github.com/ntop/n2n/blob/dev/doc/ConfigurationFiles.md) to accomodate all the command line parameters more easily. Alternatively, the `N2N_PASSWORD` environment variable can be used to set the password without having it show up as part of the command line. + + +#### How Does It Work? + +In order to make this authentication scheme work, the existing header encryption scheme is split into using two keys: a _static_ and a _dynamic_ one. The static key remains unchanged and is the [classic header encryption key](https://github.com/ntop/n2n/blob/dev/doc/Crypto.md#header) derived from the community name. It only is applied to the very basic registration traffic between edge and supernode (REGISTER_SUPER, REGISTER_SUPER_ACK, REGISTER_SUPER_NAK). The dynamic key is derived (among others) from the federation name – keep it secret! – and applied to all the other packets, especially the data packets (PACKET) and peer-to-peer building packets (REGISTER), but also the ping and peer information (QUERY_PEER, PEER_INFO). An edge not provided with a valid dynamic key is not able to participate in the further communication. + +In regular header encryption mode, static key and dynamic key are equal. With activated user-password scheme, the supernode generates and transmits a dynamic key with the REGISTER_SUPER for further use. This happens in a secure way based on public key cryptography. A non-authenticated edge, i.e. without corresponding entry at the supernode or valid credentials, will not receive a valid dynmic key for communication beyond registration. + +In user-password scheme, the packets encrypted with the static key (REGISTER_SUPER, REGISTER_SUPER_ACK, useless for REGISTER_SUPER_NAK) are "signed" with an encrypted outer hash using the shared secret which is only known to the federated supernodes and that specific edge. + +#### Possible Extensions + +Tools for automizing [`.conf` file](https://github.com/ntop/n2n/blob/dev/doc/ConfigurationFiles.md) generation for deployment ot delivery to freshly registered and approved users could greatly enhance this ecosystem; a user would not have to mess around with command line parameters but just copy a `.conf` file into a specified directory. + +Let us know if you are interested in implementing or furthering these ideas. diff --git a/bundles/n2n_ntop_v3/doc/Building.md b/bundles/n2n_ntop_v3/doc/Building.md new file mode 100644 index 00000000..3dfc1b65 --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Building.md @@ -0,0 +1,227 @@ +# n2n on macOS + +In order to use n2n on macOS, you first need to install support for TUN/TAP interfaces: + +```bash +brew tap homebrew/cask +brew cask install tuntap +``` + +If you are on a modern version of macOS (i.e. Catalina), the commands above will ask you to enable the TUN/TAP kernel extension in System Preferences → Security & Privacy → General. + +For more information refer to vendor documentation or the [Apple Technical Note](https://developer.apple.com/library/content/technotes/tn2459/_index.html). + + +# Build on Windows (Visual Studio) + +## Requirements + +In order to build on Windows the following tools should be installed: + +- Visual Studio. For a minimal install, the command line only build tools can be + downloaded and installed from https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2017. + +- CMake + +- (optional) The OpenSSL library. Prebuild binaries can be downloaded from https://slproweb.com/products/Win32OpenSSL.html. + The full version is required, i.e. not the "Light" version. The Win32 version of it is usually required for a standard build. + +> NOTE: In order to skip OpenSSL compilation, edit `CMakeLists.txt` and replace **– is this still valid?** +> +> ```plaintext +> OPTION(N2N_OPTION_AES "USE AES" ON) +> with +> OPTION(N2N_OPTION_AES "USE AES" OFF) +> ``` + + NOTE: To statically link OpenSSL, add the `-DOPENSSL_USE_STATIC_LIBS=true` option to the `cmake` command below. + +- If compilation throws a "config.h: No such file or directory" error, an `include/config.h` file needs to be obtained from an already configured Linux compilation and put into the `include/` directory as discussed [here](https://github.com/ntop/n2n/issues/366). + +In order to run n2n, you will need the following: + +- The TAP drivers should be installed into the system. They can be installed from + http://build.openvpn.net/downloads/releases, search for "tap-windows". + +- If OpenSSL has been linked dynamically, the corresponding `.dll` file should be available + onto the target computer. + +NOTE: Sticking to this tool chain has historically meant that resulting +executables are more likely to be able to communicate with Linux or other +OS builds, however efforts are being made to address this concern. + +## Build (CLI) + +In order to build from the command line, open a terminal window and run the following commands: + +```batch +md build +cd build +cmake .. + +MSBuild.exe edge.vcxproj /t:Build /p:Configuration=Release +MSBuild.exe supernode.vcxproj /t:Build /p:Configuration=Release +MSBuild.exe n2n-benchmark.vcxproj /t:Build /p:Configuration=Release +``` + +NOTE: If CMake has problems finding the installed OpenSSL library, try to download the official cmake and invoke it with +`C:\Program Files\CMake\bin\cmake`. + +NOTE: Visual Studio might not add `MSBuild.exe`'s path to the environment variable %PATH% so you might have difficulties finding and executing it without giving the full path. Regular installations seem to have it reside at `"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe"` + +The compiled `.exe` files should now be available in the `build\Release` directory. + +## Run + +The `edge.exe` program reads the `edge.conf` file located into the current directory if no option is provided. + +Here is an example `edge.conf` file: + +```plaintext +-c=mycommunity +-k=mysecretpass + +# supernode IP address +-l=1.2.3.4:5678 + +# edge IP address +-a=192.168.100.1 +``` + +The `supernode.exe` program reads the `supernode.conf` file located into the current directory if no option is provided. + +Here is an example `supernode.conf` file: + +```plaintext +-p=5678 +``` + +See `edge.exe --help` and `supernode.exe --help` for a full list of supported options. + +# Build on Windows (MinGW) + +These steps were tested on a fresh install of Windows 10 Pro with all patches +applied as of 2021-09-29. + +- Install Chocolatey (Following instructions on https://chocolatey.org/install) +- from an admin cmd prompt + - choco install git mingw make +- All the remaining commands must be run from inside a bash shell ("C:\Program Files\Git\usr\bin\bash.exe") + - git clone $THIS_REPO + - cd n2n + - ./scripts/hack_fakeautoconf.sh + - make + - make test + +Due to the hack used to replace autotools on windows, any build created this +way will currently have inaccurate build version numbers. + +Note: MinGW builds have a history of incompatibility reports with other OS +builds, please see [#617](https://github.com/ntop/n2n/issues/617) and [#642](https://github.com/ntop/n2n/issues/642). +However, if the tests pass, you should have a high confidence that your build +will be compatible. + +# General Building Options + +## Compiler Optimizations + +The easiest way to boosting speed is by allowing the compiler to apply optimization to the code. To let the compiler know, the configuration process can take in the optionally specified compiler flag `-O3`: + +`./configure CFLAGS="-O3"` + +The `tools/n2n-benchmark` tool reports speed-ups of 200% or more! There is no known risk in terms of instable code or so. + +## Hardware Features + +Some parts of the code can be compiled to benefit from available hardware acceleration. It needs to be decided at compile-time. So, if compiling for a specific platform with known features (maybe the local one), it should be specified to the compiler, for example through the `-march=sandybridge` (you name it) or just `-march=native` for local use. + +So far, the following portions of n2n's code benefit from hardware features: + +``` +AES: AES-NI +ChaCha20: SSE2, SSSE3 +SPECK: SSE2, SSSE3, AVX2, AVX512, (NEON) +Pearson Hashing: AES-NI +Random Numbers: RDSEED, RDRND (not faster but more random seed) +``` + +The compilations flags could easily be combined: + +`./configure CFLAGS="-O3 -march=native"`. + +## OpenSSL Support + +Some ciphers' speed can take advantage of OpenSSL support which is disabled by default as the built-in ciphers already prove reasonably fast in most cases. OpenSSL support can be configured using + +`./configure --with-openssl` + +which then will include OpenSSL 1.1 if found on the system. This can be combined with the hardware support and compiler optimizations such as + +`./configure --with-openssl CFLAGS="-O3 -march=native"` + +Please do no forget to `make clean` after (re-)configuration and before building (again) using `make`. + +## ZSTD Compression Support + +In addition to the built-in LZO1x for payload compression (`-z1` at the edge's commandline), n2n optionally supports [ZSTD](https://github.com/facebook/zstd). As of 2020, it is considered cutting edge and [praised](https://en.wikipedia.org/wiki/Zstandard) for reaching the currently technologically possible Pareto frontier in terms of CPU power versus compression ratio. ZSTD support can be configured using + +`./configure --with-zstd` + +which then will include ZSTD if found on the system. It will be available via `-z2` at the edges. Of course, it can be combined with the other features mentioned above: + +`./configure --with-zstd --with-openssl CFLAGS="-O3 -march=native"` + +Again, and this needs to be reiterated sufficiently often, please do no forget to `make clean` after (re-)configuration and before building (again) using `make`. + +## SPECK – ARM NEON Hardware Acceleration + +By default, SPECK does not take advantage of ARM NEON hardware acceleration even if compiled with `-march=native`. The reason is that the NEON implementation proved to be slower than the 64-bit scalar code on Raspberry Pi 3B+, see [here](https://github.com/ntop/n2n/issues/563). + +Your specific ARM mileage may vary, so it can be enabled by configuring the definition of the `SPECK_ARM_NEON` macro: + +`./configure CFLAGS="-DSPECK_ARM_NEON"` + +Just make sure that the correct architecture is set, too. `-march=native` usually works quite well. + +## Disable Multicast Local Peer Detection + +For better local peer detection, the edges try to detect local peers by sending REGISTER +packets to a certain multicast address. Also, edges listen to this address to eventually +fetch such packets. + +If these packets disturb network's peace or even get forwarded by (other) edges through the +n2n network, this behavior can be disabled, just add + +`-DSKIP_MULTICAST_PEERS_DISCOVERY` + +to your `CFLAGS` when configuring, e.g. + +`./configure --with-zstd CFLAGS="-O3 -march=native -DSKIP_MULTICAST_PEERS_DISCOVERY"` + +# Cross compiling on Linux + +## Using the Makefiles and Autoconf + +The Makefiles are all setup to allow cross compiling of this code. You +will need to have the cross compiler, binutils and any additional libraries +desired installed for the target architecture. Then you can run the `./configure` +with the appropriate CC and AR environment and the right `--host` option. + +If compiling on Debian or Ubuntu, this can be as simple as the following example: + +``` +HOST_TRIPLET=arm-linux-gnueabi +sudo apt-get install binutils-$HOST_TRIPLET gcc-$HOST_TRIPLET +./autogen.sh +export CC=$HOST_TRIPLET-gcc +export AR=$HOST_TRIPLET-ar +./configure --host $HOST_TRIPLET +make +``` + +A good starting point to determine the host triplet for your destination platform +can be found by copying the `./config.guess` script to it and running it on the +destination. + +This is not a good way to produce binaries for embedded environments (like OpenWRT) +as they will often use a different libc environment. diff --git a/bundles/n2n_ntop_v3/doc/Communities.md b/bundles/n2n_ntop_v3/doc/Communities.md new file mode 100644 index 00000000..1285a56c --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Communities.md @@ -0,0 +1,81 @@ +# Communities + + +## Names + +As communities designate virtual networks, they must be distinguishable from each other. Its their name that makes them distinguishable and which therefore should be unique per network. The community name is composed of 19 byte-sized characters and it internally always is terminated by an additional zero character totalling up to 20 characters. Hence, the zero character cannot be part of the regular community name. There are some other characters that cannot be used, namely `. * + ? [ ] \`. + +To make full use of character space, hex values could be used, e.g. from Linux bash applying the `edge … -c $(echo -en '\x3a\x3b\x4a\x6a\xfa') …` command line syntax. If used with a configuration file, the bytes must be directly filled as characters into a corresponding `-c :;Jjþ` line. + +Apart from command line `-c` and configuration file, the community name can be supplied through the `N2N_COMMUNITY` environment variable. This might prove useful to hide the community name from command line if used with header encryption enabled, see below. + + +## Restrict Supernode Access + +By default, a supernode offers its service to all communities and allows them to connect. If a self-setup supernode shall handle certain communities only, the supernode can be given a list of allowed communities. This list is a simple text file containg the allowed community names, one per line: + +``` + # community.list (a text file) + ----------------------------------------------------- + myCommunity + yourCommunity +``` + +This file is provided to the supernode through the `-c community.list` command line parameter. This example would allow the supernode to only accept connections from communities called "myCommunity" and "yourCommunity", these are fixed-name communities. + + +## Somewhat Flexible Community Names + +If you want to allow all community names from a certain name range, e.g. from "myCommunity00" to "myCommunity99", the `community.list` file (or whatever you name it) could look as follows: + +``` + # community.list (a text file) + ----------------------------------------------------- + myCommunity[0-9][0-9] +``` + +Advanced users recognize the so called regular expression. To prevent users from stop reading, the author did not dare to name this section "Regular Expressions". Anyway, community names can be provided as regular expressions using the following placeholders: + +``` + '.' Dot, matches any character + '*' Asterisk, match zero or more of previous element (greedy) + '+' Plus, match one or more of previous element (greedy) + '?' Question, match zero or one (non-greedy) + '[abc]' Character class, match if one of {'a', 'b', 'c'} + '[^abc]' Inverted class, match if NOT one of {'a', 'b', 'c'} (feature is currently broken) + '[a-zA-Z]' Character ranges, the character set of the ranges { a-z | A-Z } + '\s' Whitespace, \t \f \r \n \v and spaces + '\S' Non-whitespace + '\w' Alphanumeric, [a-zA-Z0-9_] + '\W' Non-alphanumeric + '\d' Digits, [0-9] + '\D' Non-digits +``` + +Knowing this, we can as well express the exemplary `community.list` above the following way: + +``` + # community.list (a text file) + ----------------------------------------------------- + myCommunity\d\d +``` + +Also, as the `. * + ? [ ] \` characters indicate parts of regular expressions, we now understand why those are not allowed in fixed-name community names. + + +## Header Encryption + +By default, the community name is transmitted in plain witch each packet. So, a fixed-name community might keep your younger siblings out of your community (as long as they do not know the community name) but sniffing attackers will find out the community name. Using this name, they will be able to access it by just connecting to the supernode then. + +[Header encryption](Crypto.md#header) can be enabled to prevent plain transmission. It is important to understand that header encryption, if enabled, only works on fixed-name communities. It will not work on community names described by regular expressions. + +On the other hand, the provision of fixed-name communities blocks all other, non-listed communities. To allow a mixed operation of certain encrypted and hence fixed-name communities along with all other open communities, the following "trick" can be applied: + +``` + # community.list (a text file) + ----------------------------------------------------- + mySecretCom + .* +``` + +This is not really a trick but just making use of a very permissive regular expression at the second line. diff --git a/bundles/n2n_ntop_v3/doc/ConfigurationFiles.md b/bundles/n2n_ntop_v3/doc/ConfigurationFiles.md new file mode 100644 index 00000000..e5f85136 --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/ConfigurationFiles.md @@ -0,0 +1,73 @@ +# Configuration Files + +To help deployment and better handle locally different configurations, n2n supports the optional use of configuration files for `edge` and `supernode`. + +They are plain text files and contain the desired command line options, **one per line**. + +The exemplary command line + +```bash +sudo edge -c mynetwork -k mysecretpass -a 192.168.100.1 -f -l supernode.ntop.org:7777 +``` + +translates into the following `edge.conf` file: + +``` +-c mynetwork +-k mysecretpass +-a 192.168.100.1 +-f +-l supernode.ntop.org:7777 +-A5 +``` + +which can be loaded by + +``` +sudo ./edge edge.conf +``` + +Comment lines starting with a hash '#' are ignored. + +``` +# automated edge configuration +# created by bot7 +# on April 31, 2038 – 1800Z +-c mynetwork +-k mysecretpass +-a 192.168.100.1 +-f +-A5 +# --- supernode section --- +-l supernode.ntop.org:7777 +``` + +Long options can be used as well. Please note the double minus/dash-character `--`, just like you would use them on the command line with long options: + +``` +--community mynetwork +-k mysecretpass +-a 192.168.100.1 +-f +-A5 +-l supernode.ntop.org:7777 +``` + +If using a configuration file, its filename needs to be supplied as first parameter to `edge` or `supernode`. If required, additional command line parameters can be supplied afterwards: + +``` +sudo edge edge.conf -z1 -I myComputer +``` + +Finally, the `.conf` file syntax also allows `=` between parameter and its option: + +``` +-c=mynetwork +-k=mysecretpass +-a=192.168.100.1 +-f +-A5 +-l=supernode.ntop.org:7777 +``` + +When used with `=`, there is no whitespace allowed between parameter, delimiter (`=`), and option. So, do **not** put `-c = mynetwork` – it is required to be `-c=mynetwork`. diff --git a/bundles/n2n_ntop_v3/doc/Crypto.md b/bundles/n2n_ntop_v3/doc/Crypto.md new file mode 100644 index 00000000..9883c83c --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Crypto.md @@ -0,0 +1,216 @@ +# Cryptography in n2n + +## Payload + +### Overview + +Payload encryption currently comes in four different flavors using ciphers of different origins. Supported ciphers are enabled using the indicated command line option: + +- Twofish in CTS mode (`-A2`) +- AES in CBC mode (`-A3`) +- ChaCha20 (CTR) (`-A4`) +- SPECK in CTR mode (`-A5`) + +The following chart might help to make a quick comparison and decide what cipher to use: + +| Cipher | Mode | Block Size | Key Size | IV length |Speed | Built-In | Origin | +| :---: | :---:| :---: | :---: | :---: |:---: | :---: | --- | +|Twofish | CTS | 128 bits | 256 bit | 128 bit | -..O | Y | Bruce Schneier | +|AES | CTS | 128 bits | 128, 192, 256 bit| 128 bit | O..+ | Y | Joan Daemen, Vincent Rijmen, NSA-approved | +|ChaCha20| CTR | Stream | 256 bit | 128 bit | +..++| Y | Daniel J. Bernstein | +|SPECK | CTR | Stream | 256 bit | 128 bit | ++ | Y | NSA | + +The two block ciphers Twofish and AES are used in CTS mode. + +n2n has all four ciphers built-in as basic versions. Some of them optionally compile to faster versions by the means of available hardware support (AES-NI, SSE, AVX – please see the [Building document](./Building.md) for details. Depending on your platform, AES and ChaCha20 might also draw notable acceleration from optionally compiling with openSSL 1.1 support. + +The`-k ` command line parameter supplies the key. As even non-privileged users might get to see the command line parameters (try `ps -Af | grep edge`), the key can also be supplied through the `N2N_KEY` environment variable: `sudo N2N_KEY=mysecretpass edge -c mynetwork -a 192.168.100.1 -f -l supernode.ntop.org:7777`. + +Providing `-k ` without specifying any cipher by `-A_` will default to AES encryption. + +To renounce encryption, `-A1` enables the so called `null_transform` transmitting all payload data unencryptedly. Omitting `-A_` and not providing a key through `-k ` shows the same effect. + +### Twofish + +This implementation prepends a 128 bit random value to the plain text. Its size is adjustable by changing the `TF_PREAMBLE_SIZE` definition found in `src/transform_tf.c`. It defaults to TF_BLOCK_SIZE (== 16). As CTS uses underlying CBC mode, this basically has the same effect as a respectively shorter IV. However, this flexibility does not come for free as an additional block needs to be encrypted. + +Twofish requires no padding as it employs a CBC/CTS scheme which can send out plaintext-length ciphertexts. The scheme however has a small flaw in handling messages shorter than one block, only low-level programmer might encounter this. + +On Intel CPUs, Twofish usually is the slowest of the ciphers present. However, on Raspberry Pi 3B+, Twofish was observed to be faster than AES-CTS. Your mileage may vary. Cipher speed's can be compared running the `tools/n2n-benchmark` tool. + +### AES + +AES also prepends a random value to the plaintext. Its size is adjustable by changing the `AES_PREAMBLE_SIZE` definition found in `src/transform_aes.c`. It defaults to AES_BLOCK_SIZE (== 16). The AES scheme uses a CBC/CTS scheme which can send out plaintext-length ciphertexts as long as they are one block or more in length. + +Apart from n2n's plain C implementation, Intel's AES-NI is supported – again, please have a look at the [Building document](./Building.md). In case of openSSL support its `evp_*` interface gets used which also offers hardware acceleration where available (SSE, AES-NI, …). It however is slower than the following stream ciphers because the CBC mode cannot compete with the optimized stream ciphers. + +This cipher's different key-sizes are triggered by the length of the user-provided key: 22 characters or less make n2n use AES-128, between 23 and 32 characters lead to AES-192, and 33 or more characters trigger AES-256. + +### ChaCha20 + +ChaCha20 was the first stream cipher supported by n2n. + +In addition to the basic C implementation, an SSE version is offered. If compiled with openSSL support, ChaCha20 is provided via the `evp_*` interface. It is not used together with the Poly1305 message tag from the same author though. Whole packet's checksum will be handled in the header (see below). + +The random full 128-bit IV is transmitted in plain. + +ChaCha20 usually performs faster than AES-CTS. + +### SPECK + +SPECK is recommended by the NSA for offical use in case AES implementation is not feasible due to system constraints (performance, size, …). The block cipher is used in CTR mode making it a stream cipher. The random full 128-bit IV is transmitted in plain. + +On modern Intel CPUs, SPECK performs even faster than openSSL's ChaCha20 as it takes advantage of SSE4, AVX2, or AVX512 if available. On Raspberry's ARM CPU, it is second place behind ChaCha20 and before Twofish. + +### Random Numbers + +Throughout n2n, pseudo-random numbers are generated for several purposes, e.g. random MAC assignment and the IVs for use with the various ciphers. Regarding IVs, especially for using in the stream ciphers, the pseudo-random numbers shall be as collision-free as possible. n2n uses an implementation of XORSHIFT128+ which shows a periodicity of 2¹²â¸. + +Its initialization relies on seeding with a value as random as possible. Various sources are tapped including a syscall to Linux' `SYS_getrandom` as well as Intels hardware random number generators `RDRND` and `RDSEED`, if available (compile using `-march=native`). + +### Pearson Block Hashing + +For general purpose hashing, n2n employs [Pearson Block Hashing](https://github.com/Logan007/pearsonB) as it offers variable hash sizes and is said not to be too "collidy". However, this is not a cryptographically secure hashing function which by the way is not required here: The hashing is never applied in a way that the hash value shall publicly prove the knowledge of a secret without showing the secret itself. + +_Pearson hashing is tweakable by using your own block-sized permutation._ Here, we use a three-round xor-rotate-multiply permutation scheme on 64-bit wide integer numbers with constants discovered by [David Stafford](http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) (`mix13`, permission obtained via eMail) which, meanwhile, is better known as part of `splitmix64()`. + +_Pearson hashing allows verification of block-sized parts of the hash only – just in case performance requirements would urge to do so._ + +## Header + +### Overview + +Packet's header consist of a COMMON section followed by a packet-type specific section, e.g. REGISTER, REGISTER_ACK, PACKET including the payload, REGISTER_SUPER, … + +The COMMON section is built as follows: + +``` +0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Version = 3 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! ... Community ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +In case of a PACKET-type, it is succeeded by the fields depicted below: + +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Socket Flags (v=IPv4) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Destination IPv4 Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 ! Compress'n ID ! Transform ID ! Payload ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +48 ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+... +``` + +### Encryption + +If enabled (`-H`), all fields but the payload (which is handled separately as outlined above) get encrypted using SPECK in CTR mode. As packet headers need to be decryptable by the supernode and we do not want to add another key (to keep it a simple interface), the community name serves as key (keep it secret!) because it is already known to the supernode. The community name consists of up to 20 characters (well, 19 + `0x00`), so key size of 128 bit is a reasonable choice here. + +The scheme applied tries to maintain compatibility with current packet format and works as follows: + +- First line of 4 bytes (Version, TTL, Flags) goes to sixth line: + +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Version = 3 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` +- To be able to identify a correctly decrpyted header later on, a magic number is stamped in fourth line starting at byte number 16. We use "n2" string and add the 16-bit header length to be able to stop header decryption right before an eventually following ethernet data payload begins – in case of PACKET-type, header-length does not equal packet-length. 16-bit length is required because REGISTER_SUPER_ACK packets consist of header only and could grow quite large due to their payload (other supernodes of federation) – don't mix up this kind of payload (part of the header) with the ethernet data payload of PACKET messages. + +- The rest of the community field, namely the first 16 bytes, is reframed towards a 128-bit IV for the header encryption. + +``` + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! IV ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! ... IV ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... IV ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... IV ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! Magic Number "n2" = 0x6E32 ! Header Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! Version = 3 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +- As we use a stream cipher, the IV should be a nonce. The IV plays an additional role sketched later, see the following sections on checksum and replay protection. + +- To make a less predictable use of the key space – just think of the typically reset MSB of ASCII characters of community names – we actually use a hash of the community name as key. + +- Encryption starts at byte number 16 and ends at header's end. It does not comprise PACKET's ethernet data payload which eventually has its own encryption scheme as chosen with the `-A_` options. + +Decryption checks all known communities (several in case of supernode, only one at edge) as keys. On success, the emerging magic number along with a reasonable header's length value will reveal the correct community whose name will be copied back to the original fields allowing for regular packet handling. + +Thus, header encryption will only work with previously determined community names introduced to the supernode by `-c ` parameter. Also, it should be clear that header encryption is a per-community decision, i.e. all nodes and the supernode need to have it enabled. However, the supernode supports encrypted and unencrypted communities in parallel, it determines their status online at arrival of the first packet. Use a fresh community name for encrypted communities; do not use a previously used one of former unecrypted communities: their names were transmitted openly. + +### Checksum + +The whole packet including the eventually present payload is checksummed using a Person block hashing scheme. The 64-bit checksum is exclusive-ored with a (shifted by 32 bit) 64-bit time stamp and filled up with 32 more random bits to obtain a 128-bit pre-IV. This pre-IV gets encrypted using a single block-cipher step to get the pseudo-random looking IV. This way, the checksum resists targeted bit-flips (to header, payload, and IV) as any change to the whole 128-bit IV would render the header un-decryptable. Also, as explained below, the checksum comes along with a time stamp minimizing opportunities for random attacks. + +The single block-cipher step employs SPECK because it is quite fast and it offers a 128-bit block cipher version. The key is derived from the header key – a hash of the hash. + +The checksum is calculated by the edges and the supernode. Changes to the payload will cause a different locally calculated checksum. Extracting the time stamp by exclusive-oring an erroneous checksum will lead to an invalid timestamp. So, checksum errors are indirectly detected when checking for a valid time stamp. + +### Replay Protection + +The aforementioned 128-bit pre-IV can be depicted as follows: + +``` + 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 + +----------------------------------------------------------------+-------------------------------+-------------------------------+ + ! 64-bit checksum of the whole packet ! 0x00 ! ! + + - - - - - - - - - - - - - - - - - - - - - - - XOR - - - - - - - - - - - - - - - - - - - - - - -! 32 pseudo-random bits ! + ! 0x00 ! 52-bit time stamp with microsecond-accuracy ! countr ! F ! ! + +------------------------------------------------------------------------------------------------+-------------------------------+ + +``` + +The time stamp consists of the 52-bit microsecond value, a 8-bit counter in case of equal following time stamps and, a 4-bit flag field F (accuracy indicator in last bit). edge and supernode monitor their own time stamps for doublets which would indicate an accuracy issue. If the counter overflows on the same time stamp, the sub-second part of the time stamp will also become counter. In this case, the whole stamp carries the accuracy bit flag (lowest bit) set so other edges and supernodes can handle this stamp appropriately. + +Encrypting this pre-IV using a block cipher step will generate a pseudo-random looking IV which gets written to the packet and used for the header encryption. + +Due to the time-stamp encoded, the IV will more likely be unique, close to a real nonce. + +Upon receival, the time stamp as well as the checksum can be extracted from the IV by performing a 128-bit block-cipher decryption step. Verification of the time stamp happens in two steps: + +- The (remote) time stamp is checked against the local clock. It may not deviate more than plus/minus 16 seconds. So, edges and supernode need to keep a somewhat current time. This limit can be adjusted by changing the `TIME_STAMP_FRAME` definition. It is time-zone indifferent as UTC is used. + +- Valid (remote) time stamps get stored as "last valid time stamp" seen from each node (supernode and edges). So, a newly arriving packet's time stamp can be compared to the last valid one. It should be equal or higher. However, as UDP packets may overtake each other just by taking another path through the internet, they are allowed to be 160 millisecond earlier than the last valid one. This limit is set with the `TIME_STAMP_JITTER` definition. If the accuracy flag is set, the time stamp will be allowed a jitter eight times as high, corresponding to 1.25 seconds by default. + +- However, the systemic packets such as REGISTER_SUPER are not allowed any time stamp jitter because n2n relies on the actual sender's socket. A replay from another IP within any allowed jitter time frame would deviate the traffic which shall be prevented (even if it remains undecryptable). Under absolutely rare (!) circumstances, this might cause a re-registration requirement which happens automatically but might cause a small delay – security (including network availability) first! REGISTER packets from the local multicast environment are exempt from the very strict no-jitter requirement because they indeed regularly can show some deviation if compared to time stamps in packets received on the regular socket. As these packets are incoming on different sockets, their processing is more likely to no take place in the order these packets were sent. + +The way the IV is used for replay protection and for checksumming makes enabled header encryption a prerequisite for these features. diff --git a/bundles/n2n_ntop_v3/doc/Faq.md b/bundles/n2n_ntop_v3/doc/Faq.md new file mode 100644 index 00000000..7958248e --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Faq.md @@ -0,0 +1,72 @@ +# n2n Frequently Asked Questions + + +## Supernode + + +### I want to setup a supernode that only I can use. Perhaps even password protected? + +Please think of the community-name as password and start the supernode with the `-c ` parameter where the `` is the path to a simple text file containing a single line with the name of your secret community. It will be the only community allowed. Only edge nodes from that community can join (`-c ` at the edge). + +If you additionally want to prevent open transmission of your secret community name via the network, **all** edge nodes should use `-H` command line option for header encryption. + +Also, please see the `community.list` file coming with n2n for advanced use of that file. + +Beyond this access barrier you may want to use payload encryption `-A_` at the edges. Only the edges – not the supernode – are able to decipher the payload data. So, even if anyone would be able to break the access barrier to the supernode, the payload remains protected by the payload crypto, see [this document](https://github.com/ntop/n2n/blob/dev/doc/Crypto.md) for details. + + +### Can I get a list of connected edge nodes and their community and source IP address from the supernode? + +The supernode provides basic information via its localhost udp management port. It defaults to 5645 and can be changed using supernode's `-t` command line option. + +You can request the current status by just sending a new line, i.e. pressing [ENTER] key, running the following command (localhost only) + +`netcat -u localhost 5645` + + +### Is there support for multiple supernodes? + +Yes, there is. Please [read](https://github.com/ntop/n2n/blob/dev/doc/Federation.md) about how several supernodes can form a Federation to increase network resilience. + + +### Can a supernode listen on multiple ports? + +The supernode itself can only listen on one port. However, your firewall might be able to map additional UDP ports to the supernode's regular port: + +`sudo iptables -t nat -A PREROUTING -i -d -p udp --dport -j REDIRECT --to-ports ` + +This command line can be put down as additional `ExecStartPost=` line (without `sudo`) in the supernode's `.service` file which can hold several such lines if required. + + +### How to handle the error message "process_udp dropped a packet with seemingly encrypted header for which no matching community which uses encrypted headers was found"? + +This error message means that the supernode is not able to identify a packet as unencrypted. It does check for a sane packet format. If it fails the header is assumed encrypted (thus, "_seemingly_ encrypted header") and the supernode tries all communities that would make a key (some have already been ruled out as they definitely are unenecrypted). If no matching community is found, the error occurs. + +If all edges use the same `-H` setting (all edges either with it or without it) and restarting the supernode does not help, most probably one of the components (an edge or the supernode) is outdated, i.e. uses a different packet format – from time to time, a lot of changes happen to the packet format in a very short period of time, especially in _dev_ branch. + +So, please make sure that all edges **and** the supernode have the exact same built version, e.g. all from current _dev_. + + +## Edge + + +### How can I know if peer-to-peer connection has successfully been established? + +The edge also offers a local udp management port at which it provides some information about connected _peers_ allowing a peer-to-peer connection, and _pending peers_ whose connections are forwarded through the supernode. + +The edge's management port defaults to 5644 and can be changed using edge's `-t` command line option. Connecting using the following command (localhost only) + +`netcat -u localhost 5644` + +answers every new line, i.e. pressing [ENTER] key, with current information. The edge even understands some simple commands, try `help`. + + +### The edge repeatedly throws an "Authentication error. MAC or IP address already in use or not released yet by supernode" message. What is wrong? + +The edge encountered n2n's protection against spoofing. It prevents that one edge's identity, MAC and IP address, can be impersonated by some other while the original one is still online, see some [details](Authentication.md). Mostly, there are two situations which can trigger this: + +If you use a MAC or IP address that already is in use, just change those parameters. + +If the edge prematurely has ended in a non-regular way, i.e. by killing it using `kill -9 ...` or `kill -SIGKILL ...`, it did not have a chance to un-register with the supernode which still counts the edge for online. A re-registration with the same MAC or IP address will be unsuccessful then. After two minutes or so the supernode will have forgotten. A new registration with the same parameters will be possible then. So, either wait two minutes or chose different parameters to restart with. + +And, as a matter of principal, always end an edge by either pressing `CTRL` + `C` or by sending SIGTERM or SIGINT by using `kill -SIGTERM ...` or `kill -SIGINT ...`! A plain `kill ...` without `-9` will do, too. And finally, a `stop` command to the management port peacefully ends the edge as well. diff --git a/bundles/n2n_ntop_v3/doc/Federation.md b/bundles/n2n_ntop_v3/doc/Federation.md new file mode 100644 index 00000000..3442346e --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Federation.md @@ -0,0 +1,39 @@ +# Supernode Federation + +## Idea +To enhance resilience in terms of backup and fail-over, also for load-balancing, multiple supernodes can easily interconnect and form a special community, called **federation**. + + +## Using Multiple Supernodes + +### Form a Federation + +To form a federation, multiple supernodes need to be aware of each other. To get them connected, an additional `-l` option from command line is required at the supernode. + +This option takes the IP address (or name) and the UDP port of another known supernode, e.g. `-l 192.168.1.1:1234`. + +### Use a Federation + +Federated supernodes take care of propagating their knowledge about other supernodes to all other supernodes and the edges. + +So, in the first place, edges only need to connect to one supernode (called anchor supernode) using `-l` option. This supernode needs to be present at start-up. + +Optionally, more anchor supernodes of the same federation can be provided to an edge using several `-l` options. This will counter scenarios with reduced assured initial supernode availability. + +## How It Works + +Supernodes should be able to communicate among each other as regular edges already do. For this purpose, a special community called federation was introduced. The federation feature provides some mechanisms to inter-connect the supernodes of the network enhancing backup, fail-over and load-sharing, without any visible behavioral change. + +The default name for the federation is `*Federation`. Internally, a mandatory special character is prepended to the name: that way, an edge won't be able to provide a regular community with the same name of the federation. Optionally, a user can choose a federation name (same on all supernodes) and provide it via `-F mySecretFed` option to the supernode. Alternatively, the federation name can be passed through the environment variable `N2N_FEDERATION`. + +Federated supernodes register to each other using REGISTER_SUPER message type. The answer, REGISTER_SUPER_ACK, contains a payload with information about other supernodes in the network. + +This specific mechanism is also used during the registration process taking place between edges and supernodes, so edges are able to learn about other supernodes. + +Once edges have received this information, it is up to them choosing the supernode they want to connect to. Each edge pings supernodes from time to time and receives information about them inside the answer. We decided to implement a work-load based selection strategy because it is more in line with the idea of keeping the workload low on supernodes. Moreover, this way, the entire network load is evenly distributed among all available supernodes. + +An edge connects to the supernode with the lowest work-load and it is re-considered from time to time, with each re-registration. We use a stickyness factor to avoid too much jumping between supernodes. + +Thanks to this feature, n2n is now able to handle security attacks such as DoS against supernodes and it can redistribute the entire load of the network in a fair manner between all the supernodes. + +To serve scenarios in which an edge is supposed to select the supernode by round trip time, i.e. choosing the "closest" one, the `--select-rtt` command line option is available at the edge. Note, that workload distribution among supernodes might not be so fair then. diff --git a/bundles/n2n_ntop_v3/doc/Hacking.md b/bundles/n2n_ntop_v3/doc/Hacking.md new file mode 100644 index 00000000..1dd47740 --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Hacking.md @@ -0,0 +1,262 @@ +# Hacking + +-------- + +This program and document 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 3 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 see see [](http://www.gnu.org/licenses/) + +-------- + +This file describes the internals of n2n. Read this before starting to modify +the code. Because coding examples may be present in this document it is licensed +under the GPL rather than FDL. + +## Symmetric NAT + +Symmetric NAT is a form of firewall NAT in which an UDP packets are only passed +back to an inside host socket when the return packets originate from the outside +socket to which the initiating UDP packets were sent. This means that when an +inside host sends UDP to some outside socket; other hosts cannot piggyback on +this opening in the firewall to send data to the inside host. + +For example, an asymmetric NAT would keep the mapping: + + ` -> ` + +and would redirect all the packets on external port ExtPort to the internal host +regardless of the remote IP. + +Whereas a symmetric NAT would keep the mapping: + + ` -> ` + +so only RemoteIP can send packets to the internal host. RemoteIP is the supernode +IP in case of n2n, to which the internal host has registered. + +In n2n, P2P can work monodirectionally if only one of the two peers is behind a symmetric +NAT. For example, if A is behind symmetric NAT and B is behind asymmetric NAT + - A->B packets are P2P (will have the B public IP as destination) + - B->A packets must go through the supernode + +If both the peers are behind symmetric NAT, then no P2P communication is possible. + +## ARP Cache + +n2n makes use of the host operating system's own ARP cache. Each edge node +allocates a random MAC address to itself. This MAC is constant for the life of +the edge process. ARP packets are passed around as broadcast ethernet packets +over n2n and these packets cause the native ARP cache to be updated. + +Edge nodes send gratuitous ARP packets on startup. See section on gratuitous ARP below. + + +## Registration and Peer-to-Peer Communication Setup + +A and B are edge nodes with public sockets Apub and Bpub; and private network +addresses A and B respectively. S is the supernode. + +A sends {REGISTER,Amac} to S. S registers {Amac->Apub}. + +B sends {REGISTER,Bmac} to S. S registers {Bmac->Bpub}. + +Now ping from A to B. + +A sends broadcast "arp who-has B" to S. S relays the packet to all known edge +nodes. B replies "B at Bmac" to supernode which forwards this to A. So now ping +A->B is known to be ping Amac(A)->Bmac(B). Note: gratuitous arp also requires +discussion. + +In response to receiving the arp reply, Apub sends {REGISTER,Amac} to Bpub. If +Bpub receives the request it sends back {REGISTER_ACK,Amac} and also sends its +own {REGISTER,Bmac} request. + +In response to receiving the "arp who-has", Bpub sends {REGISTER,Bmac} to Apub. + +Now the OS has received the arp reply and sends ICMP to Bmac(B) via the tunnel +on A. A looks up Bmac in the peers list and encapsulates the packet to Bpub or +the supernode if the MAC is not found. + +We assume that between two edge nodes, if Bpub receives a packet from Apub then +Apub can receive a packet from Bpub. This is the symmetric NAT case. Note: In +the symmetric NAT case, the public socket for a MAC address will be different +for direct contact when compared to information from the supernode. + +When two edge nodes are both behind symmetric NAT they cannot establish direct +communication. + +If A receives {REGISTER,Bmac} from B, A adds {Bmac->Bpub} to its peers list +knowing that Bmac is now reachable via that public socket. Similarly if B +receives {REGISTER,Amac} from A. + +The supernode never forwards REGISTER messages because the public socket seen by +the supervisor for some edge (eg. A) may be different to the socket seen by +another edge due to the actions of symmetric NAT (allocating a new public socket +for the new outbound UDP "connection"). + +## Edge Resgitration Design Ammendments (starting from 2008-04-10) + + * Send REGISTER on rx of PACKET or REGISTER only when dest_mac == device MAC +(do not send REGISTER on Rx of broadcast packets). + * After sending REGISTER add the new peer to pending_peers list; but + * Don't send REGISTER to a peer in pending_peers list + * Remove old entries from pending_peers at regular intervals + * On rx of REGISTER_ACK, move peer from pending_peers to known_peers for direct +comms and set last_seen=now + * On rx of any packet set last_seen=now in the known_peers entry (if it +exists); but do not add a new entry. + * If the public socket address for a known_peers entry changes, deleted it and +restart registration to the new peer. + * Peer sockets provided by the supernode are ignored unless no other entry +exists. Direct peer-to-peer sockets are always given more priority as the +supernode socket will not be usable for direct contact if the peer is behind +symmetric NAT. + +The pending_peers list concept is to prevent massive registration traffic when +supernode relay is in force - this would occur if REGISTER was sent for every +incident packet sent via supernode. Periodic REGISTER attempts will still occur; +not for every received packet. In the case where the peer cannot be contacted +(eg. both peers behind symmetric NAT), then there will still be periodic +attempts. Suggest a pending timeout of about 60 sec. + +A peer is only considered operational for peer-to-peer sending when a +REGISTER_ACK is returned. Once operational the peer is kept operational while +any direct packet communications are occurring. REGISTER is not required to +keep the path open through any firewalls; just some activity in one direction. + +After an idle period; the peer should be deleted from the known_peers list. We +should not try to re-register when this time expires. If there is no data to +send then forget the peer. This helps scalability. + +If a peer wants to be remembered it can send gratuitous ARP traffic which will +keep its entry in the known_peers list of any peers which already have the +entry. + +``` +peer = find_by_src_mac( hdr, known_peers ); /* return NULL or entry */ + +if ( peer ) +{ + peer_last_seen = time(NULL); +} +else +{ + if ( ! is_broadcast( hdr ) ) /* ignore broadcasts */ + { + if ( IS_REGISTER_ACK( hdr ) ) + { + /* move from pending to known_peers */ + set_peer_operational( hdr ); + } + else + { + /* add to pending and send REGISTER - ignore if in pending. */ + try_send_register( hdr ) + } + } +} +``` + +### Notes + + * In testing it was noted that if a symmetric NAT firewall shuts down the UDP +association but the known_peers registration is still active, then the peer +becomes unreachable until the known_peers registration is deleted. Suggest two +ways to mitigate this problem: + (a) make the known_peers purge timeout a config parameter; + (b) send packets direct and via supernode if the registration is older than + eg. 60 sec. + + +## Gratuitous ARP + +In addition to the ARP who-has mechanism noted above, two edge nodes can become +aware of one another by gratuitous ARP. A gratuitous ARP packet is a broadcast +packet sent by a node for no other purpose than to announce its presence and +identify its MAC and IP address. Gratuitous ARP packets are to keep ARP caches +up to date so contacting the host will be faster after an long idle time. + + +## man Pages + +Look at a non-installed man page like this (linux/UNIX): + +`nroff -man edge.8 | less` + + +## PACKET message format + +All message encoding and decoding is contained in wire.c. The PACKET message is +of main concern as it is the most frequently transferred as it contains +encapsulated ethernet packets. + +``` +Version 3 + + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Version=3 ! TTL ! Flags ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 4 ! Community : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 8 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +12 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +16 ! ... Community ... : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +20 ! ... Community ... ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +24 ! Source MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +28 : ! Destination MAC Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +32 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Socket Flags (v=IPv4) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Destination IPv4 Address ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 ! Compress'n ID ! Transform ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 ! Payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +So each n2n PACKET has a 48 byte overhead. For a 1500 byte ethernet packet this +is roughly 3%. + +Socket flags provides support for IPv6. In this case the PACKET message ends as +follows: + +``` + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +36 ! Socket Flags (v=IPv6) ! Destination UDP Port ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +40 ! Destination IPv6 Address : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +44 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +48 : : + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +52 : ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +56 ! Compress'n ID ! Transform ID ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +60 ! Encapsulated ethernet payload + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +``` + +------- +(C) 2008-2010 - Richard Andrews + +January 2010 - Richard Andrews \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/doc/ManagementAPI.md b/bundles/n2n_ntop_v3/doc/ManagementAPI.md new file mode 100644 index 00000000..617e3458 --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/ManagementAPI.md @@ -0,0 +1,188 @@ +# Management API + +This document is focused on the machine readable API interfaces. + +Both the edge and the supernode provide a management interface UDP port. +These interfaces have some documentation on their non machine readable +commands in the respective daemon man pages. + +Default Ports: +- UDP/5644 - edge +- UDP/5645 - supernode + +A Quick start example query: + `echo r 1 help | nc -w1 -u 127.0.0.1 5644` + +## JSON Query interface + +A machine readable API is available for both the edge and supernode. It +takes a simple text request and replies with JSON formatted data. + +The request is in simple text so that the daemon does not need to include any +complex parser. + +The replies are all in JSON so that the data is fully machine readable and +the schema can be updated as needed - the burden is entirely on the client +to handle different replies with different fields. It is expected that +any client software will be written in higher level programming languages +where this flexibility is easy to provide. + +Since the API is over UDP, the replies are structured so that each part of +the reply is clearly tagged as belonging to one request and there is a +clear begin and end marker for the reply. This is expected to support the +future possibilities of pipelined and overlapping transactions as well as +pub/sub asynchronous event channels. + +The replies will also handle some small amount of re-ordering of the +packets, but that is not an specific goal of the protocol. + +Note that this API will reply with a relatively large number of UDP packets +and that it is not intended for high frequency or high volume data transfer. +It was written to use a low amount of memory and to support incremental +generation of the reply data. + +With a small amount of effort, the API is intended to be human readable, +but this is intended for debugging. + +## Request API + +The request is a single UDP packet containing one line of text with at least +three space separated fields. Any text after the third field is available for +the API method to use for additional parameters + +Fields: +- Message Type +- Options +- Method +- Optional Additional Parameters + +The maximum length of the entire line of text is 80 octets. + +### Message Type + +This is a single octet that is either "r" for a read (or query) method +call or "w" for a write (or change) method call. + +To simplify the interface, the reply from both read and write calls to the +same method is expected to contain the same data. In the case of a write +call, the reply will contain the new state after making the requested change. + +### Options + +The options field is a colon separated set of options for this request. Only +the first subfield (the "tag") is mandatory. The second subfield is a set +of flags that describe which optional subfields are present. +If there are no additional subfields then the flags can be omitted. + +SubFields: +- Message Tag +- Optional Message Flags (defaults to 0) +- Optional Authentication Key + +#### Message Tag + +Each request provides a tag value. Any non error reply associated with this +request will include this tag value, allowing all related messages to be +collected within the client. + +Where possible, the error replies will also include this tag, however some +errors occur before the tag is parsed. + +The tag is not interpreted by the daemon, it is simply echoed back in all +the replies. It is expected to be a short string that the client chooses +to be unique amongst all recent or still outstanding requests. + +One possible client implementation is a number between 0 and 999, incremented +for each request and wrapping around to zero when it is greater than 999. + +#### Message Flags + +This subfield is a set of bit flags that are hex-encoded and describe any +remaining optional subfields. + +Currently, only one flag is defined. The presence of that flag indicates +that an authentication key subfield is also present. + +Values: +- 0 - No additional subfields are present +- 1 - One additional field, containing the authentication key + +#### Authentication Key + +A simple string password that is provided by the client to authenticate +this request. See the Authentication section below for more discussion. + +#### Example Options value + +e.g: + `102:1:PassWord` + +### Example Request string + +e.g: + `r 103:1:PassWord peer` + +## Reply API + +Each UDP packet in the reply is a complete and valid JSON dictionary +containing a fragment of information related to the entire reply. + +### Common metadata + +There are two keys in each dictionary containing metadata. First +is the `_tag`, containing the Message Tag from the original request. +Second is the `_type` whic identifies the expected contents of this +packet. + +### `_type: error` + +If an error condition occurs, a packet with a `error` key describing +the error will be sent. This usually also indicates that there will +be no more substantial data arriving related to this request. + +e.g: + `{"_tag":"107","_type":"error","error":"badauth"}` + +### `_type: begin` + +Before the start of any substantial data packets, a `begin` packet is +sent. For consistency checking, the method in the request is echoed +back in the `error` key. + +e.g: + `{"_tag":"108","_type":"begin","cmd":"peer"}` + +For simplicity in decoding, if a `begin` packet is sent, all attempts +are made to ensure that a final `end` packet is also sent. + +### `_type: end` + +After the last substantial data packet, a final `end` packet is sent +to signal to the client that this reply is finished. + +e.g: + `{"_tag":"108","_type":"end"}` + +### `_type: row` + +The substantial bulk of the data in the reply is contained within one or +more `row` packets. The non metadata contents of each `row` packet is +defined entirely by the method called and may change from version to version. + +Each `row` packet contains exactly one complete JSON object. The row replies +may be processed incrementally as each row arrives and no batching of multiple +packets will be required. + +e.g: + `{"_tag":"108","_type":"row","mode":"p2p","ip4addr":"10.135.98.84","macaddr":"86:56:21:E4:AA:39","sockaddr":"192.168.7.191:41701","desc":"client4","lastseen":1584682200}` + +## Authentication + +Some API requests will make global changes to the running daemon and may +affect the availability of the n2n networking. Therefore the machine +readable API include an authentication component. + +Currently, the only authentication is a simple password that the client +must provide. It defaults to 'n2n' and can manually be set through the +command line parameter `--management-password ` – for edge as well +as for supernode. diff --git a/bundles/n2n_ntop_v3/doc/Routing.md b/bundles/n2n_ntop_v3/doc/Routing.md new file mode 100644 index 00000000..c4d57f2f --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Routing.md @@ -0,0 +1,188 @@ +# IPv4 Routing (Linux) + +## General Remarks + +Reaching a remote network or tunneling all the internet traffic via n2n are two common tasks which require a proper routing setup. n2n supports routing needs providing options for packet forwarding including broadcasts as well as modifying the routing table. + +In this context, the `server` is the edge node which provides access to the remote network/internet, whereas the `client` is the connecting edge node. + +In order to enable routing, the `server` must be configured as follows: + +1. Add the `-r` option to the edge options to enable routing +2. Enable packet forwarding with `sudo sysctl -w net.ipv4.ip_forward=1` +3. Enable IP masquerading: `sudo iptables -t nat -A POSTROUTING -j MASQUERADE` + +On the client side, the easiest way to configure routing is via the `-n` option. For example: + +- In order to connect to the remote network `192.168.100.0/24`, use `-n 192.168.100.0/24:10.0.0.1` +- In order to tunnel all the internet traffic, use `-n 0.0.0.0/0:10.0.0.1` + +10.0.0.1 is the IP address of the gateway to use to route the specified network. It should correspond to the IP address of the `server` within n2n. Multiple `-n` options can be specified. + +As an alternative to the `-n` option, the `ip route` linux command can be manually used. See the [n2n-gateway.sh](scripts/n2n-gateway.sh) script for an example. See also the following description of other use cases and in depth explanation. + +## Special Scenarios + +### Assumptions + +- There are two Local Area Networks, namely 10.11.12.0/24 (maybe at + **h**ome) and 192.168.1.0/24 (maybe in **o**ffice). +- These networks are connected to the internet via routers 10.11.12.1 + and 192.168.1.1, respectively. +- In each network, there is a computer running a successfully setup n2n + node: 10.11.12.5 (**h**ickory) and 192.168.1.6 (**o**scar). They are + connected to their networks through a device called _eth0_. Their n2n + devices shall be called _n2n0_, and their n2n IP addresses are + 10.99.99.50 (**h**ickory) and 10.99.99.60 (**o**scar) in the + 10.99.99.0/24 network. +- The _iptables_ are flushed. + +### Prerequisites + +- Both, **h**ickory and **o**scar have ip forwarding enabled: `echo 1 > /proc/sys/net/ipv4/ip_forward` or `sysctl -w net.ipv4.ip_forward=1`. To + make this setting persistent over reboot, a file containing the line + `net.ipv4.ip_forward=1` could be added in /etc/sysctl.d/ – your distro + may vary. +- To allow n2n to forward packets, both edge nodes need to be started + with `-r` option on their command line. All other regular network + interfaces usually already allow packet forwarding and thus do not need + any further configuration. + +### Reach Complete Office Network from n2n Node at Home + +- To make **h**ickory send all packets with office destination via + **o**scar, **h**ickory needs to be made aware of where to route this + packets to. On **h**ickory: `ip route add 192.168.1.0/24 via 10.99.99.60 dev n2n0 src 10.11.12.5`. +- **o**scar needs to know where to send packets to, too. So, on + **o**scar: `ip route add 10.11.12.5 via 10.99.99.50 dev n2n0 src 192.168.1.6`. + +**o**scar and **h**ickory should now be able to exchange packets by +using just their regular (non-n2n) IP addresses 10.11.12.5 and 192.168.1.6. +To make the complete office network aware of how packets or answers are +sent to **h**ickory, one more step is required: + +- Packets from any office computer to **h**ickory need to be directed to + **o**scar that – thanks to enabled IP forwarding and the routing rule – + already knows how to handle this kind of packets. + - To handle it in a one-stop-shop, the office router 192.168.1.1 can + be configured to direct those packets to **o**scar. Luckily, even most + modern small-office-and-home routers allow to add static routing rules + via a web interface. A rule like "All packets for host 10.11.12.5 (or + network 10.11.12.0/24) need to be sent to another router, namely + 192.168.1.5" will do. This is the **recommended** solution. + - However, a **less recommended** but working option would be to add + static routes to each single of those computers in the office network + that shall be able to connect to or be accessed by **h**ickory. On + those, e.g. **o**livia with IP address 192.168.1.123: `ip route add 10.11.12.5 via 192.168.1.5 dev eth0 src 192.168.1.123`. + - Alternatively, in case the office router does not allow to have + added own static routing rules, **o**scar needs to perform NAT for all + connections initiated from **h**ickory: + `iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE` + `iptables -A FORWARD -i eth0 -o n2n0 -m state --state RELATED,ESTABLISHED -j ACCEPT` + `iptables -A FORWARD -i n2n0 -o eth0 -j ACCEPT` + There is a major drawback with this solution which thus is the **least + recommended**: Connections between **h**ickory and the office network + will only work if initiated by **h**ickory – not the other way 'round. + By the way, in case _iptables_ are messed up, they can be flushed by: + `iptables -F` + `iptables -X` + `iptables -t nat -F` + `iptables -t nat -X` + `iptables -t mangle -F` + `iptables -t mangle -X` + `iptables -t raw -F` + `iptables -t raw -X` + `iptables -t security -F` + `iptables -t security -X` + `iptables -P INPUT ACCEPT` + `iptables -P FORWARD ACCEPT` + `iptables -P OUTPUT ACCEPT` + +### Reach n2n Node in Office from Whole Home Network + +This is easy: + +- Just exchange home and office IP addresses and the computer names in + the instructions given above. + +### Reach Whole Home Network from Whole Office Network + +This is not too complicated either. Basically, follow the given example +above and apply the following changes: + +- The instructions used above need to be expanded from **h**ickory's IP + 10.11.12.5 to its full network 10.11.12.0/24 in the route commands on + **o**scar:, especially: `ip route add 10.11.12.0/24 via 10.99.99.50 dev n2n0 src 192.168.1.6`. +- In case of adding a static route to the office network router + 192.168.1.1, the home network 10.11.12.0/24 must be specified instead of + **h**ickory's more specific IP address 11.11.12.5. Same for the less + recommended static routes on other office computers. +- Packets from home network's computers to the office network need to be + sent through the n2n tunnel. The three alternatives given above can be + used just with exchanged office and home IP addresses. One needs to be + aware that NAT only (third alternative) on both sides will not allow any + connection, i.e. at least on one side static routes need to be added + either to the router (best option) or all those computers that shall be + able to connect to the other network. + +### Route All Internet Traffic from n2n Node at Home through Office Network + +This scenario could be considered a n2n-tunneled VPN connection which +also would work for travelling users on their laptop. All external +internet traffic will appear to originate from **o**scar and the office +network. + +- First, one of the setups described above needs to be in place, with + the following change: +- NAT on **o**scar (see the three _iptables_ commands above) must be + enabled. It will not work without because the office router 192.168.1.1 + usually denies forwarding to packets not originating from its own + network. It could be in addition to the eventually installed static + routes for 10.11.12.0/24 in the router 192.168.1.1 or on other office + computers – it will not interfere. However, **o**scar definitely needs + the route given above: `ip route add 10.11.12.5 via 10.99.99.50 dev n2n0 src 192.168.1.6`. +- To have **h**ickory's complete internet traffic going through the n2n + tunnel, its default route needs to be changed: + `ip route del default` + `ip route add default via 10.99.99.60 dev n2n0 src 10.11.12.5` + +- **h**ickory's home network should still be reachable as usually, + _eth0_ and the associated network 10.11.12.0/24 get their very own + route. If not, i.e. it was only covered by default route before, it + needs to be added: `ip route add 10.11.12.0/24 dev eth0 src 10.11.12.5`. +- Unfortunately (unless the supernode is on **h**ickory's local + network), n2n supernode becomes unreachable for **h**ickory. To fix it: + `ip route add via 10.11.12.1 dev eth0 src 10.11.12.5` + +The supernode's IP address needs to be known to have this work. However, +if the supernode's IP needs to be resolved from some domain name (FQDN), +e.g. in case of using dynamic domain name services, a DNS server needs +to remain reachable, too. Either the reachable home network router +10.11.12.1 is good enough for that (if it offers DNS) or another route +could to be added and **h**ickory's DNS settings might be set +accordingly, maybe to Google's 8.8.8.8. + +If [DNS leaks](https://en.wikipedia.org/wiki/DNS_leak) do not matter, +this setup is complete. + +### Preventing DNS Leaks + +Otherwise, there is more to it: Without changes, all future DNS queries +go through the home router 10.11.12.1 to the ISP's servers or directly +to Google (via the home router 10.11.12.1 along the configured route for +8.8.8.8 and not through the n2n tunnel) while the remaining traffic +ships through the n2n tunnel. + +To prevent such a DNS leak, the supernode's IP address must be +determined independently from **h**ickory's DNS configuration, e.g. by +digesting `dig +short mysupernode.myfavoritednsservice.com @8.8.8.8`'s +output in the n2n-edge's setup script for both, the edge node command +line as well as the static route mentioned above. Without further +additional work, dynamic address changes remain undetected. A static +route to 8.8.8.8 is still required. **h**ickory's regular DNS +configuration should query a different DNS server for its regular DNS +needs, e.g. 9.9.9.9 or 1.1.1.1 or maybe the office DNS server, maybe +192.168.1.1. This guarantees the regular DNS queries also to get sent +through the n2n tunnel. + +A test for DNS leaks can be found [here](https://www.dnsleaktest.com/). diff --git a/bundles/n2n_ntop_v3/doc/Scratchpad.md b/bundles/n2n_ntop_v3/doc/Scratchpad.md new file mode 100644 index 00000000..68d5f882 --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Scratchpad.md @@ -0,0 +1,61 @@ +# n2n's Scratchpad + +## RPM Packaging + +``` +bash +./autogen.sh +./configure +make + +cd packages/rpm +./configure +rpmbuild -bb ./n2n.spec +``` + +## New Features between 2.0.x and 2.1.x + +- Better ming Windows build support. +- Added `-E` flag to allow multicast ethernet traffic. + +## Draft changelog between 2.8 and 3.0 (as of September 27, 2021) + +### New Features + +- Federated supernodes to allow multiple supernodes for load balancing and fail-over (`doc/Federation.md`) +- Automatic IP address assignment allows edges to draw IP addresses from the supernode (just skip `-a`) +- Allowed community names can be restricted by regular expressions (`community.list` file) +- Network filter for rules (`-R`) allowing and denying specific traffic to tunnel +- Experimental TCP support (`-S2`) lets edges connect to the supernodes via TCP in case firewalls block UDP (not available on Windows yet) +- All four supported ciphers offer integrated versions rendering OpenSSL dependency non-mandatory (optionally still available) +- MAC and IP address spoofing prevention +- Network interface metric can be set by command-line option `-x` (Windows only) +- Re-enabled local peer detection by multicast on Windows +- Edge identifier (`-I`) helps to identify edges more easily in management port output +- Optionally bind edge to one local IP address only (extension to `-p`) +- A preferred local socket can be advertised to other edges for better local peer-to-peer connections (`-e`) +- Optional edge user and password authentication (`-J`, `-P`, `doc/Authentication.md`) +- Optional json format at management port allows for machine-driven handling such as `.html` page generation (`scripts/n2n-httpd`) or script-based evaluation (`scripts/n2n-ctl`) +- Completely overhauled build system including GitHub's action runners performing code syntax and formal checks, creating and running test builds, providing binairies and packages as artifacts and running verification tests + + +### Improvements + +- Increased edges' resilience to temporary supernode failure +- Fixed a compression-related memory leak +- Ciphers partly come with platform-specific hardware acceleration +- Added a test framework (`tools/test-*.c` and `tests/`) +- Clean-up management port output +- Polished benchmark tool output +- Spun-off the name resolution into a separate thread avoiding lags +- Added support for additional environment variables (`N2N_COMMUNITY`, `N2N_PASSWORD`, and `N2N_FEDERATION`) +- Implemented new `reload_communities` command to make supernode hot-reload the `-c` provided `community.list` file, issued through management port +- Reactivated send out of gratuitous ARP packet on establishing connection +- Enhanced documentation (`doc/` folder) including the man pages and command-line help text (`-h` and more detailed `--help`) +- Self-monitoring time stamp accuracy for use on systems with less accurate clocks +- Fixed man pages' and config files' paths +- Code clean-up + + + + diff --git a/bundles/n2n_ntop_v3/doc/Scripts.md b/bundles/n2n_ntop_v3/doc/Scripts.md new file mode 100644 index 00000000..f2ac2ebc --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/Scripts.md @@ -0,0 +1,55 @@ +# Scripts + +There are a number of useful scripts included with the distribution. +Some of these scripts are only useful during build and development, but +other scripts are intended for end users to be able to use. These scripts +may be installed with n2n as part of your operating system package. + +Short descriptions of these scripts are below. + +## `scripts/hack_fakeautoconf.sh` + +This shell script is used during development to help build on Windows +systems. An example of how to use it is shown in +the [Building document](Building.md) + +## `scripts/indent.sh` + +This shell script is a wrapper for the `uncrustify` C code style checker +which checks or applies a set of rules to the code. It is used during +the automated lint checks. + +## `scripts/test_harness.sh` + +This shell script is used to run automated tests during development. + +## `scripts/n2n-ctl` + +This python script provides an easy command line interface to the running +n2n processes. It uses UDP communications to talk to the Management API. +By specifying the right UDP port, it can talk to both the edge and the +supernode daemons. + +Example: +- `scripts/n2n-ctl --help` +- `scripts/n2n-ctl help` + +## `scripts/n2n-httpd` + +This python script is a simple http gateway to the running edge. It provides +a proxy for REST-like HTTP requests to talk to the Management API. + +By default it runs on port 8080. + +It also provides a simple HTML page showing some edge information, which when +run with default settings can be seen at http://localhost:8080/ (Also +a http://localhost:8080/supernode.html page for the supernode) + +Example: +- `scripts/n2n-httpd --help` +- `scripts/n2n-httpd 8087` + +## `scripts/n2n-gateway.sh` + +A sample script to route all the host traffic towards a remote gateway, +which is reachable via the n2n virtual interface. diff --git a/bundles/n2n_ntop_v3/doc/TapConfiguration.md b/bundles/n2n_ntop_v3/doc/TapConfiguration.md new file mode 100644 index 00000000..69c9491c --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/TapConfiguration.md @@ -0,0 +1,151 @@ +# TAP Device Configuration + +n2n provides its service through a TAP device which is the virtual ethernet device seen by the computer and user. As a prerequisite, it requires the appropriate TAP driver to be installed. Most Linux systems come with it. If not loaded, `sudo modprobe tap` will do. + +For MacOS and Windows there are specific instructions; please see the [Building](./Building.md) document. + +## Device Name + +If the OS specific driver allows **naming** the virtual Ethernet device created by n2n, the `-d ` command-line option can be used to give a name, e.g. `-d n2n0`. This device name makes the virtual ethernet device easily accessible to all `ip` command activity, `iptables`, `tcpdump` and any other of your preferred network tools. It defaults to `edge0` if not provided through `-d`. + +One exception applies to Windows: As the installed TAP driver(s) come with fixed names, `-d ` **selects** the appropriate device by name out of the present ones. This is only required if more than one TAP devices are present. To help with it, `edge --help` lists the available TAP adapters at the bottom of its output (Windows only). + +## MAC + +Even virtual ethernet devices have a MAC address. As in real networks, it should be unique as it is used to identify the different participants and transport packets accordingly. The MAC address can optionally be specified by using the `-m ` command line parameter, e.g. `-m 01:02:03:04:05:06`. If omitted, n2n tries to assign a random MAC address. + +## IP Address + +n2n supports several ways to assign an IPv4 address to the virtual ethernet device. Support for IPv6 addresses relies on OS support. + +### Manually Assigned IP Address + +The command line parameter `-a ` assigns a static IP address, e.g. `-a static:192.168.8.5` to the device. The optional `static` keyword (and the delimiting colon) can be omitted, so `-a 192.168.8.5` works as well. + +The netmask in CIDR notation can optionally be appended to the address, e.g. `-a 192.168.8.5/24` for netmask `255.255.255.0` which also is the default should the netmask not be provided. + +### Auto IP Address + +If `-a` is omitted, the supernode assigns an IP address to the node. This feature uses different IP address pools on a per-community basis. So, all edges of the same community will find themselves in the same sub-network. + +By default, `/24`-sized IP address sub-network pools from the upper half of the `10.0.0.0` class A network will be used, that is from `10.128.0.0/24` … `10.255.255.0/24`. The supernode can be configured to assign addresses from a different network range: `-a 10.0.0.0-10.255.0.0/16` would the supernode make use of the complete `10.0.0.0` class A range but handle `/16`-sized sub-networks. Also, named communities could be pre-assigned certain sub-networks, please see the explanatory comments in the `community.list` file. + +### DHCP + +If an edge of the community runs a DHCP server, the others could draw their IP addresses from there. It requires the new edges to start-up with the `-r -a dhcp:0.0.0.0` parameters (literally). More details can be found [at this discussion](https://github.com/ntop/n2n/issues/629). + +### IPv6 + +n2n supports the carriage of IPv6 packets within the n2n tunnel. n2n does not +yet use IPv6 for transport between edges and supernodes. + +To make IPv6 carriage work you need to manually add IPv6 addresses to the TAP +interfaces at each end. There is currently no way to specify an IPv6 address on +the edge command line. + +For example, under Linux + +on hostA: +`[hostA] $ /sbin/ip -6 addr add fc00:abcd:1234::7/48 dev n2n0` + +on hostB: +`[hostB] $ /sbin/ip -6 addr add fc00:abcd:1234::6/48 dev n2n0` + +You may find it useful to make use of `tunctl` from the uml-utilities +package. `tunctl` allows you to bring up a TAP interface and configure addressing +prior to starting the edge. It also allows the edge to be restarted without the +interface closing (which would normally affect routing tables). + +Once the IPv6 addresses are configured and edge is started, IPv6 neighbor discovery +packets flow (get broadcast) and IPv6 entities self-arrange. Test your IPv6 +setup with `ping6` - the IPv6 ping command. + +## MTU + +The MTU of the VPN interface is set to a lower value (rather than the standard +value of 1500 bytes) to avoid excessive fragmentation of the datagram sent over the internet. +This is required because n2n adds additional headers to the packets received from +the VPN interface. The size of the final frame sent through the internet interface +must have a size lower or equal to the internet interface MTU (usually 1500 bytes). + +As a fragmentation example, suppose that a 3000 byte TCP segment should be sent through +the VPN. If the VPN interface MTU is set to 1500, the packet will be split into two +fragments of 1500 bytes each. However, n2n will add its headers to each fragment, so +each fragment becomes a 1540 byte packet. The internet interface MTU of 1500 bytes +will fragment each packet again in two further fragments, e.g. 1500 + 50 bytes, so a +total of 4 fragments will be sent over the internet. On the other hand, if the VPN interface +MTU was set to 1460 bytes, it would result in only 3 fragments sent as the initial segment of +3000 bytes would be split in 1460 + 1460 + 80 bytes without further fragmentation. + +IP packet fragmentation in general is something to avoid, as described in +http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-87-3.pdf. If possible, +the fragmentation should be moved to the TCP layer by a proper MSS value. +This can be forced by mangling the packet MSS, which is called "MSS clamping" (currently not +implemented in n2n). See https://github.com/gsliepen/tinc/blob/228a03aaa707a5fcced9dd5148a4bdb7e5ef025b/src/route.c#L386. + +The exact value to use as a clamp value, however, depends on the PMTU, which is the minimum +MTU of the path between two hosts. Knowing the PMTU is also useful for a sender in order to +avoid fragmentation at IP level. Trying to find the highest non-fragmenting MTU possible is useful since it allows to +maximize bandwidth. + +### PMTU Discovery Failures + +Most operating systems try to periodically discover the PMTU by using a PMTU discovery algorithm. +This involves setting the DF (don't fragment) flag on the IP packets. When a large IP packet exceeds +the MTU of a router in the path, an "ICMP Fragmentation Needed" message should be received, which will +help the OS along to tune the size of the next IP packets. However, some routers do not report such ICMP message, +which results in packets being silently dropped. The `tracepath` tool can be used to detect the PMTU. + +The main problem with this situation is that the actual PMTU is unknown, so an automatic +solution is not applicable. The user must manually specify a lower MTU for the VPN interface +in order to solve the issue. + +### n2n and MTU + +n2n shall work by default in different environments. For this reason, the following solution +has been provided: + +- PMTU discovery is disabled if possible (via the IP_MTU_DISCOVER socket option). This avoids + silently dropping an oversized packet due to the DF flag; however, it possibly increments fragmentation on the path. +- As explained above, a lower MTU is set on the VPN interface, thus removing excessive fragmentation on + the sender. +- A value of 1290 bytes is used instead of 1500 bytes as reference value for the internet interface MTU. + This essentially avoids fragmentation if the PMTU is greater or equal than 1400 bytes. + +This is a conservative solution which should make n2n work by default. The user can manually +specify the MTU (`-M `) and re-enable PMTU discovery (`-D`) via the command-line interface options. + +## Interface Metric and Broadcasts + +On Windows, broadcasts are sent out to the network interface with the lowest metric only. This usually is the +WAN interface with its default metric of `25`. The `-x ` option could be used to configure the TAP with a +lower interface metric and hence facilitate service and online game server detection over n2n. + +Linux and others do not require this feature as broadcasts are sent to all network interfaces by default, also to the +virtual ones. + +## Multicast + +n2n does not transmit multicast packets by default. It can be enabled by edge's `-E` command-line parameter. + +## Egde Description + +To keep edge's and supernode's management port output well arranged and understandable, each edge can have a plain text description +fed to the edge by the optional `-I ` command-line parameter. If not provided, n2n uses the +hostname by default. + +A description field's hash value is used to choose an auto IP address. So, just be aware that changing the hostname +can lead to assigning a different auto IP address on next edge start-up – if auto IP address is used. + +## Routing + +n2n supports routing the traffic through its network. `-r` enables an edge to accept packets at its TAP interface not originating from the local IP address or not destined to the local IP address. As there is more to routing than just this one command-line option, please refer to the dedicated [Routing](Routing.md) document +explaining it all in detail. + +## Traffic Filter + +Setting up the integrated traffic filter permits to define exactly the kind of allowed traffic or deny +other on edge's TAP interface. It helps to keep unwanted traffic out of the n2n network for +bandwidth and security reasons. The traffic filter is disabled by default and gets activated by providing +as many `-R `-rules as required through edge's command-line. Specifics are written down in the +[Traffic Restrictions](TrafficRestricitons.md) documentation. diff --git a/bundles/n2n_ntop_v3/doc/TrafficRestrictions.md b/bundles/n2n_ntop_v3/doc/TrafficRestrictions.md new file mode 100644 index 00000000..8d6441ae --- /dev/null +++ b/bundles/n2n_ntop_v3/doc/TrafficRestrictions.md @@ -0,0 +1,41 @@ +# Traffic Restrictions + +It is possible to drop or accept specific packet transmit over edge network interface by rules. Rules can be specify by (`-R rule_str`) multiple times. + +## Rule String Format + +rule_str format: `src_ip/len:[b_port,e_port],dst_ip/len:[s_port,e_port],TCP+/-,UDP+/-,ICMP+/-` + +`ip/len` indicate a cidr block, len can be ignore, means single ip (not cidr block) will be use in filter rule. + +`+`,`-` after `TCP`,`UDP`,`ICMP` proto type indicate allow or drop packet of that proto. if any of above three proto missed, the rule will not take effect for that proto. + +Ports range `[s_port,e_port]` can be instead by single port number. If not specify, `[0,65535]` will be used. Ports range include start_port and end_port. + +examples: +`192.168.1.5/32:[0,65535],192.168.0.0/24:[8081,65535],TCP-,UDP-,ICMP+` +`192.168.1.5:[0,65535],192.168.0.0/24:8000,ICMP+` +`192.168.1.5,192.168.0.7,TCP-,UDP-,ICMP-` // packets by all proto of all ports from 192.158.1.5 to any ports of 192.168.0.7 will be dropped. + +## Multiple Rules + +`-R rule_str` can be used multiple times to add multiple rules. Each `-R rule_str` add one rule. for example: + +`edge -c xxxx -k xxxx -a 192.168.100.5 -l xxx.xxx.xxx.xxx:1234 -r -R 192.168.1.5/32:[0,65535],192.168.0.0/24:[8081,65535],TCP-,UDP-,ICMP+ -R 192.168.1.5:[0,65535],192.168.0.0/24:8000,ICMP+ -R 192.168.1.5,192.168.0.7,TCP-` + +## Matching Rules Priority + +If multiple rules matching packet's ips and ports, the rule with smaller cidr block(smaller address space) will be selected. That means rules with larger `len` value has higher priority. + +Actually, current implementation will add the `len` of src cidr and dst cidr of each matched rules as priority value, the rule with largest priority value will take effect. + +## Blocklist/Allowlist mode + +Packets that cannot match any rule will be accepted by default. Users can add rules to block traffics. + +This behavior can be change by add the rule : `0.0.0.0/0:[0,65535],0.0.0.0/0:[0,65535],TCP-,UDP-,ICMP-`. Then all traffic will be dropped, users need add rules to allow traffics. + +for example, `-R 0.0.0.0/0,0.0.0.0/0,TCP-,UDP-,ICMP- -R 192.168.100.0/24,192.168.100.0/24,ICMP+` dropped all traffic, except ICMP traffics inside `192.168.100.0/24`. + +More complex behavior can be set with the feature of `Matching Rules Priority`. + diff --git a/bundles/n2n_ntop_v3/edge.8 b/bundles/n2n_ntop_v3/edge.8 new file mode 100644 index 00000000..529fd6fb --- /dev/null +++ b/bundles/n2n_ntop_v3/edge.8 @@ -0,0 +1,285 @@ +.TH edge 8 "18 Jul 2021" "version 3" "SUPERUSER COMMANDS" +.SH NAME +edge \- n2n edge node daemon +.SH SYNOPSIS +.B edge + +.br +.B edge +\-c \-l [further options]... +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Edge is the edge node daemon for n2n which +creates a TAP interface to expose the n2n virtual LAN. On startup n2n creates +the TAP interface and configures it then registers with the supernode so it can +begin to find other nodes in the community. +.PP +The config file is similar to the command line, with one option per line. +Lines starting with a "#" are ignored. +An equal sign ('=') should be used between key and value. Example: -p=7777 +.SH OPTIONS FOR THE UNDERLYING NETWORK CONNECTION +.TP +\fB\-c \fR<\fIcommunity\fR>, \fB\-\-community\fR=<\fIcommunity\fR> +sets the n2n community name (see also N2N_COMMUNITY in ENVIRONMENT). All edges +within the same community appear on the same LAN (layer 2 network segment). +Community name is 16 bytes in length. A name smaller than this is padded with +0x00 bytes and a name longer than this is truncated to take the first 16 bytes. +.TP +\fB\-l \fR<\fIhost:port\fR>, \fB\-\-supernode-list\fR=<\fIhost:port\fR> +sets the n2n supernode IP address and port to register to. Multiple supernodes +can be specified. +.TP +\fB\-p \fR[<\fIlocal_ip_address\fR>:]<\fIlocal_port\fR> +binds edge to the given UDP port. Useful for keeping the same external socket +across restarts of edge. This allows peer edges which know the edge socket to +continue p2p operation without going back to the supernode. Also, home router's +port forwarding feature can refer to that fixed port. +Optionally, the edge can bind to the provided local ip address only. This is +useful in case restriction to a certain LAN or WiFi interface is desired. +By default, the edge binds to any interface. +.TP +\fB\-T \fR<\fItos\fR> +TOS for packets, e.g. 0x48 for SSH like priority +.TP +\fB\-D\fR +enable PMTU discovery, it can reduce fragmentation but +causes connections to stall if not properly supported +.TP +\fB\-e \fR<\fIlocal_ip_address\fR> +advertises the provided local IP address as preferred, +useful if multicast peer detection is not available, e.g. +disabled on routers. \fB\-e auto\fR tries auto-detection of +local IP address. +.TP +\fB\-S1\fR ... \fB\-S2\fR +do not connect p2p, always use the supernode, +\-S1 = via UDP, \-S2 = via TCP +.TP +\fB\-i \fR<\fIreg_interval\fR> +Supernode registration interval. It specifies the interval in seconds +between consecutive REGISTER_SUPER packets and it's used to keep NAT hole +open via the UDP NAT hole punching technique. This only works for asymmetric +NATs and allows for P2P communication. +.TP +\fB\-L \fR<\fIreg_ttl\fR> +set the TTL for the hole punching packet. This is an advanced flag to make +sure that the registration packet is dropped immediately when it goes out of +local nat so that it will not trigger some firewall behavior on target peer. +Actually, the registration packet is only expected to make local nat UDP hole +and is not expected to reach the target peer, see +https://tools.ietf.org/html/rfc5389. To achieve this, the flag should be set as +nat level + 1. For example, if we have 2 layer nat in local, we should set -L 3. +Usually we know exactly how much nat layers in local. +If we are not sure how much nat layers in local, we can use traceroute on +Linux to check. The following example shows a local single layer nat because on +second jump it shows a public ip address. In this case it should set -L 2. + +$ /usr/sbin/traceroute -w1 8.8.8.8 +.br +traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets + 1 192.168.3.1 (192.168.3.1) 0.464 ms 0.587 ms 0.719 ms + 2 112.65.17.217 (112.65.17.217) 5.269 ms 7.031 ms 8.666 ms + +But this method does not always work due to various local network device policy. +.TP +\fB\-k \fR<\fIkey\fR> +encryption key (ASCII) - also N2N_KEY= +\-k +sets the encryption key from ASCII text (see also N2N_KEY in +ENVIRONMENT). All edges communicating must use the same key and community +name. If -k not specified then edge uses cleartext mode (no encryption). +.TP +\fB\-A1\fR +disable payload encryption, do not use with key, defaults to AES then +.TP +\fB\-A2\fR ... \fB\-A5\fR +choose a cipher for payload encryption, requires a key, +\-A2 = Twofish, \-A3 = AES (default if key provided), +\-A4 = ChaCha20, \-A5 = Speck-CTR +.TP +\fB\-H\fR +use header encryption, supernode needs fixed community +.TP +\fB\-z1\fR ... \fB\-z2\fR +compress outgoing data packets, -z1 = lzo1x, disabled by default +.TP +\fB\-\-select-rtt\fR +select supernode by round trip time if several to choose from (federation), +defaults to load-based selection strategy if not provided. +.TP +\fB\-\-select-mac\fR +select supernode by MAC address if several to choose from (federation), +lowest MAC address first. +.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION +.TP +\fB\-a \fR[\fImode\fR]<\fIip\fR>[\fI/n\fR] +interface address and optional CIDR subnet, default '/24', +mode = [static|dhcp]:, for DHCP use '\-r -a dhcp:0.0.0.0', +edge draws IP address from supernode if no '\-a ...' given +.TP +\fB\-m \fR<\fImac\fR> +start the TAP interface with the given MAC address. This is highly recommended +as it means the same address will be used if edge stops and restarts. If this is +not done, the ARP caches of all peers will be wrong and packets will not flow to +this edge until the next ARP refresh. +e.g. '\-m 10:20:30:40:50:60', by default a random MAC address is used. +.TP +\fB\-d \fR<\fIdevice\fR>, \fB\-\-device\fR=<\fIdevice\fR> +TAP device name +.TP +\fB\-M \fR<\fImtu\fR> +specify n2n MTU of TAP interface, default 1290 +.TP +\fB\-r\fR +enable IP packet forwarding/routing through the n2n virtual LAN. Without this +option, IP packets arriving over n2n are dropped if not for the -a (or +DHCP assigned) IP address of the edge interface. +.TP +\fB\-E\fR +accept packets destined for multicast ethernet MAC addresses. These addresses +are used in multicast ethernet and IPv6 neighbour discovery. If this option is +not present these multicast packets are discarded as most users do not need or +understand them. +.TP +\fB\-I \fR<\fIdescription\fR> +annotate the edge's description used for easier +identification in management port output or username +.TP +\fB\-J \fR<\fIpassword\fR> +password for user-password edge authentication (see also N2N_PASSWORD in ENVIRONMENT) +.TP +\fB\-P \fR<\fIpublic key\fR> +federation public key for user-password authentication +.TP +\fB\-R \fR<\fIrule_str\fR> +Add rule to drop or accept specific packet transmit over edge network interface. +-R rule_str can be used multiple times to add multiple rules. Each -R rule_str add +one rule. + +rule_str format:"src_ip/len:[b_port,e_port],dst_ip/len:[s_port,e_port],TCP+/-,UDP+/-,ICMP+/-". + +ip/len indicate a cidr block, len can be ignore, means single ip(not cidr block) +will be use in filter rule. + ++,- after TCP,UDP,ICMP proto type indicate allow or drop packet of that proto. +if any of above three proto missed, the rule will not take effect for that proto. + +Ports range [s_port,e_port] can be instead by single port number. If not specify, [0,65535] +will be used. Ports range include start_port and end_port. If multiple rules matching packet's +ips and ports, the rule with smaller cidr block(smaller address space) will be selected. That +means rules with larger len value has higher priority. + +Packets that cannot match any rule will be accepted by default. Users can add rules to +block traffics. This behavior can be change by add the rule : `0.0.0.0/0:[0,65535],0.0.0.0/0: +[0,65535],TCP-,UDP-,ICMP-`. Then all traffic will be dropped, users need add rules to allow +traffics. + +for example : `-R 0.0.0.0/0,0.0.0.0/0,TCP-,UDP-,ICMP- -R 192.168.100.0/24,192.168.100.0/24,ICMP+`, +.TP +\fB\-x \fR<\fImetric\fR> +set TAP interface metric, defaults to 0 (auto), +e.g. set to 1 for better multiplayer game detection. +.br +(Windows only) +.SH LOCAL OPTIONS +.TP +\fB\-f\fR +do not fork and run as a daemon, rather run in foreground +.TP +\fB\-t \fR<\fIport\fR> +binds the edge management system to the given UDP port. Default 5644. Use this +if you need to run multiple instance of edge; or something is bound to that +port. +.TP +\fB\-\-management-password \fR<\fIpassword\fR> +sets the password for access to JSON API at the management port, defaults to 'n2n'. The password +has to be provided when using 'scripts/n2n-ctl', 'scripts/n2n-httpd' or for any other relevant +access to JSON API at the management port. +.TP +\fB\-v\fR, \fB\-\-verbose\fR +make more verbose, repeat as required +.TP +\fB\-n \fR<\fIcidr:gateway\fR> +route an IPv4 network via the gateway, use 0.0.0.0/0 for +the default gateway, can be set multiple times +.TP +\fB\-u \fR<\fIUID\fR>, \fB\-\-euid\fR=<\fIUID\fR> +numeric user ID to use when privileges are dropped +.TP +\fB\-g \fR<\fIGID\fR>, \fB\-\-egid\fR=<\fIGID\fR> +numeric group ID to use when privileges are dropped +.TP +\fb\-h\fr +write usage then exit. +.TP +\fb\--help\fr +shows detailed parameter description +.SH ENVIRONMENT +.TP +.B N2N_KEY +set the encryption key so it is not visible at the command line +.TP +.B N2N_COMMUNITY +set the community name so it is not visible at the command line +.TP +.B N2N_PASSWORD +set the password for user-password authentication so it is not visible at the command line +.SH EXAMPLES +.TP +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:23 \-a 192.168.254.7 \-p 50001 \-l 123.121.120.119:7654 + +Start edge with TAP device n2n0 on community "mynetwork" with community +supernode at 123.121.120.119 UDP port 7654 and bind the locally used UDP port to +50001. Use "encryptme" as the single permanent shared encryption key. Assign MAC +address DE:AD:BE:EF:01:23 to the n2n interface and drop to user=99 and group=99 +after the TAP device is successfully configured. +.PP +Add the -f option to stop edge running as a daemon. +.PP +Somewhere else setup another edge with similar parameters, eg. + +.B edge \-d n2n0 \-c mynetwork \-k encryptme \-u 99 \-g 99 \-m DE:AD:BE:EF:01:21 \-a 192.168.254.5 \-p 50001 \-l 123.121.120.119:7654 +.PP +Now you can ping from 192.168.254.5 to 192.168.254.7. +.PP +The MAC address (-m ) and virtual IP address (-a ) must be different +on all edges in the same community. + +.SH CLEARTEXT MODE +If +.B -k +is not specified then edge uses cleartext mode. In cleartext mode there is no +transform of the packet data it is simply encrypted. This is useful for +debugging n2n as packet contents can be seen clearly. + +To prevent accidental exposure of data, edge only enters cleartext mode when no +keying parameters are specified. In the case where keying parameters are +specified but no valid keys can be determined, edge exits with an error at +startup. If all keys become invalid while running, edge continues to encode +using the last key that was valid. + +.SH MANAGEMENT INTERFACE +Edge provides a very simple management system on UDP port 5644. Send a newline +to receive a status output. Send 'stop' to cause edge to exit cleanly. + +.TP +.B echo | nc -w1 -u 127.0.0.1 5644 +Shows the current statistics of a running edge. + +.SH EXIT STATUS +edge is a daemon and any exit is an error. +.SH AUTHORS +.TP +Richard Andrews +andrews (at) ntop.org - n2n-1 maintainer and main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - original author of n2n +.TP +Don Bindner +(--) - significant contributions to n2n-1 +.SH SEE ALSO +ifconfig(8) supernode(1) tunctl(8) n2n(7) +.br +the documentation contained in the source code +.br +the extensive documentation found in n2n's \fBdoc/\fR folder diff --git a/bundles/n2n_ntop_v3/include/aes.h b/bundles/n2n_ntop_v3/include/aes.h new file mode 100644 index 00000000..a43997ed --- /dev/null +++ b/bundles/n2n_ntop_v3/include/aes.h @@ -0,0 +1,88 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" // HAVE_OPENSSL_1_1, traceEvent ... + + +#ifndef AES_H +#define AES_H + + +#include +#include + +#include "portable_endian.h" + +#define AES_BLOCK_SIZE 16 +#define AES_IV_SIZE (AES_BLOCK_SIZE) + +#define AES256_KEY_BYTES (256/8) +#define AES192_KEY_BYTES (192/8) +#define AES128_KEY_BYTES (128/8) + + +#if defined (HAVE_OPENSSL_1_1) // openSSL 1.1 --------------------------------------------------------------------- + +#include +#include +#include + +typedef struct aes_context_t { + EVP_CIPHER_CTX *enc_ctx; /* openssl's reusable evp_* en/de-cryption context */ + EVP_CIPHER_CTX *dec_ctx; /* openssl's reusable evp_* en/de-cryption context */ + const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_aes_128_cbc */ + uint8_t key[AES256_KEY_BYTES]; /* the pure key data for payload encryption & decryption */ + AES_KEY ecb_dec_key; /* one step ecb decryption key */ +} aes_context_t; + +#elif defined (__AES__) && defined (__SSE2__) // Intel's AES-NI --------------------------------------------------- + +#include + +typedef struct aes_context_t { + __m128i rk_enc[15]; + __m128i rk_dec[15]; + int Nr; +} aes_context_t; + +#else // plain C -------------------------------------------------------------------------------------------------- + +typedef struct aes_context_t { + uint32_t enc_rk[60]; // round keys for encryption + uint32_t dec_rk[60]; // round keys for decryption + int Nr; // number of rounds +} aes_context_t; + +#endif // --------------------------------------------------------------------------------------------------------- + + +int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx); + +int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx); + +int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx); + +int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx); + +int aes_deinit (aes_context_t *ctx); + + +#endif // AES_H diff --git a/bundles/n2n_ntop_v3/include/auth.h b/bundles/n2n_ntop_v3/include/auth.h new file mode 100644 index 00000000..43bc5882 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/auth.h @@ -0,0 +1,43 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + + +#include "n2n.h" + + +#ifndef AUTH_H +#define AUTH_H + + +int bin_to_ascii (char *out, uint8_t *in, size_t in_len); + +int ascii_to_bin (uint8_t *out, char *in); + +int generate_private_key (n2n_private_public_key_t key, char *in); + +int generate_public_key (n2n_private_public_key_t pub, n2n_private_public_key_t prv); + +int generate_shared_secret (n2n_private_public_key_t shared, n2n_private_public_key_t prv, n2n_private_public_key_t pub); + +int bind_private_key_to_username (n2n_private_public_key_t prv, char *username); + +int calculate_dynamic_key (uint8_t out_key[N2N_AUTH_CHALLENGE_SIZE], + uint32_t key_time, n2n_community_t comm, n2n_community_t fed); + + +#endif diff --git a/bundles/n2n_ntop_v3/include/cc20.h b/bundles/n2n_ntop_v3/include/cc20.h new file mode 100644 index 00000000..1030d517 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/cc20.h @@ -0,0 +1,78 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#ifndef CC20_H +#define CC20_H + + +#include + +#include "n2n.h" // HAVE_OPENSSL_1_1, traceEvent ... + + +#define CC20_IV_SIZE 16 +#define CC20_KEY_BYTES (256/8) + + +#ifdef HAVE_OPENSSL_1_1 // openSSL 1.1 ---------------------------------------------------------------------------- + + +#include +#include + +typedef struct cc20_context_t { + EVP_CIPHER_CTX *ctx; /* openssl's reusable evp_* en/de-cryption context */ + const EVP_CIPHER *cipher; /* cipher to use: e.g. EVP_chacha20() */ + uint8_t key[CC20_KEY_BYTES]; /* the pure key data for payload encryption & decryption */ +} cc20_context_t; + + +#elif defined (__SSE2__) // SSE2 --------------------------------------------------------------------------------- + + +#include + +typedef struct cc20_context { + uint32_t keystream32[16]; + uint8_t key[CC20_KEY_BYTES]; +} cc20_context_t; + + +#else // plain C -------------------------------------------------------------------------------------------------- + + +typedef struct cc20_context { + uint32_t keystream32[16]; + uint32_t state[16]; + uint8_t key[CC20_KEY_BYTES]; +} cc20_context_t; + + +#endif // openSSL 1.1, plain C ------------------------------------------------------------------------------------ + + +int cc20_crypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, cc20_context_t *ctx); + +int cc20_init (const unsigned char *key, cc20_context_t **ctx); + +int cc20_deinit (cc20_context_t *ctx); + + +#endif // CC20_H diff --git a/bundles/n2n_ntop_v3/include/curve25519.h b/bundles/n2n_ntop_v3/include/curve25519.h new file mode 100644 index 00000000..96acaafe --- /dev/null +++ b/bundles/n2n_ntop_v3/include/curve25519.h @@ -0,0 +1,20 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +void curve25519 (unsigned char *q, const unsigned char *n, const unsigned char *p); diff --git a/bundles/n2n_ntop_v3/include/edge_utils_win32.h b/bundles/n2n_ntop_v3/include/edge_utils_win32.h new file mode 100644 index 00000000..52720f76 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/edge_utils_win32.h @@ -0,0 +1,52 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _EDGE_UTILS_WIN32_H_ +#define _EDGE_UTILS_WIN32_H_ + +#ifdef WIN32 + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include + + +/* Multicast peers discovery disabled due to https://github.com/ntop/n2n/issues/65 */ + +/* Currently, multicast is performed by specifying the default routing network adapter. + * If the solution is determined to be stable and effective, + * all macro definitions "SKIP_MULTICAST_PEERS_DISCOVERY" will be completely deleted in the future. + */ +//#define SKIP_MULTICAST_PEERS_DISCOVERY + +// TODO: this struct is pretty empty now, collapse it to just n2n_edge_t ? +struct tunread_arg { + n2n_edge_t *eee; +}; + +extern HANDLE startTunReadThread (struct tunread_arg *arg); +int get_best_interface_ip (n2n_edge_t * eee, dec_ip_str_t ip_addr); + + +#endif /* WIN32 */ + +#endif /* _EDGE_UTILS_WIN32_H_ */ + diff --git a/bundles/n2n_ntop_v3/include/header_encryption.h b/bundles/n2n_ntop_v3/include/header_encryption.h new file mode 100644 index 00000000..b12d858b --- /dev/null +++ b/bundles/n2n_ntop_v3/include/header_encryption.h @@ -0,0 +1,35 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +int packet_header_decrypt (uint8_t packet[], uint16_t packet_len, + char *community_name, + he_context_t *ctx, he_context_t *ctx_iv, + uint64_t *stamp); + +int packet_header_encrypt (uint8_t packet[], uint16_t header_len, uint16_t packet_len, + he_context_t *ctx, he_context_t *ctx_iv, + uint64_t stamp); + +void packet_header_setup_key (const char *community_name, + he_context_t **ctx_static, he_context_t **ctx_dynamic, + he_context_t **ctx_iv_static, he_context_t **ctx_iv_dynamic); + +void packet_header_change_dynamic_key (uint8_t *key_dynamic, + he_context_t **ctx_dynamic, + he_context_t **ctx_iv_dynamic); diff --git a/bundles/n2n_ntop_v3/include/hexdump.h b/bundles/n2n_ntop_v3/include/hexdump.h new file mode 100644 index 00000000..4480319a --- /dev/null +++ b/bundles/n2n_ntop_v3/include/hexdump.h @@ -0,0 +1,6 @@ +#ifndef HEXDUMP_H +#define HEXDUMP_H + +void fhexdump(unsigned int display_addr, void *in, int size, FILE *stream); + +#endif diff --git a/bundles/n2n_ntop_v3/include/lzoconf.h b/bundles/n2n_ntop_v3/include/lzoconf.h new file mode 100644 index 00000000..f9a8bdbe --- /dev/null +++ b/bundles/n2n_ntop_v3/include/lzoconf.h @@ -0,0 +1,453 @@ +/* lzoconf.h -- configuration of the LZO data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED 1 + +#define LZO_VERSION 0x20a0 /* 2.10 */ +#define LZO_VERSION_STRING "2.10" +#define LZO_VERSION_DATE "Mar 01 2017" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint must match size_t */ +#if !defined(LZO_UINT_MAX) +# if (LZO_ABI_LLP64) +# if (LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF___INT64 +# else + typedef lzo_ullong_t lzo_uint; + typedef lzo_llong_t lzo_int; +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG_LONG +# endif +# define LZO_SIZEOF_LZO_INT 8 +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif (LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_INT +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32_t. */ +#if (LZO_SIZEOF_LZO_INT >= 4) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32_t +#endif + +typedef int lzo_bool; + +/* sanity checks */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int) == LZO_SIZEOF_LZO_INT) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_INT) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t)) + +#ifndef __LZO_MMODEL +#define __LZO_MMODEL /*empty*/ +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * + +#define lzo_int8_tp lzo_int8_t __LZO_MMODEL * +#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL * +#define lzo_int16_tp lzo_int16_t __LZO_MMODEL * +#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL * +#define lzo_int32_tp lzo_int32_t __LZO_MMODEL * +#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL * +#if defined(lzo_int64_t) +#define lzo_int64_tp lzo_int64_t __LZO_MMODEL * +#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL * +#endif + +/* Older LZO versions used to support ancient systems and memory models + * such as 16-bit MSDOS with __huge pointers or Cray PVP, but these + * obsolete configurations are not supported any longer. + */ +#if defined(__LZO_MMODEL_HUGE) +#error "__LZO_MMODEL_HUGE memory model is unsupported" +#endif +#if (LZO_MM_PVP) +#error "LZO_MM_PVP memory model is unsupported" +#endif +#if (LZO_SIZEOF_INT < 4) +#error "LZO_SIZEOF_INT < 4 is unsupported" +#endif +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4) +/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should + * work but have not received much testing lately, so be strict here. + */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep)) + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 /*empty*/ +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 /*empty*/ +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(r) static r __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* INFO: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ +#define LZO_E_INVALID_ARGUMENT (-10) +#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */ +#define LZO_E_OUTPUT_NOT_CONSUMED (-12) +#define LZO_E_INTERNAL_ERROR (-99) + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) + lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memset(lzo_voidp buf, int c, lzo_uint len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32_t) + lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(lzo_uint32_t) + lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(const lzo_uint32_tp) + lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { + lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04; + void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09; +#if defined(lzo_int64_t) + lzo_uint64_t a10; +#endif +} lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of 'size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); +#define LZO_PTR_ALIGN_UP(p,size) \ + ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility +************************************************************************/ + +/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ +#define lzo_byte unsigned char +/* deprecated type names */ +#define lzo_int32 lzo_int32_t +#define lzo_uint32 lzo_uint32_t +#define lzo_int32p lzo_int32_t __LZO_MMODEL * +#define lzo_uint32p lzo_uint32_t __LZO_MMODEL * +#define LZO_INT32_MAX LZO_INT32_C(2147483647) +#define LZO_UINT32_MAX LZO_UINT32_C(4294967295) +#if defined(lzo_int64_t) +#define lzo_int64 lzo_int64_t +#define lzo_uint64 lzo_uint64_t +#define lzo_int64p lzo_int64_t __LZO_MMODEL * +#define lzo_uint64p lzo_uint64_t __LZO_MMODEL * +#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807) +#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615) +#endif +/* deprecated types */ +typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u; +typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u; +/* deprecated defines */ +#if !defined(LZO_SIZEOF_LZO_UINT) +# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LZO_INT +#endif + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL /*empty*/ +#define __LZO_DMODEL /*empty*/ +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 sw=4 et: */ diff --git a/bundles/n2n_ntop_v3/include/lzodefs.h b/bundles/n2n_ntop_v3/include/lzodefs.h new file mode 100644 index 00000000..c3e2bcf5 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/lzodefs.h @@ -0,0 +1,3268 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if 0 +#elif !defined(__LZO_LANG_OVERRIDE) +#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) +# if (__ASSEMBLER__+0) <= 0 +# error "__ASSEMBLER__" +# else +# define LZO_LANG_ASSEMBLER 1 +# endif +#elif defined(__cplusplus) +# if (__cplusplus+0) <= 0 +# error "__cplusplus" +# elif (__cplusplus < 199711L) +# define LZO_LANG_CXX 1 +# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 +# define LZO_LANG_CXX _MSVC_LANG +# else +# define LZO_LANG_CXX __cplusplus +# endif +# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) +# define LZO_LANG_C __STDC_VERSION__ +# else +# define LZO_LANG_C 1 +# endif +#endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(_MSC_VER) && defined(M_I86HM) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# define LZO_CC_CLANG_C2 _MSC_VER +# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 +# define LZO_INFO_CC "clang/c2" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# if defined(__APPLE_CC__) +# define LZO_CC_CLANG_VENDOR_APPLE 1 +# define LZO_INFO_CC "clang/apple" +# else +# define LZO_CC_CLANG_VENDOR_LLVM 1 +# define LZO_INFO_CC "clang" +# endif +# if defined(__clang_version__) +# define LZO_INFO_CCVER __clang_version__ +# else +# define LZO_INFO_CCVER __VERSION__ +# endif +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) || defined(_M_ARM64) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__riscv) +# define LZO_ARCH_RISCV 1 +# define LZO_INFO_ARCH "riscv" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if !defined(LZO_ARCH_ARM_THUMB2) +#if (LZO_ARCH_ARM) +# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) +# if defined(__thumb2__) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) +# define LZO_ARCH_ARM_THUMB2 1 +# endif +# endif +#endif +#endif +#if (LZO_ARCH_ARM_THUMB2) +# undef LZO_INFO_ARCH +# define LZO_INFO_ARCH "arm_thumb2" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON) && ((__ARM_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(__cplusplus) +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#if defined(__cplusplus) +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin +#endif +#endif +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 +#endif +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute +#endif +#endif +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 +#endif +#if !defined(lzo_has_declspec_attribute) +#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) +# define lzo_has_declspec_attribute __has_declspec_attribute +#endif +#endif +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 +#endif +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature +#endif +#endif +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 +#endif +#if !defined(lzo_has_extension) +#if (LZO_CC_CLANG) && defined(__has_extension) +# define lzo_has_extension __has_extension +#elif (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_extension __has_feature +#endif +#endif +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_RESULT) +# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_very_likely) +# ifndef __lzo_HAVE_very_likely +# define __lzo_HAVE_very_likely 1 +# endif +#else +# define __lzo_very_likely(e) __lzo_likely(e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if defined(__lzo_very_unlikely) +# ifndef __lzo_HAVE_very_unlikely +# define __lzo_HAVE_very_unlikely 1 +# endif +#else +# define __lzo_very_unlikely(e) __lzo_unlikely(e) +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#if !defined(lzo_unused_funcs_impl) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f +# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) +# define lzo_unused_funcs_impl(r,f) static r f +# else +# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +#if (LZO_LANG_ASSEMBLER) +# undef LZO_COMPILE_TIME_ASSERT_HEADER +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ +#else +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#define LZO_SIZEOF_CHAR 1 +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_ARM64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# else +# define LZO_SIZEOF_VOID_P 4 +# endif +# else + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) +# define LZO_ABI_IP32W64 1 +# ifndef LZO_INFO_ABI_PM +# define LZO_INFO_ABI_PM "ip32w64" +# endif +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# if ((__ARM_FEATURE_UNALIGNED)+0) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +# elif 1 && (LZO_ARCH_ARM_THUMB2) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_RISCV) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#define LZO_TYPEOF_CHAR 1u +#define LZO_TYPEOF_SHORT 2u +#define LZO_TYPEOF_INT 3u +#define LZO_TYPEOF_LONG 4u +#define LZO_TYPEOF_LONG_LONG 5u +#define LZO_TYPEOF___INT8 17u +#define LZO_TYPEOF___INT16 18u +#define LZO_TYPEOF___INT32 19u +#define LZO_TYPEOF___INT64 20u +#define LZO_TYPEOF___INT128 21u +#define LZO_TYPEOF___INT256 22u +#define LZO_TYPEOF___MODE_QI 33u +#define LZO_TYPEOF___MODE_HI 34u +#define LZO_TYPEOF___MODE_SI 35u +#define LZO_TYPEOF___MODE_DI 36u +#define LZO_TYPEOF___MODE_TI 37u +#define LZO_TYPEOF_CHAR_P 129u +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +# if !(LZO_LANG_ASSEMBLER) + __lzo_gnuc_extension__ typedef long long lzo_llong_t__; + __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# endif +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T +#endif +#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# endif +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T +#endif +#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) +# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 +# endif +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +#else +#endif +#endif +#if defined(lzo_int64e_t) +# define LZO_SIZEOF_LZO_INT64E_T 8 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 +# if !(LZO_LANG_ASSEMBLER) + typedef char * lzo_intptr_t; + typedef char * lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) +# if !(LZO_LANG_ASSEMBLER) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 +# if !(LZO_LANG_ASSEMBLER) + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# endif +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif /* already included */ + +/* vim:set ts=4 sw=4 et: */ diff --git a/bundles/n2n_ntop_v3/include/minilzo.h b/bundles/n2n_ntop_v3/include/minilzo.h new file mode 100644 index 00000000..c1c22975 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/minilzo.h @@ -0,0 +1,106 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H_INCLUDED +#define __MINILZO_H_INCLUDED 1 + +#define MINILZO_VERSION 0x20a0 /* 2.10 */ + +#if defined(__LZOCONF_H_INCLUDED) +# error "you cannot use both LZO and miniLZO" +#endif + +/* internal Autoconf configuration file - only used when building miniLZO */ +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include + +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 sw=4 et: */ diff --git a/bundles/n2n_ntop_v3/include/n2n.h b/bundles/n2n_ntop_v3/include/n2n.h new file mode 100644 index 00000000..046ef492 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/n2n.h @@ -0,0 +1,284 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _N2N_H_ +#define _N2N_H_ + +/* + tunctl -t tun0 + tunctl -t tun1 + ifconfig tun0 1.2.3.4 up + ifconfig tun1 1.2.3.5 up + ./edge -d tun0 -l 2000 -r 127.0.0.1:3000 -c hello + ./edge -d tun1 -l 3000 -r 127.0.0.1:2000 -c hello + + + tunctl -u UID -t tunX +*/ + +#define N2N_HAVE_DAEMON /* needs to be defined before it gets undefined */ +#define N2N_HAVE_TCP /* needs to be defined before it gets undefined */ + +/* #define N2N_CAN_NAME_IFACE */ + +/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */ +#ifdef WIN32 +#ifndef CMAKE_BUILD +#include "config.h" /* Visual C++ */ +#else +#include "winconfig.h" +#endif +#define N2N_CAN_NAME_IFACE 1 +#undef N2N_HAVE_DAEMON +#undef N2N_HAVE_TCP /* as explained on https://github.com/ntop/n2n/pull/627#issuecomment-782093706 */ +#undef N2N_HAVE_SETUID +#else +#ifndef CMAKE_BUILD +#include "config.h" +#endif +#endif + + + +#define PACKAGE_BUILDDATE (__DATE__ " " __TIME__) + +#include +#include +#include + +#ifndef WIN32 +#include +#endif + +#ifndef _MSC_VER +#include +#endif /* #ifndef _MSC_VER */ + +#include +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#include + +#ifdef __linux__ +#define N2N_CAN_NAME_IFACE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* #ifdef __linux__ */ + +#ifdef __FreeBSD__ +#include +#endif /* #ifdef __FreeBSD__ */ + +#include +#include + +#ifdef HAVE_LIBZSTD +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined (HAVE_OPENSSL_1_1) +#include +#include +#endif + +#define closesocket(a) close(a) +#endif /* #ifndef WIN32 */ + +#include "minilzo.h" +#include +#include +#include +#include "lzoconf.h" +#include "uthash.h" +#include "n2n_define.h" +#include "n2n_typedefs.h" + +#ifdef WIN32 +#include /* for tcp */ +#define SHUT_RDWR SD_BOTH /* for tcp */ +#include "wintap.h" +#include +#else +#include +#endif /* #ifdef WIN32 */ + +#include "n2n_wire.h" +#include "random_numbers.h" +#include "pearson.h" +#include "portable_endian.h" +#include "aes.h" +#include "cc20.h" +#include "speck.h" +#include "curve25519.h" +#include "n2n_regex.h" +#include "sn_selection.h" +#include "network_traffic_filter.h" +#include "auth.h" + +/* ************************************** */ + +#include "header_encryption.h" +#include "tf.h" + +#ifndef TRACE_ERROR +#define TRACE_ERROR 0, __FILE__, __LINE__ +#define TRACE_WARNING 1, __FILE__, __LINE__ +#define TRACE_NORMAL 2, __FILE__, __LINE__ +#define TRACE_INFO 3, __FILE__, __LINE__ +#define TRACE_DEBUG 4, __FILE__, __LINE__ +#endif + +/* ************************************** */ + +/* Transop Init Functions */ +int n2n_transop_null_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +int n2n_transop_tf_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +int n2n_transop_aes_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); +int n2n_transop_speck_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt); + +/* Log */ +void setTraceLevel (int level); +void setUseSyslog (int use_syslog); +void setTraceFile (FILE *f); +int getTraceLevel (); +void closeTraceFile (); +void traceEvent (int eventTraceLevel, char* file, int line, char * format, ...); + +/* Tuntap API */ +int tuntap_open (struct tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, + char *device_mask, const char * device_mac, int mtu +#ifdef WIN32 + , int metric +#endif + ); +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len); +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len); +void tuntap_close (struct tuntap_dev *tuntap); +void tuntap_get_address (struct tuntap_dev *tuntap); + +/* Utils */ +char* intoa (uint32_t addr, char* buf, uint16_t buf_len); +uint32_t bitlen2mask (uint8_t bitlen); +uint8_t mask2bitlen (uint32_t mask); +char* macaddr_str (macstr_t buf, const n2n_mac_t mac); +int str2mac (uint8_t * outmac /* 6 bytes */, const char * s); +int supernode2sock (n2n_sock_t * sn, const n2n_sn_name_t addrIn); +uint8_t is_multi_broadcast (const n2n_mac_t dest_mac); +uint8_t is_broadcast (const n2n_mac_t dest_mac); +uint8_t is_null_mac (const n2n_mac_t dest_mac); +char* msg_type2str (uint16_t msg_type); +void hexdump (const uint8_t * buf, size_t len); +void print_n2n_version (); +int is_empty_ip_address (const n2n_sock_t * sock); +void print_edge_stats (const n2n_edge_t *eee); +int memrnd (uint8_t *address, size_t len); +int memxor (uint8_t *destination, const uint8_t *source, size_t len); + +/* Sockets */ +char* sock_to_cstr (n2n_sock_str_t out, + const n2n_sock_t * sock); +char * ip_subnet_to_str (dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr); +SOCKET open_socket (int local_port, in_addr_t address, int type); +int sock_equal (const n2n_sock_t * a, + const n2n_sock_t * b); + +/* Header encryption */ +uint64_t time_stamp (void); +uint64_t initial_time_stamp (void); +int time_stamp_verify_and_update (uint64_t stamp, uint64_t * previous_stamp, int allow_jitter); + +/* Operations on peer_info lists. */ +size_t purge_peer_list (struct peer_info ** peer_list, + SOCKET socket_not_to_close, + n2n_tcp_connection_t **tcp_connections, + time_t purge_before); + +size_t clear_peer_list (struct peer_info ** peer_list); + +size_t purge_expired_nodes (struct peer_info **peer_list, + SOCKET socket_not_to_close, + n2n_tcp_connection_t **tcp_connections, + time_t *p_last_purge, + int frequency, int timeout); + +/* Edge conf */ +void edge_init_conf_defaults (n2n_edge_conf_t *conf); +int edge_verify_conf (const n2n_edge_conf_t *conf); +int edge_conf_add_supernode (n2n_edge_conf_t *conf, const char *ip_and_port); +const n2n_edge_conf_t* edge_get_conf (const n2n_edge_t *eee); +void edge_term_conf (n2n_edge_conf_t *conf); + +/* Public functions */ +n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv); +void update_supernode_reg (n2n_edge_t * eee, time_t nowTime); +void readFromIPSocket (n2n_edge_t * eee, int in_sock); +void edge_term (n2n_edge_t *eee); +void edge_set_callbacks (n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks); +void edge_set_userdata (n2n_edge_t *eee, void *user_data); +void* edge_get_userdata (n2n_edge_t *eee); +void edge_send_packet2net (n2n_edge_t *eee, uint8_t *tap_pkt, size_t len); +void edge_read_from_tap (n2n_edge_t *eee); +int edge_get_n2n_socket (n2n_edge_t *eee); +int edge_get_management_socket (n2n_edge_t *eee); +int run_edge_loop (n2n_edge_t *eee); +int quick_edge_init (char *device_name, char *community_name, + char *encrypt_key, char *device_mac, + char *local_ip_address, + char *supernode_ip_address_port, + int *keep_on_running); +int comm_init (struct sn_community *comm, char *cmn); +int sn_init_defaults (n2n_sn_t *sss); +void sn_init (n2n_sn_t *sss); +void sn_term (n2n_sn_t *sss); +int supernode2sock (n2n_sock_t * sn, const n2n_sn_name_t addrIn); +struct peer_info* add_sn_to_list_by_mac_or_sock (struct peer_info **sn_list, n2n_sock_t *sock, const n2n_mac_t mac, int *skip_add); +int run_sn_loop (n2n_sn_t *sss); +int assign_one_ip_subnet (n2n_sn_t *sss, struct sn_community *comm); +const char* compression_str (uint8_t cmpr); +const char* transop_str (enum n2n_transform tr); + +void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock); +void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock); +#endif /* _N2N_H_ */ diff --git a/bundles/n2n_ntop_v3/include/n2n_define.h b/bundles/n2n_ntop_v3/include/n2n_define.h new file mode 100644 index 00000000..cdee5dad --- /dev/null +++ b/bundles/n2n_ntop_v3/include/n2n_define.h @@ -0,0 +1,215 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* N2N packet header indicators. */ +#define MSG_TYPE_REGISTER 1 +#define MSG_TYPE_DEREGISTER 2 +#define MSG_TYPE_PACKET 3 +#define MSG_TYPE_REGISTER_ACK 4 +#define MSG_TYPE_REGISTER_SUPER 5 +#define MSG_TYPE_UNREGISTER_SUPER 6 +#define MSG_TYPE_REGISTER_SUPER_ACK 7 +#define MSG_TYPE_REGISTER_SUPER_NAK 8 +#define MSG_TYPE_FEDERATION 9 +#define MSG_TYPE_PEER_INFO 10 +#define MSG_TYPE_QUERY_PEER 11 +#define MSG_TYPE_MAX_TYPE 11 +#define MSG_TYPE_RE_REGISTER_SUPER 12 + +/* Max available space to add supernodes' informations (sockets and MACs) in REGISTER_SUPER_ACK + * Field sizes of REGISTER_SUPER_ACK as used in encode/decode fucntions in src/wire.c + */ +#define REG_SUPER_ACK_PAYLOAD_SPACE (DEFAULT_MTU - (sizeof(n2n_common_t) + sizeof(n2n_REGISTER_SUPER_ACK_t))) + +/* Space needed to store socket and MAC address of a supernode */ +#define REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE (sizeof(n2n_REGISTER_SUPER_ACK_payload_t)) + +#define BOOTSTRAP_TIMEOUT 3 +#define PURGE_REGISTRATION_FREQUENCY 30 +#define RE_REG_AND_PURGE_FREQUENCY 10 +#define REGISTRATION_TIMEOUT 60 + +#define SOCKET_TIMEOUT_INTERVAL_SECS 10 +#define REGISTER_SUPER_INTERVAL_DFL 20 /* sec, usually UDP NAT entries in a firewall expire after 30 seconds */ +#define SWEEP_TIME 30 /* sec, indicates the value after which we have to sort the hash list of supernodes in edges + * and when we send out packets to query selection-relevant informations from supernodes. */ + +#define NUMBER_SN_PINGS_INITIAL 15 /* number of supernodes to concurrently ping during bootstrap and immediately afterwards */ +#define NUMBER_SN_PINGS_REGULAR 5 /* number of supernodes to concurrently ping during regular edge operation */ + +/* Timeouts used in re_register_and_purge_supernodes. LAST_SEEN_SN_ACTIVE and LAST_SEEN_SN_INACTIVE + * values should be at least 3*SOCKET_TIMEOUT_INTERVAL_SECS apart. */ +#define LAST_SEEN_SN_ACTIVE 20 /* sec, indicates supernodes that are proven to be active */ +#define LAST_SEEN_SN_INACTIVE 90 /* sec, indicates supernodes that are proven to be inactive: they will be purged */ +#define LAST_SEEN_SN_NEW (LAST_SEEN_SN_INACTIVE - 3 * RE_REG_AND_PURGE_FREQUENCY) /* sec, indicates supernodes with unsure status, must be tested to check if they are active */ + +#define IFACE_UPDATE_INTERVAL (30) /* sec. How long it usually takes to get an IP lease. */ +#define TRANSOP_TICK_INTERVAL (10) /* sec */ + +#define SORT_COMMUNITIES_INTERVAL 90 /* sec. until supernode sorts communities' hash list again */ + +#define AF_INVALID -1 /* to mark a socket invalid by an invalid address family (do not use AF_UNSPEC, it could turn into auto-detect) */ +#define N2N_RESOLVE_INTERVAL 300 /* seconds until edge and supernode try to resolve supernode names again */ +#define N2N_RESOLVE_CHECK_INTERVAL 30 /* seconds until main loop checking in on changes from resolver thread */ + +#define ETH_FRAMESIZE 14 +#define IP4_SRCOFFSET 12 +#define IP4_DSTOFFSET 16 +#define IP4_MIN_SIZE 20 +#define UDP_SIZE 8 + +/* parameters for replay protection */ +#define TIME_STAMP_FRAME 0x0000001000000000LL /* clocks of different computers are allowed +/- 16 seconds to be off */ +#define TIME_STAMP_JITTER 0x0000000027100000LL /* we allow a packet to arrive 160 ms (== 0x27100 us) before another + * set to 0x0000000000000000LL if increasing (or equal) time stamps allowed only */ +#define TIME_STAMP_ALLOW_JITTER 1 /* constant for allowing or... */ +#define TIME_STAMP_NO_JITTER 0 /* not allowing jitter to be considered */ + +/* N2N compression indicators. */ +/* Compression is disabled by default for outgoing packets if no cli + * option is given. All edges are built with decompression support so + * they are able to understand each other (this applies to lzo only). */ +#define N2N_COMPRESSION_ID_INVALID 0 +#define N2N_COMPRESSION_ID_NONE 1 /* default, see edge_init_conf_defaults(...) in edge_utils.c */ +#define N2N_COMPRESSION_ID_LZO 2 /* set if '-z1' or '-z' cli option is present, see setOption(...) in edge.c */ +#define N2N_COMPRESSION_ID_ZSTD 3 /* set if '-z2' cli option is present, available only if compiled with zstd lib */ +#define ZSTD_COMPRESSION_LEVEL 7 /* 1 (faster) ... 22 (more compression) */ + +/* Federation name and indicators */ +#define FEDERATION_NAME "*Federation" +enum federation {IS_NO_FEDERATION = 0,IS_FEDERATION = 1}; + +/* (un)purgeable community indicator (supernode) */ +#define COMMUNITY_UNPURGEABLE 0 +#define COMMUNITY_PURGEABLE 1 + +/* (un)purgeable supernode indicator */ +enum sn_purge {SN_PURGEABLE = 0, SN_UNPURGEABLE = 1}; + +/* Header encryption indicators */ +#define HEADER_ENCRYPTION_UNKNOWN 0 +#define HEADER_ENCRYPTION_NONE 1 +#define HEADER_ENCRYPTION_ENABLED 2 + +/* REGISTER_SUPER_ACK packet hash length with user/pw auth, up to 16 bytes */ +#define N2N_REG_SUP_HASH_CHECK_LEN 16 + +#define DEFAULT_MTU 1290 + +#define HASH_ADD_PEER(head,add) \ + HASH_ADD(hh,head,mac_addr,sizeof(n2n_mac_t),add) +#define HASH_FIND_PEER(head,mac,out) \ + HASH_FIND(hh,head,mac,sizeof(n2n_mac_t),out) +#define N2N_EDGE_SN_HOST_SIZE 48 +#define N2N_EDGE_SUP_ATTEMPTS 3 /* Number of failed attmpts before moving on to next supernode. */ +#define N2N_PATHNAME_MAXLEN 256 +#define N2N_EDGE_MGMT_PORT 5644 +#define N2N_SN_MGMT_PORT 5645 + +enum n2n_mgmt_type { + N2N_MGMT_READ = 0, + N2N_MGMT_WRITE = 1, +}; + +#define N2N_MGMT_PASSWORD "n2n" /* default password for management port access (so far, json only) */ + + +#define N2N_TCP_BACKLOG_QUEUE_SIZE 3 /* number of concurrently pending connections to be accepted */ + /* NOT the number of max. TCP connections */ + +#define N2N_CLOSE_SOCKET_COUNTER_MAX 15 /* number of times of edge's reconnects to supernode after */ + /* which the socket explicitly is closed before reopening */ + +/* flag used in add_sn_to_list_by_mac_or_sock */ +enum skip_add {SN_ADD = 0, SN_ADD_SKIP = 1, SN_ADD_ADDED = 2}; + +#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ +#define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ +#define N2N_IF_MODE_SIZE 16 /* static | dhcp */ + +#define N2N_EDGE_DEFAULT_DEV_NAME "edge0" +#define N2N_EDGE_DEFAULT_NETMASK "255.255.255.0" /* default netmask for edge ip address... */ +#define N2N_EDGE_DEFAULT_CIDR_NM 24 /* ... also in cidr format */ + +#define N2N_SN_LPORT_DEFAULT 7654 +#define N2N_SN_PKTBUF_SIZE 2048 + + +/* The way TUNTAP allocated IP. */ +#define TUNTAP_IP_MODE_SN_ASSIGN 0 +#define TUNTAP_IP_MODE_STATIC 1 +#define TUNTAP_IP_MODE_DHCP 2 + +/* Default network segment of the auto ip address service provided by sn. */ +#define N2N_SN_MIN_AUTO_IP_NET_DEFAULT "10.128.0.0" +#define N2N_SN_MAX_AUTO_IP_NET_DEFAULT "10.255.255.0" +#define N2N_SN_AUTO_IP_NET_BIT_DEFAULT 24 + +/* ************************************** */ + +#define SUPERNODE_IP "127.0.0.1" +#define SUPERNODE_PORT 1234 + +/* ************************************** */ + +#define N2N_PKT_VERSION 3 +#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */ +#define N2N_COMMUNITY_SIZE 20 +#define N2N_PRIVATE_PUBLIC_KEY_SIZE 32 +#define N2N_USER_KEY_LINE_STARTER '*' +#define N2N_MAC_SIZE 6 +#define N2N_NO_REG_COOKIE 0x00000000 +#define N2N_FORWARDED_REG_COOKIE 0x00001000 +#define N2N_PORT_REG_COOKIE 0x00004000 +#define N2N_REGULAR_REG_COOKIE 0x00010000 +#define N2N_MCAST_REG_COOKIE 0x00400000 +#define N2N_LOCAL_REG_COOKIE 0x01000000 +#define N2N_DESC_SIZE 16 +#define N2N_PKT_BUF_SIZE 2048 +#define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ + +#define N2N_MULTICAST_PORT 1968 +#define N2N_MULTICAST_GROUP "224.0.0.68" + +#ifdef WIN32 +#define N2N_IFNAMSIZ 64 +#else +#define N2N_IFNAMSIZ 16 /* 15 chars * NULL */ +#endif + +#ifdef _MSC_VER +#define N2N_THREAD_RETURN_DATATYPE DWORD WINAPI +#define N2N_THREAD_PARAMETER_DATATYPE LPVOID +#else +#define N2N_THREAD_RETURN_DATATYPE void* +#define N2N_THREAD_PARAMETER_DATATYPE void* +#endif + +#define SN_SELECTION_CRITERION_DATA_TYPE uint64_t +#define SN_SELECTION_CRITERION_BUF_SIZE 16 + +#define N2N_TRANSFORM_ID_USER_START 64 +#define N2N_TRANSFORM_ID_MAX 65535 + +#ifndef max +#define max(a, b) (((a) < (b)) ? (b) : (a)) +#endif + +#ifndef min +#define min(a, b) (((a) >(b)) ? (b) : (a)) +#endif diff --git a/bundles/n2n_ntop_v3/include/n2n_regex.h b/bundles/n2n_ntop_v3/include/n2n_regex.h new file mode 100644 index 00000000..9ac409c4 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/n2n_regex.h @@ -0,0 +1,76 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +// taken from https://github.com/kokke/tiny-regex-c +// under Unlicense as of August 4, 2020 + +/* + * + * Mini regex-module inspired by Rob Pike's regex code described in: + * + * http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html + * + * + * + * Supports: + * --------- + * '.' Dot, matches any character + * '^' Start anchor, matches beginning of string + * '$' End anchor, matches end of string + * '*' Asterisk, match zero or more (greedy) + * '+' Plus, match one or more (greedy) + * '?' Question, match zero or one (non-greedy) + * '[abc]' Character class, match if one of {'a', 'b', 'c'} + * '[^abc]' Inverted class, match if NOT one of {'a', 'b', 'c'} -- NOTE: feature is currently broken! + * '[a-zA-Z]' Character ranges, the character set of the ranges { a-z | A-Z } + * '\s' Whitespace, \t \f \r \n \v and spaces + * '\S' Non-whitespace + * '\w' Alphanumeric, [a-zA-Z0-9_] + * '\W' Non-alphanumeric + * '\d' Digits, [0-9] + * '\D' Non-digits + * + * + */ + +#ifndef _N2N_REGEX_ +#define _N2N_REGEX_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Compile regex string pattern to a regex_t-array. */ +re_t re_compile (const char* pattern); + + +/* Find matches of the compiled pattern inside text. */ +int re_matchp (re_t pattern, const char* text, int* matchlenght); + + +/* Find matches of the txt pattern inside text (will compile automatically first). */ +int re_match (const char* pattern, const char* text, int* matchlenght); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bundles/n2n_ntop_v3/include/n2n_typedefs.h b/bundles/n2n_ntop_v3/include/n2n_typedefs.h new file mode 100644 index 00000000..3ba65f2b --- /dev/null +++ b/bundles/n2n_ntop_v3/include/n2n_typedefs.h @@ -0,0 +1,846 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _N2N_TYPEDEFS_H_ +#define _N2N_TYPEDEFS_H_ + + +typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; +typedef uint8_t n2n_private_public_key_t[N2N_PRIVATE_PUBLIC_KEY_SIZE]; +typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; +typedef uint32_t n2n_cookie_t; +typedef uint8_t n2n_desc_t[N2N_DESC_SIZE]; +typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ + + +#if defined(_MSC_VER) || defined(__MINGW32__) +#include "getopt.h" + +/* Other Win environments are expected to support stdint.h */ + +/* stdint.h typedefs (C99) (not present in Visual Studio) */ +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* sys/types.h typedefs (not present in Visual Studio) */ +typedef unsigned int u_int32_t; +typedef unsigned short u_int16_t; +typedef unsigned char u_int8_t; + +#ifndef __MINGW32__ +typedef int ssize_t; +#endif + +typedef unsigned long in_addr_t; + +#include "n2n_win32.h" + +#endif /* #if defined(_MSC_VER) || defined(__MINGW32__) */ + + + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#endif + +#ifdef __OpenBSD__ +#include +#define __BYTE_ORDER BYTE_ORDER +#if BYTE_ORDER == LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#endif /* __LITTLE_ENDIAN__ */ +#else +#define __BIG_ENDIAN__ +#endif/* BYTE_ORDER */ +#endif/* __OPENBSD__ */ + + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#endif +#else +#ifndef __BIG_ENDIAN__ +#define __BIG_ENDIAN__ +#endif +#endif + +#ifdef WIN32 +#ifndef __LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ 1 +#endif +#endif + +#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)) +#if defined(__mips__) +#undef __LITTLE_ENDIAN__ +#undef __LITTLE_ENDIAN +#define __BIG_ENDIAN__ +#endif + +/* Everything else */ +#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)) +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define __LITTLE_ENDIAN__ +#else +#define __BIG_ENDIAN__ +#endif +#endif + +#endif + +/* *************************************** */ + +#ifdef __GNUC__ +#define PACK_STRUCT __attribute__((__packed__)) +#else +#define PACK_STRUCT +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) +#pragma pack(push,1) +#endif + + +// those are definitely not typedefs (with a view to the filename) but neither are they defines +static const n2n_mac_t broadcast_mac = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const n2n_mac_t multicast_mac = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 }; /* First 3 bytes are meaningful */ +static const n2n_mac_t ipv6_multicast_mac = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; /* First 2 bytes are meaningful */ +static const n2n_mac_t null_mac = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +#define ETH_ADDR_LEN 6 + +struct ether_hdr { + uint8_t dhost[ETH_ADDR_LEN]; + uint8_t shost[ETH_ADDR_LEN]; + uint16_t type; /* higher layer protocol encapsulated */ +} PACK_STRUCT; + +typedef struct ether_hdr ether_hdr_t; + + +struct n2n_iphdr { +#if defined(__LITTLE_ENDIAN__) + u_int8_t ihl:4, version:4; +#elif defined(__BIG_ENDIAN__) + u_int8_t version:4, ihl:4; +#else +# error "Byte order must be defined" +#endif + u_int8_t tos; + u_int16_t tot_len; + u_int16_t id; + u_int16_t frag_off; + u_int8_t ttl; + u_int8_t protocol; + u_int16_t check; + u_int32_t saddr; + u_int32_t daddr; +} PACK_STRUCT; + +struct n2n_tcphdr { + u_int16_t source; + u_int16_t dest; + u_int32_t seq; + u_int32_t ack_seq; +#if defined(__LITTLE_ENDIAN__) + u_int16_t res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; +#elif defined(__BIG_ENDIAN__) + u_int16_t doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1; +#else +# error "Byte order must be defined" +#endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; +} PACK_STRUCT; + +struct n2n_udphdr { + u_int16_t source; + u_int16_t dest; + u_int16_t len; + u_int16_t check; +} PACK_STRUCT; + +#if defined(_MSC_VER) || defined(__MINGW32__) +#pragma pack(pop) +#endif + + +typedef struct port_range { + uint16_t start_port; // range contain 'start_port' self + uint16_t end_port; // range contain 'end_port' self +} port_range_t; + +typedef struct filter_rule_key { + in_addr_t src_net_cidr; + uint8_t src_net_bit_len; + port_range_t src_port_range; + in_addr_t dst_net_cidr; + uint8_t dst_net_bit_len; + port_range_t dst_port_range; + uint8_t bool_tcp_configured; + uint8_t bool_udp_configured; + uint8_t bool_icmp_configured; +} filter_rule_key_t; + +typedef struct filter_rule { + filter_rule_key_t key; + + uint8_t bool_accept_icmp; + uint8_t bool_accept_udp; + uint8_t bool_accept_tcp; + + UT_hash_handle hh; /* makes this structure hashable */ +} filter_rule_t; + + +#ifndef WIN32 +typedef struct tuntap_dev { + int fd; + int if_idx; + n2n_mac_t mac_addr; + uint32_t ip_addr; + uint32_t device_mask; + uint16_t mtu; + char dev_name[N2N_IFNAMSIZ]; +} tuntap_dev; + +#define SOCKET int +#endif /* #ifndef WIN32 */ + +/** Uncomment this to enable the MTU check, then try to ssh to generate a fragmented packet. */ +/** NOTE: see doc/MTU.md for an explanation on the 1400 value */ +//#define MTU_ASSERT_VALUE 1400 + +/** Common type used to hold stringified IP addresses. */ +typedef char ipstr_t[32]; + +/** Common type used to hold stringified MAC addresses. */ +#define N2N_MACSTR_SIZE 32 +typedef char macstr_t[N2N_MACSTR_SIZE]; +typedef char dec_ip_str_t[N2N_NETMASK_STR_SIZE]; +typedef char dec_ip_bit_str_t[N2N_NETMASK_STR_SIZE + 4]; + +typedef struct speck_context_t he_context_t; +typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; + +typedef enum n2n_pc { + n2n_ping = 0, /* Not used */ + n2n_register = 1, /* Register edge to edge */ + n2n_deregister = 2, /* Deregister this edge */ + n2n_packet = 3, /* PACKET data content */ + n2n_register_ack = 4, /* ACK of a registration from edge to edge */ + n2n_register_super = 5, /* Register edge to supernode */ + n2n_unregister_super = 6, /* Deregister edge from supernode */ + n2n_register_super_ack = 7, /* ACK from supernode to edge */ + n2n_register_super_nak = 8, /* NAK from supernode to edge - registration refused */ + n2n_federation = 9, /* Not used by edge */ + n2n_peer_info = 10, /* Send info on a peer from sn to edge */ + n2n_query_peer = 11, /* ask supernode for info on a peer */ + n2n_re_register_super = 12 /* ask edge to re-register with supernode */ +} n2n_pc_t; + +#define N2N_FLAGS_OPTIONS 0x0080 +#define N2N_FLAGS_SOCKET 0x0040 +#define N2N_FLAGS_FROM_SUPERNODE 0x0020 + +/* The bits in flag that are the packet type */ +#define N2N_FLAGS_TYPE_MASK 0x001f /* 0 - 31 */ +#define N2N_FLAGS_BITS_MASK 0xffe0 + +#define IPV4_SIZE 4 +#define IPV6_SIZE 16 + + +#define N2N_AUTH_MAX_TOKEN_SIZE 48 /* max token size in bytes */ +#define N2N_AUTH_CHALLENGE_SIZE 16 /* challenge always is of same size as dynamic key */ +#define N2N_AUTH_ID_TOKEN_SIZE 16 +#define N2N_AUTH_PW_TOKEN_SIZE (N2N_PRIVATE_PUBLIC_KEY_SIZE + N2N_AUTH_CHALLENGE_SIZE) + +#define N2N_EUNKNOWN -1 +#define N2N_ENOTIMPL -2 +#define N2N_EINVAL -3 +#define N2N_ENOSPACE -4 + + +#define N2N_VERSION_STRING_SIZE 20 +typedef char n2n_version_t[N2N_VERSION_STRING_SIZE]; + + +#define SN_SELECTION_STRATEGY_LOAD 1 +#define SN_SELECTION_STRATEGY_RTT 2 +#define SN_SELECTION_STRATEGY_MAC 3 + + +typedef struct n2n_ip_subnet { + uint32_t net_addr; /* Host order IP address. */ + uint8_t net_bitlen; /* Subnet prefix. */ +} n2n_ip_subnet_t; + +typedef struct n2n_sock { + uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ + uint16_t port; /* host order */ + union { + uint8_t v6[IPV6_SIZE]; /* byte sequence */ + uint8_t v4[IPV4_SIZE]; /* byte sequence */ + } addr; +} n2n_sock_t; + +typedef enum { + n2n_auth_none = 0, + n2n_auth_simple_id = 1, + n2n_auth_user_password = 2 +} n2n_auth_scheme_t; + +typedef enum { + update_edge_no_change = 0, + update_edge_sock_change = 1, + update_edge_new_sn = 2, + update_edge_auth_fail = -1 +} update_edge_ret_value_t; + +typedef struct n2n_auth { + uint16_t scheme; /* What kind of auth */ + uint16_t token_size; /* Size of auth token */ + uint8_t token[N2N_AUTH_MAX_TOKEN_SIZE]; /* Auth data interpreted based on scheme */ +} n2n_auth_t; + +typedef struct n2n_common { + /* NOTE: wire representation is different! */ + /* int version; */ + + uint8_t ttl; + uint8_t pc; + uint16_t flags; + n2n_community_t community; +} n2n_common_t; + +typedef struct n2n_REGISTER { + n2n_cookie_t cookie; /**< Link REGISTER and REGISTER_ACK */ + n2n_mac_t srcMac; /**< MAC of registering party */ + n2n_mac_t dstMac; /**< MAC of target edge */ + n2n_sock_t sock; /**< Supernode's view of edge socket OR edge's preferred local socket */ + n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */ + n2n_desc_t dev_desc; /**< Hint description correlated with the edge */ +} n2n_REGISTER_t; + +typedef struct n2n_REGISTER_ACK { + n2n_cookie_t cookie; /**< Return cookie from REGISTER */ + n2n_mac_t srcMac; /**< MAC of acknowledging party (supernode or edge) */ + n2n_mac_t dstMac; /**< Reflected MAC of registering edge from REGISTER */ + n2n_sock_t sock; /**< Supernode's view of edge socket (IP Addr, port) */ +} n2n_REGISTER_ACK_t; + +typedef struct n2n_PACKET { + n2n_mac_t srcMac; + n2n_mac_t dstMac; + n2n_sock_t sock; + uint8_t transform; + uint8_t compression; +} n2n_PACKET_t; + +/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */ +typedef struct n2n_REGISTER_SUPER { + n2n_cookie_t cookie; /**< Link REGISTER_SUPER and REGISTER_SUPER_ACK */ + n2n_mac_t edgeMac; /**< MAC to register with edge sending socket */ + n2n_sock_t sock; /**< Sending socket associated with edgeMac */ + n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */ + n2n_desc_t dev_desc; /**< Hint description correlated with the edge */ + n2n_auth_t auth; /**< Authentication scheme and tokens */ + uint32_t key_time; /**< key time for dynamic key, used between federatred supernodes only */ +} n2n_REGISTER_SUPER_t; + + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +typedef struct n2n_REGISTER_SUPER_ACK { + n2n_cookie_t cookie; /**< Return cookie from REGISTER_SUPER */ + n2n_mac_t srcMac; /**< MAC of answering supernode */ + n2n_ip_subnet_t dev_addr; /**< Assign an IP address to the tuntap adapter of edge. */ + uint16_t lifetime; /**< How long the registration will live */ + n2n_sock_t sock; /**< Sending sockets associated with edge */ + n2n_auth_t auth; /**< Authentication scheme and tokens */ + + /** The packet format provides additional supernode definitions here. + * uint8_t count, then for each count there is one + * n2n_sock_t. + */ + uint8_t num_sn; /**< Number of supernodes that were send + * even if we cannot store them all. */ + + uint32_t key_time; /**< key time for dynamic key, used between federatred supernodes only */ +} n2n_REGISTER_SUPER_ACK_t; + + +/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ +typedef struct n2n_REGISTER_SUPER_NAK { + n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ + n2n_mac_t srcMac; + n2n_auth_t auth; /* Authentication scheme and tokens */ +} n2n_REGISTER_SUPER_NAK_t; + + +/* REGISTER_SUPER_ACK may contain extra payload (their number given by num_sn) + * of following type describing a(nother) supernode */ +typedef struct n2n_REGISTER_SUPER_ACK_payload { + n2n_sock_t sock; /**< socket of supernode */ + n2n_mac_t mac; /**< MAC of supernode */ +} n2n_REGISTER_SUPER_ACK_payload_t; + + +/* Linked with n2n_unregister_super in n2n_pc_t. */ +typedef struct n2n_UNREGISTER_SUPER { + n2n_auth_t auth; + n2n_mac_t srcMac; +} n2n_UNREGISTER_SUPER_t; + + +typedef struct n2n_PEER_INFO { + uint16_t aflags; + n2n_mac_t srcMac; + n2n_mac_t mac; + n2n_sock_t sock; + n2n_sock_t preferred_sock; + uint32_t load; + n2n_version_t version; + time_t uptime; +} n2n_PEER_INFO_t; + + +typedef struct n2n_QUERY_PEER { + uint16_t aflags; + n2n_mac_t srcMac; + n2n_sock_t sock; + n2n_mac_t targetMac; + +} n2n_QUERY_PEER_t; + +typedef struct n2n_buf n2n_buf_t; + +struct peer_info { + n2n_mac_t mac_addr; + n2n_ip_subnet_t dev_addr; + n2n_desc_t dev_desc; + n2n_sock_t sock; + SOCKET socket_fd; + n2n_sock_t preferred_sock; + n2n_cookie_t last_cookie; + n2n_auth_t auth; + int timeout; + uint8_t purgeable; + time_t last_seen; + time_t last_p2p; + time_t last_sent_query; + SN_SELECTION_CRITERION_DATA_TYPE selection_criterion; + uint64_t last_valid_time_stamp; + char *ip_addr; + uint8_t local; + time_t uptime; + n2n_version_t version; + + UT_hash_handle hh; /* makes this structure hashable */ +}; + +typedef struct peer_info peer_info_t; + +typedef struct n2n_route { + in_addr_t net_addr; + uint8_t net_bitlen; + in_addr_t gateway; +} n2n_route_t; + +typedef struct n2n_edge n2n_edge_t; + +/* *************************************************** */ + +typedef enum { + N2N_ACCEPT = 0, + N2N_DROP = 1 +} n2n_verdict; + +/* *************************************************** */ + +typedef enum { + FPP_UNKNOWN = 0, + FPP_ARP = 1, + FPP_TCP = 2, + FPP_UDP = 3, + FPP_ICMP = 4, + FPP_IGMP = 5 +} filter_packet_proto; + + +typedef struct packet_address_proto_info { + in_addr_t src_ip; + uint16_t src_port; + in_addr_t dst_ip; + uint16_t dst_port; + filter_packet_proto proto; +}packet_address_proto_info_t; + +typedef struct filter_rule_pair_cache { + packet_address_proto_info_t key; + + uint8_t bool_allow_traffic; + uint32_t active_count; + + UT_hash_handle hh; /* makes this structure hashable */ +} filter_rule_pair_cache_t; + +struct network_traffic_filter; +typedef struct network_traffic_filter network_traffic_filter_t; + +struct network_traffic_filter { + n2n_verdict (*filter_packet_from_peer)(network_traffic_filter_t* filter, n2n_edge_t *eee, + const n2n_sock_t *peer, uint8_t *payload, uint16_t payload_size); + + n2n_verdict (*filter_packet_from_tap)(network_traffic_filter_t* filter, n2n_edge_t *eee, uint8_t *payload, uint16_t payload_size); + + filter_rule_t *rules; + + filter_rule_pair_cache_t *connections_rule_cache; + + uint32_t work_count_scene_last_clear; + +}; + +/* *************************************************** */ + +/* Callbacks allow external programs to attach functions in response to + * N2N events. */ +typedef struct n2n_edge_callbacks { + /* The supernode registration has been updated */ + void (*sn_registration_updated)(n2n_edge_t *eee, time_t now, const n2n_sock_t *sn); + + /* A packet has been received from a peer. N2N_DROP can be returned to + * drop the packet. The packet payload can be modified. This only allows + * the packet size to be reduced */ + n2n_verdict (*packet_from_peer)(n2n_edge_t *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t *payload_size); + + /* A packet has been received from the TAP interface. N2N_DROP can be + * returned to drop the packet. The packet payload can be modified. + * This only allows the packet size to be reduced */ + n2n_verdict (*packet_from_tap)(n2n_edge_t *eee, uint8_t *payload, uint16_t *payload_size); + + /* Called whenever the IP address of the TAP interface changes. */ + void (*ip_address_changed)(n2n_edge_t *eee, uint32_t old_ip, uint32_t new_ip); + + /* Called periodically in the main loop. */ + void (*main_loop_period)(n2n_edge_t *eee, time_t now); + + /* Called when a new socket to supernode is created. */ + void (*sock_opened)(n2n_edge_t *eee); +} n2n_edge_callbacks_t; + +typedef struct n2n_tuntap_priv_config { + char tuntap_dev_name[N2N_IFNAMSIZ]; + char ip_mode[N2N_IF_MODE_SIZE]; + dec_ip_str_t ip_addr; + dec_ip_str_t netmask; + char device_mac[N2N_MACNAMSIZ]; + int mtu; + int metric; + uint8_t daemon; +#ifndef WIN32 + uid_t userid; + gid_t groupid; +#endif +} n2n_tuntap_priv_config_t; + +/* *************************************************** */ + +typedef enum n2n_transform { + N2N_TRANSFORM_ID_INVAL = 0, + N2N_TRANSFORM_ID_NULL = 1, + N2N_TRANSFORM_ID_TWOFISH = 2, + N2N_TRANSFORM_ID_AES = 3, + N2N_TRANSFORM_ID_CHACHA20 = 4, + N2N_TRANSFORM_ID_SPECK = 5, +} n2n_transform_t; + +struct n2n_trans_op; /* Circular definition */ + +typedef int (*n2n_transdeinit_f)(struct n2n_trans_op * arg); +typedef void (*n2n_transtick_f)(struct n2n_trans_op * arg, time_t now); +typedef int (*n2n_transform_f)(struct n2n_trans_op * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const n2n_mac_t peer_mac); +/** Holds the info associated with a data transform plugin. + * + * When a packet arrives the transform ID is extracted. This defines the code + * to use to decode the packet content. The transform code then decodes the + * packet and consults its internal key lookup. + */ +typedef struct n2n_trans_op { + void * priv; /* opaque data. Key schedule goes here. */ + uint8_t no_encryption; /* 1 if this transop does not perform encryption */ + n2n_transform_t transform_id; + size_t tx_cnt; + size_t rx_cnt; + + n2n_transdeinit_f deinit; /* destructor function */ + n2n_transtick_f tick; /* periodic maintenance */ + n2n_transform_f fwd; /* encode a payload */ + n2n_transform_f rev; /* decode a payload */ +} n2n_trans_op_t; + + +/* *************************************************** */ + + +typedef struct n2n_resolve_ip_sock { + char *org_ip; /* pointer to original ip/named address string (used read only) */ + n2n_sock_t sock; /* resolved socket */ + n2n_sock_t *org_sock; /* pointer to original socket where 'sock' gets copied to from time to time */ + int error_code; /* result of last resolution attempt */ + + UT_hash_handle hh; /* makes this structure hashable */ +} n2n_resolve_ip_sock_t; + + +// structure to hold resolver thread's parameters +typedef struct n2n_resolve_parameter { + n2n_resolve_ip_sock_t *list; /* pointer to list of to be resolved nodes */ + uint8_t changed; /* indicates a change */ +#ifdef HAVE_PTHREAD + pthread_t id; /* thread id */ + pthread_mutex_t access; /* mutex for shared access */ +#endif + uint8_t request; /* flags main thread's need for intermediate resolution */ + time_t check_interval;/* interval to checik resolover results */ + time_t last_checked; /* last time the resolver results were cheked */ + time_t last_resolved; /* last time the resolver completed */ +} n2n_resolve_parameter_t; + + +/* *************************************************** */ + + +typedef struct n2n_edge_conf { + struct peer_info *supernodes; /**< List of supernodes */ + n2n_route_t *routes; /**< Networks to route through n2n */ + n2n_community_t community_name; /**< The community. 16 full octets. */ + n2n_desc_t dev_desc; /**< The device description (hint) */ + n2n_private_public_key_t *public_key; /**< edge's public key (for user/password based authentication) */ + n2n_private_public_key_t *shared_secret; /**< shared secret derived from federation public key, username and password */ + he_context_t *shared_secret_ctx; /**< context holding the roundkeys derived from shared secret */ + n2n_private_public_key_t *federation_public_key; /**< federation public key provided by command line */ + uint8_t header_encryption; /**< Header encryption indicator. */ + he_context_t *header_encryption_ctx_static; /**< Header encryption cipher context. */ + he_context_t *header_encryption_ctx_dynamic; /**< Header encryption cipher context. */ + he_context_t *header_iv_ctx_static; /**< Header IV ecnryption cipher context, REMOVE as soon as separate fileds for checksum and replay protection available */ + he_context_t *header_iv_ctx_dynamic; /**< Header IV ecnryption cipher context, REMOVE as soon as separate fileds for checksum and replay protection available */ + n2n_transform_t transop_id; /**< The transop to use. */ + uint8_t compression; /**< Compress outgoing data packets before encryption */ + uint16_t num_routes; /**< Number of routes in routes */ + uint8_t tuntap_ip_mode; /**< Interface IP address allocated mode, eg. DHCP. */ + uint8_t allow_routing; /**< Accept packet no to interface address. */ + uint8_t drop_multicast; /**< Multicast ethernet addresses. */ + uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */ + uint8_t allow_p2p; /**< Allow P2P connection */ + uint8_t sn_num; /**< Number of supernode addresses defined. */ + uint8_t tos; /** TOS for sent packets */ + char *encrypt_key; + int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */ + int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */ + in_addr_t bind_address; /**< The address to bind to if provided (-b) */ + n2n_sock_t preferred_sock; /**< propagated local sock for better p2p in LAN (-e) */ + uint8_t preferred_sock_auto; /**< indicates desired auto detect for preferred sock */ + int local_port; + int mgmt_port; + uint8_t connect_tcp; /** connection to supernode 0 = UDP; 1 = TCP */ + n2n_auth_t auth; + filter_rule_t *network_traffic_filter_rules; + int metric; /**< Network interface metric (Windows only). */ + uint8_t sn_selection_strategy; /**< encodes currently chosen supernode selection strategy. */ + uint8_t number_max_sn_pings; /**< Number of maximum concurrently allowed supernode pings. */ + uint64_t mgmt_password_hash; /**< contains hash of managament port password. */ +} n2n_edge_conf_t; + + +struct n2n_edge_stats { + uint32_t tx_p2p; + uint32_t rx_p2p; + uint32_t tx_sup; + uint32_t rx_sup; + uint32_t tx_sup_broadcast; + uint32_t rx_sup_broadcast; +}; + +struct n2n_edge { + n2n_edge_conf_t conf; + + /* Status */ + int *keep_running; /**< Pointer to edge loop stop/go flag */ + struct peer_info *curr_sn; /**< Currently active supernode. */ + uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */ + uint8_t sn_pong; /**< Whether we have seen a PONG since last time reset. */ + size_t sup_attempts; /**< Number of remaining attempts to this supernode. */ + tuntap_dev device; /**< All about the TUNTAP device */ + n2n_trans_op_t transop; /**< The transop to use when encoding */ + n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */ + n2n_edge_callbacks_t cb; /**< API callbacks */ + void *user_data; /**< Can hold user data */ + SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_data; + + /* Sockets */ + /* supernode socket is in eee->curr_sn->sock (of type n2n_sock_t) */ + int sock; + int close_socket_counter; /**< counter for close-event before re-opening */ + int udp_mgmt_sock; /**< socket for status info. */ + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */ + int udp_multicast_sock; /**< socket for local multicast registrations. */ + int multicast_joined; /**< 1 if the group has been joined.*/ +#endif + + /* Peers */ + struct peer_info * known_peers; /**< Edges we are connected to. */ + struct peer_info * pending_peers; /**< Edges we have tried to register with. */ + + /* Timers */ + time_t last_register_req; /**< Check if time to re-register with super*/ + time_t last_p2p; /**< Last time p2p traffic was received. */ + time_t last_sup; /**< Last time a packet arrived from supernode. */ + time_t last_sweep; /**< Last time a sweep was performed. */ + time_t start_time; /**< For calculating uptime */ + + + struct n2n_edge_stats stats; /**< Statistics */ + + n2n_resolve_parameter_t *resolve_parameter; /**< Pointer to name resolver's parameter block */ + uint8_t resolution_request; /**< Flag an immediate DNS resolution request */ + + n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */ + + network_traffic_filter_t *network_traffic_filter; +}; + +typedef struct sn_stats { + size_t errors; /* Number of errors encountered. */ + size_t reg_super; /* Number of REGISTER_SUPER requests received. */ + size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ + size_t fwd; /* Number of messages forwarded. */ + size_t broadcast; /* Number of messages broadcast to a community. */ + time_t last_fwd; /* Time when last message was forwarded. */ + time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ +} sn_stats_t; + +typedef struct node_supernode_association { + + n2n_mac_t mac; /* mac address of an edge */ + const struct sockaddr_in sock; /* network order socket of that edge's supernode */ + time_t last_seen; /* time mark to keep track of purging requirements */ + + UT_hash_handle hh; /* makes this structure hashable */ +} node_supernode_association_t; + +typedef struct sn_user { + n2n_private_public_key_t public_key; + n2n_private_public_key_t shared_secret; + he_context_t *shared_secret_ctx; + n2n_desc_t name; + + UT_hash_handle hh; +} sn_user_t; + +struct sn_community { + char community[N2N_COMMUNITY_SIZE]; + uint8_t is_federation; /* if not-zero, then the current community is the federation of supernodes */ + uint8_t purgeable; /* indicates purgeable community (fixed-name, predetermined (-c parameter) communties usually are unpurgeable) */ + uint8_t header_encryption; /* Header encryption indicator. */ + he_context_t *header_encryption_ctx_static; /* Header encryption cipher context. */ + he_context_t *header_encryption_ctx_dynamic; /* Header encryption cipher context. */ + he_context_t *header_iv_ctx_static; /* Header IV encryption cipher context, REMOVE as soon as separate fields for checksum and replay protection available */ + he_context_t *header_iv_ctx_dynamic; /* Header IV encryption cipher context, REMOVE as soon as separate fields for checksum and replay protection available */ + uint8_t dynamic_key[N2N_AUTH_CHALLENGE_SIZE]; /* dynamic key */ + struct peer_info *edges; /* Link list of registered edges. */ + node_supernode_association_t *assoc; /* list of other edges from this community and their supernodes */ + sn_user_t *allowed_users; /* list of allowed users */ + int64_t number_enc_packets; /* Number of encrypted packets handled so far, required for sorting from time to time */ + n2n_ip_subnet_t auto_ip_net; /* Address range of auto ip address service. */ + + UT_hash_handle hh; /* makes this structure hashable */ +}; + +/* Typedef'd pointer to get abstract datatype. */ +typedef struct regex_t* re_t; + +struct sn_community_regular_expression { + re_t rule; /* compiles regular expression */ + + UT_hash_handle hh; /* makes this structure hashable */ +}; + + +typedef struct n2n_tcp_connection { + int socket_fd; /* file descriptor for tcp socket */ + struct sockaddr sock; /* network order socket */ + + uint16_t expected; /* number of bytes expected to be read */ + uint16_t position; /* current position in the buffer */ + uint8_t buffer[N2N_PKT_BUF_SIZE + sizeof(uint16_t)]; /* buffer for data collected from tcp socket incl. prepended length */ + uint8_t inactive; /* connection not be handled if set, already closed and to be deleted soon */ + + UT_hash_handle hh; /* makes this structure hashable */ +} n2n_tcp_connection_t; + + +typedef struct n2n_sn { + int *keep_running; /* Pointer to sn loop stop/go flag */ + time_t start_time; /* Used to measure uptime. */ + n2n_version_t version; /* version string sent to edges along with PEER_INFO a.k.a. PONG */ + sn_stats_t stats; + int daemon; /* If non-zero then daemonise. */ + n2n_mac_t mac_addr; + uint16_t lport; /* Local UDP port to bind to. */ + uint16_t mport; /* Management UDP port to bind to. */ + int sock; /* Main socket for UDP traffic with edges. */ + int tcp_sock; /* auxiliary socket for optional TCP connections */ + n2n_tcp_connection_t *tcp_connections;/* list of established TCP connections */ + int mgmt_sock; /* management socket. */ + n2n_ip_subnet_t min_auto_ip_net; /* Address range of auto_ip service. */ + n2n_ip_subnet_t max_auto_ip_net; /* Address range of auto_ip service. */ +#ifndef WIN32 + uid_t userid; + gid_t groupid; +#endif + int lock_communities; /* If true, only loaded and matching communities can be used. */ + char *community_file; + struct sn_community *communities; + struct sn_community_regular_expression *rules; + struct sn_community *federation; + n2n_private_public_key_t private_key; /* private federation key derived from federation name */ + n2n_auth_t auth; + uint32_t dynamic_key_time; /* UTC time of last dynamic key generation (second accuracy) */ + uint8_t override_spoofing_protection; /* set if overriding MAC/IP spoofing protection (cli option '-M') */ + n2n_resolve_parameter_t *resolve_parameter;/*Pointer to name resolver's parameter block */ + uint64_t mgmt_password_hash;/* contains hash of managament port password */ +} n2n_sn_t; + + +/* *************************************************** */ + +#endif /* _N2N_TYPEDEFS_H_ */ diff --git a/bundles/n2n_ntop_v3/include/n2n_wire.h b/bundles/n2n_ntop_v3/include/n2n_wire.h new file mode 100644 index 00000000..62d30c61 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/n2n_wire.h @@ -0,0 +1,226 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#if !defined( N2N_WIRE_H_ ) +#define N2N_WIRE_H_ + +#include +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include +#endif + +#if defined(WIN32) +#include "n2n_win32.h" +#else /* #if defined(WIN32) */ +#include +#include /* AF_INET and AF_INET6 */ +#endif /* #if defined(WIN32) */ + +#include "sn_selection.h" + + +int encode_uint8 (uint8_t * base, + size_t * idx, + const uint8_t v); + +int decode_uint8 (uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_uint16 (uint8_t * base, + size_t * idx, + const uint16_t v); + +int decode_uint16 (uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_uint32 (uint8_t * base, + size_t * idx, + const uint32_t v); + +int decode_uint32 (uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_uint64 (uint8_t * base, + size_t * idx, + const uint64_t v); + +int decode_uint64 (uint64_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_buf (uint8_t * base, + size_t * idx, + const void * p, + size_t s); + +int decode_buf (uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_mac (uint8_t * base, + size_t * idx, + const n2n_mac_t m); + +int decode_mac (n2n_mac_t out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_cookie (uint8_t * base, + size_t * idx, + const n2n_cookie_t c); + +int decode_cookie (n2n_cookie_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_common (uint8_t * base, + size_t * idx, + const n2n_common_t * common); + +int decode_common (n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_sock (uint8_t * base, + size_t * idx, + const n2n_sock_t * sock); + +int decode_sock (n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_REGISTER (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_t * reg); + +int decode_REGISTER (n2n_REGISTER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_REGISTER_SUPER (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_SUPER_t * reg); + +int decode_REGISTER_SUPER (n2n_REGISTER_SUPER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_UNREGISTER_SUPER (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_UNREGISTER_SUPER_t *unreg); + +int decode_UNREGISTER_SUPER (n2n_UNREGISTER_SUPER_t *unreg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx); + +int encode_REGISTER_ACK (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_REGISTER_ACK_t * reg); + +int decode_REGISTER_ACK (n2n_REGISTER_ACK_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_REGISTER_SUPER_ACK (uint8_t * base, + size_t * idx, + const n2n_common_t * cmn, + const n2n_REGISTER_SUPER_ACK_t * reg, + uint8_t * tmpbuf); + +int decode_REGISTER_SUPER_ACK (n2n_REGISTER_SUPER_ACK_t * reg, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx, + uint8_t * tmpbuf); + +int encode_REGISTER_SUPER_NAK (uint8_t * base, + size_t * idx, + const n2n_common_t * cmn, + const n2n_REGISTER_SUPER_NAK_t * nak); + +int decode_REGISTER_SUPER_NAK (n2n_REGISTER_SUPER_NAK_t * nak, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int fill_sockaddr (struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock); + +int encode_PACKET (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt); + +int decode_PACKET (n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_PEER_INFO (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PEER_INFO_t * pkt); + +int decode_PEER_INFO (n2n_PEER_INFO_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +int encode_QUERY_PEER (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * pkt); + +int decode_QUERY_PEER (n2n_QUERY_PEER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx); + +#endif /* #if !defined( N2N_WIRE_H_ ) */ diff --git a/bundles/n2n_ntop_v3/include/network_traffic_filter.h b/bundles/n2n_ntop_v3/include/network_traffic_filter.h new file mode 100644 index 00000000..97de7ecd --- /dev/null +++ b/bundles/n2n_ntop_v3/include/network_traffic_filter.h @@ -0,0 +1,37 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +// +// Zhou Bin +// + +#ifndef N2N_NETWORK_TRAFFIC_FILTER_H +#define N2N_NETWORK_TRAFFIC_FILTER_H + +#include "n2n_typedefs.h" + +network_traffic_filter_t* create_network_traffic_filter (); + +void destroy_network_traffic_filter (network_traffic_filter_t* filter); + +void network_traffic_filter_add_rule (network_traffic_filter_t* filter, filter_rule_t* rules); + +//rule_str format: src_ip/len:[b_port,e_port],dst_ip/len:[s_port,e_port],TCP+/-,UDP+/-,ICMP+/- +uint8_t process_traffic_filter_rule_str (const char* rule_str, filter_rule_t* rule_struct); + +#endif //N2N_NETWORK_TRAFFIC_FILTER_H diff --git a/bundles/n2n_ntop_v3/include/pearson.h b/bundles/n2n_ntop_v3/include/pearson.h new file mode 100644 index 00000000..97d25002 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/pearson.h @@ -0,0 +1,36 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include +#include + +#include "portable_endian.h" + + +void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len); + +void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len); + +uint64_t pearson_hash_64 (const uint8_t *in, size_t len); + +uint32_t pearson_hash_32 (const uint8_t *in, size_t len); + +uint16_t pearson_hash_16 (const uint8_t *in, size_t len); + +void pearson_hash_init (); diff --git a/bundles/n2n_ntop_v3/include/portable_endian.h b/bundles/n2n_ntop_v3/include/portable_endian.h new file mode 100644 index 00000000..12a30b97 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/portable_endian.h @@ -0,0 +1,226 @@ +// taken from +// https://raw.githubusercontent.com/pyca/bcrypt/master/src/_csrc/portable_endian.h +// as of June 11, 2020 + +// "License": Public Domain +// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. +// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to +// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it +// an example on how to get the endian conversion functions on different platforms. + +#ifndef PORTABLE_ENDIAN_H__ +#define PORTABLE_ENDIAN_H__ + +#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) + +# define __WINDOWS__ + +#endif + +#if defined(__linux__) || defined(__CYGWIN__) +/* Define necessary macros for the header to expose all fields. */ +# if !defined(_BSD_SOURCE) +# define _BSD_SOURCE +# endif +# if !defined(__USE_BSD) +# define __USE_BSD +# endif +# if !defined(_DEFAULT_SOURCE) +# define _DEFAULT_SOURCE +# endif +# include +# include +/* See http://linux.die.net/man/3/endian */ +# if defined(htobe16) && defined(htole16) && defined(be16toh) && defined(le16toh) && defined(htobe32) && defined(htole32) && defined(be32toh) && defined(htole32) && defined(htobe64) && defined(htole64) && defined(htobe64) && defined(be64toh) && defined(htole64) && defined(le64toh) +/* Do nothing. The macros we need already exist. */ +# elif !defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9))) +# include +# if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) +# define htobe16(x) htons(x) +# define htole16(x) (x) +# define be16toh(x) ntohs(x) +# define le16toh(x) (x) + +# define htobe32(x) htonl(x) +# define htole32(x) (x) +# define be32toh(x) ntohl(x) +# define le32toh(x) (x) + +# define htobe64(x) (((uint64_t)htonl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htonl(((uint32_t)(x)))) << 32)) +# define htole64(x) (x) +# define be64toh(x) (((uint64_t)ntohl(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)ntohl(((uint32_t)(x)))) << 32)) +# define le64toh(x) (x) +# elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) +# define htobe16(x) (x) +# define htole16(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) +# define be16toh(x) (x) +# define le16toh(x) (((((uint16_t)(x)) >> 8))|((((uint16_t)(x)) << 8))) + +# define htobe32(x) (x) +# define htole32(x) (((uint32_t)htole16(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)htole16(((uint16_t)(x)))) << 16)) +# define be32toh(x) (x) +# define le32toh(x) (((uint32_t)le16toh(((uint16_t)(((uint32_t)(x)) >> 16)))) | (((uint32_t)le16toh(((uint16_t)(x)))) << 16)) + +# define htobe64(x) (x) +# define htole64(x) (((uint64_t)htole32(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)htole32(((uint32_t)(x)))) << 32)) +# define be64toh(x) (x) +# define le64toh(x) (((uint64_t)le32toh(((uint32_t)(((uint64_t)(x)) >> 32)))) | (((uint64_t)le32toh(((uint32_t)(x)))) << 32)) +# else +# error Byte Order not supported or not defined. +# endif +# endif + +#elif defined(__APPLE__) + +# include + +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htole16(x) OSSwapHostToLittleInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) + +# define htobe32(x) OSSwapHostToBigInt32(x) +# define htole32(x) OSSwapHostToLittleInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) + +# define htobe64(x) OSSwapHostToBigInt64(x) +# define htole64(x) OSSwapHostToLittleInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#elif defined(__OpenBSD__) + +# include + +#elif defined(__HAIKU__) + +# include + +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) + +# include + +# if !defined(be16toh) + # define be16toh(x) betoh16(x) + # define le16toh(x) letoh16(x) +# endif + +# if !defined(be32toh) + # define be32toh(x) betoh32(x) + # define le32toh(x) letoh32(x) +# endif + +# if !defined(be64toh) + # define be64toh(x) betoh64(x) + # define le64toh(x) letoh64(x) +# endif + +#elif defined(__WINDOWS__) + +# if BYTE_ORDER == LITTLE_ENDIAN + +# define htobe16(x) _byteswap_ushort(x) +# define htole16(x) (x) +# define be16toh(x) _byteswap_ushort(x) +# define le16toh(x) (x) + +# define htobe32(x) _byteswap_ulong(x) +# define htole32(x) (x) +# define be32toh(x) _byteswap_ulong(x) +# define le32toh(x) (x) + +# define htobe64(x) (((uint64_t)htobe32(((uint32_t)(((uint64_t)(x)) >> 32))) & 0x00000000FFFFFFFFULL) | (((uint64_t)htobe32(((uint32_t)(x)))) << 32)) +# define be64toh(x) (((uint64_t)be32toh(((uint32_t)(((uint64_t)(x)) >> 32))) & 0x00000000FFFFFFFFULL) | (((uint64_t)be32toh(((uint32_t)(x)))) << 32)) +# define htole64(x) (x) +# define le64toh(x) (x) + +# elif BYTE_ORDER == BIG_ENDIAN + + /* that would be xbox 360 */ +# define htobe16(x) (x) +# define htole16(x) __builtin_bswap16(x) +# define be16toh(x) (x) +# define le16toh(x) __builtin_bswap16(x) + +# define htobe32(x) (x) +# define htole32(x) __builtin_bswap32(x) +# define be32toh(x) (x) +# define le32toh(x) __builtin_bswap32(x) + +# define htobe64(x) (x) +# define htole64(x) __builtin_bswap64(x) +# define be64toh(x) (x) +# define le64toh(x) __builtin_bswap64(x) + +# else + +# error byte order not supported + +# endif + +# define __BYTE_ORDER BYTE_ORDER +# define __BIG_ENDIAN BIG_ENDIAN +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __PDP_ENDIAN PDP_ENDIAN + +#elif defined(__sun) + +# include + +# define htobe16(x) BE_16(x) +# define htole16(x) LE_16(x) +# define be16toh(x) BE_16(x) +# define le16toh(x) LE_16(x) + +# define htobe32(x) BE_32(x) +# define htole32(x) LE_32(x) +# define be32toh(x) BE_32(x) +# define le32toh(x) LE_32(x) + +# define htobe64(x) BE_64(x) +# define htole64(x) LE_64(x) +# define be64toh(x) BE_64(x) +# define le64toh(x) LE_64(x) + +#elif defined _AIX /* AIX is always big endian */ +# define be64toh(x) (x) +# define be32toh(x) (x) +# define be16toh(x) (x) +# define le32toh(x) \ + ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000) >> 8) | \ + (((x) & 0xff000000) >> 24)) +# define le64toh(x) \ + ((((x) & 0x00000000000000ffL) << 56) | \ + (((x) & 0x000000000000ff00L) << 40) | \ + (((x) & 0x0000000000ff0000L) << 24) | \ + (((x) & 0x00000000ff000000L) << 8) | \ + (((x) & 0x000000ff00000000L) >> 8) | \ + (((x) & 0x0000ff0000000000L) >> 24) | \ + (((x) & 0x00ff000000000000L) >> 40) | \ + (((x) & 0xff00000000000000L) >> 56)) +# ifndef htobe64 +# define htobe64(x) be64toh(x) +# endif +# ifndef htobe32 +# define htobe32(x) be32toh(x) +# endif +# ifndef htobe16 +# define htobe16(x) be16toh(x) +# endif + + +#else + +# error platform not supported + +#endif + +#endif diff --git a/bundles/n2n_ntop_v3/include/random_numbers.h b/bundles/n2n_ntop_v3/include/random_numbers.h new file mode 100644 index 00000000..55cc400a --- /dev/null +++ b/bundles/n2n_ntop_v3/include/random_numbers.h @@ -0,0 +1,69 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#ifndef RND_H +#define RND_H + + +#include +#include +#include /* time, clock */ + +#include "n2n.h" /* traceEvent */ + + +// syscall and inquiring random number from hardware generators might fail, so we will retry +#define RND_RETRIES 1000 + +#if defined (__linux__) +#include /* syscall, SYS_getrandom */ +#ifdef SYS_getrandom +#define GRND_NONBLOCK 1 +#include /* errno, EAGAIN */ +#endif +#endif + +#if defined (__RDRND__) || defined (__RDSEED__) +#include /* _rdrand64_step, rdseed4_step */ +#endif + +#if defined (WIN32) +#include // HCTYPTPROV, Crypt*-functions +#endif + + +typedef struct rn_generator_state_t { + uint64_t a, b; +} rn_generator_state_t; + +typedef struct splitmix64_state_t { + uint64_t s; +} splitmix64_state_t; + + +int n2n_srand (uint64_t seed); + +uint64_t n2n_rand (void); + +uint64_t n2n_seed (void); + +uint32_t n2n_rand_sqr (uint32_t max_n); + + +#endif // RND_H diff --git a/bundles/n2n_ntop_v3/include/sn_selection.h b/bundles/n2n_ntop_v3/include/sn_selection.h new file mode 100644 index 00000000..4f47f974 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/sn_selection.h @@ -0,0 +1,46 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifndef _SN_SELECTION_ +#define _SN_SELECTION_ + +typedef char selection_criterion_str_t[SN_SELECTION_CRITERION_BUF_SIZE]; + +#include "n2n.h" + +/* selection criterion's functions */ +int sn_selection_criterion_init (peer_info_t *peer); +int sn_selection_criterion_default (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); +int sn_selection_criterion_bad (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); +int sn_selection_criterion_good (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion); +int sn_selection_criterion_calculate (n2n_edge_t *eee, peer_info_t *peer, SN_SELECTION_CRITERION_DATA_TYPE *data); + +/* common data's functions */ +int sn_selection_criterion_common_data_default (n2n_edge_t *eee); + +/* sorting function */ +int sn_selection_sort (peer_info_t **peer_list); + +/* gathering data function */ +SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_gather_data (n2n_sn_t *sss); + +/* management port output function */ +extern char * sn_selection_criterion_str (n2n_edge_t *eee, selection_criterion_str_t out, peer_info_t *peer); + + +#endif /* _SN_SELECTION_ */ diff --git a/bundles/n2n_ntop_v3/include/speck.h b/bundles/n2n_ntop_v3/include/speck.h new file mode 100644 index 00000000..bf448fca --- /dev/null +++ b/bundles/n2n_ntop_v3/include/speck.h @@ -0,0 +1,142 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +// cipher SPECK -- 128 bit block size -- 128 and 256 bit key size -- CTR mode +// taken from (and modified: removed pure crypto-stream generation and seperated key expansion) +// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/ + + +#ifndef SPECK_H +#define SPECK_H + + +#include +#include + +#include "portable_endian.h" + + +#define u32 uint32_t +#define u64 uint64_t + +#define N2N_SPECK_IVEC_SIZE 16 +#define SPECK_KEY_BYTES (256/8) + + +#if defined (__AVX512F__) // AVX512 support ----------------------------------------------------------------------- + + +#include +#include /* memcpy() */ + +#define u512 __m512i + +#define SPECK_ALIGNED_CTX 64 + +typedef struct { + u512 rk[34]; + u64 key[34]; + u32 keysize; +} speck_context_t; + + +#elif defined (__AVX2__) // AVX2 support -------------------------------------------------------------------------- + + +#include + +#define u256 __m256i + +#define SPECK_ALIGNED_CTX 32 + +typedef struct { + u256 rk[34]; + u64 key[34]; + u32 keysize; +} speck_context_t; + + +#elif defined (__SSE2__) // SSE support --------------------------------------------------------------------------- + + +#include + +#define u128 __m128i + +#define SPECK_ALIGNED_CTX 16 +#define SPECK_CTX_BYVAL 1 + +typedef struct { + u128 rk[34]; + u64 key[34]; + u32 keysize; +} speck_context_t; + + +#elif defined (__ARM_NEON) && defined (SPECK_ARM_NEON) // NEON support --------------------------------------- + + +#include + +#define u128 uint64x2_t + +typedef struct { + u128 rk[34]; + u64 key[34]; + u32 keysize; +} speck_context_t; + + +#else // plain C -------------------------------------------------------------------------------------------------- + + +typedef struct { + u64 key[34]; + u32 keysize; +} speck_context_t; + + +#endif // --------------------------------------------------------------------------------------------------------- + + +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, + speck_context_t *ctx); + +int speck_init (speck_context_t **ctx, const unsigned char *k, int keysize); + +int speck_deinit (speck_context_t *ctx); + + +// ---------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------------- + + +// cipher SPECK -- 128 bit block size -- 128 bit key size -- ECB mode +// follows endianess rules as used in official implementation guide and NOT as in original 2013 cipher presentation +// used for IV in header encryption (one block) and challenge encryption (user/password) +// for now: just plain C -- probably no need for AVX, SSE, NEON + + +int speck_128_decrypt (unsigned char *inout, speck_context_t *ctx); + +int speck_128_encrypt (unsigned char *inout, speck_context_t *ctx); + + +#endif // SPECK_H diff --git a/bundles/n2n_ntop_v3/include/tf.h b/bundles/n2n_ntop_v3/include/tf.h new file mode 100644 index 00000000..e9353bb0 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/tf.h @@ -0,0 +1,87 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +// taken (and modified) from github/fudanchii/twofish as of August 2020 +// which itself is a modified copy of Andrew T. Csillag's implementation +// published on github/drewcsillag/twofish + + +/** + * The MIT License (MIT) + * + * Copyright (c) 2015 Andrew T. Csillag + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef TF_H +#define TF_H + + +#include +#include +#include + +#include "portable_endian.h" + + +#define TF_BLOCK_SIZE 16 +#define TF_IV_SIZE (TF_BLOCK_SIZE) + + +typedef struct tf_context_t { + int N; + uint32_t K[40]; + uint32_t QF[4][256]; +} tf_context_t; + + +int tf_ecb_decrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx); + +int tf_ecb_encrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx); + +int tf_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, tf_context_t *ctx); + +int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, tf_context_t *ctx); + +int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx); + +int tf_deinit (tf_context_t *ctx); + + +#endif // TF_H diff --git a/bundles/n2n_ntop_v3/include/uthash.h b/bundles/n2n_ntop_v3/include/uthash.h new file mode 100644 index 00000000..a790ea59 --- /dev/null +++ b/bundles/n2n_ntop_v3/include/uthash.h @@ -0,0 +1,1230 @@ +/* +Copyright (c) 2003-2018, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#define UTHASH_VERSION 2.1.0 + +#include /* memcmp, memset, strlen */ +#include /* ptrdiff_t */ +#include /* exit */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) +#if defined(_MSC_VER) /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#endif +#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) +#define NO_DECLTYPE +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE(x) +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while (0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while (0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */ +#if defined(_WIN32) +#if defined(_MSC_VER) && _MSC_VER >= 1600 +#include +#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif +#elif defined(__GNUC__) && !defined(__VXWORKS__) +#include +#else +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#endif + +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif +#ifndef uthash_bzero +#define uthash_bzero(a,n) memset(a,'\0',n) +#endif +#ifndef uthash_strlen +#define uthash_strlen(s) strlen(s) +#endif + +#ifdef uthash_memcmp +/* This warning will not catch programs that define uthash_memcmp AFTER including uthash.h. */ +#warning "uthash_memcmp is deprecated; please use HASH_KEYCMP instead" +#else +#define uthash_memcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifndef HASH_KEYCMP +#define HASH_KEYCMP(a,b,n) uthash_memcmp(a,b,n) +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +#ifndef HASH_NONFATAL_OOM +#define HASH_NONFATAL_OOM 0 +#endif + +#if HASH_NONFATAL_OOM +/* malloc failures can be recovered from */ + +#ifndef uthash_nonfatal_oom +#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) +#define IF_HASH_NONFATAL_OOM(x) x + +#else +/* malloc failures result in lost memory, hash tables are unusable */ + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ +#endif + +#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") +#define IF_HASH_NONFATAL_OOM(x) + +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhp */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) +/* calculate the hash handle from element address elp */ +#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle *)(((char*)(elp)) + ((tbl)->hho))) + +#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ + unsigned _hd_bkt; \ + HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + (head)->hh.tbl->buckets[_hd_bkt].count++; \ + _hd_hh_item->hh_next = NULL; \ + _hd_hh_item->hh_prev = NULL; \ +} while (0) + +#define HASH_VALUE(keyptr,keylen,hashv) \ +do { \ + HASH_FCN(keyptr, keylen, hashv); \ +} while (0) + +#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_bkt; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ + } \ + } \ +} while (0) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + (out) = NULL; \ + if (head) { \ + unsigned _hf_hashv; \ + HASH_VALUE(keyptr, keylen, _hf_hashv); \ + HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) +#define HASH_BLOOM_MAKE(tbl,oomed) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!(tbl)->bloom_bv) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ + } \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) + +#else +#define HASH_BLOOM_MAKE(tbl,oomed) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0U +#endif + +#define HASH_MAKE_TABLE(hh,head,oomed) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ + if (!(head)->hh.tbl) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ + if (!(head)->hh.tbl->buckets) { \ + HASH_RECORD_OOM(oomed); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } else { \ + uthash_bzero((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + uthash_free((head)->hh.tbl->buckets, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + } \ + ) \ + } \ + } \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ +} while (0) + +#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ +do { \ + (replaced) = NULL; \ + HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ + if (replaced) { \ + HASH_DELETE(hh, head, replaced); \ + } \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ +} while (0) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ +} while (0) + +#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ +do { \ + unsigned _hr_hashv; \ + HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ + HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ +} while (0) + +#define HASH_APPEND_LIST(hh, head, add) \ +do { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail->next = (add); \ + (head)->hh.tbl->tail = &((add)->hh); \ +} while (0) + +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + do { \ + if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ + break; \ + } \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) + +#ifdef NO_DECLTYPE +#undef HASH_AKBI_INNER_LOOP +#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ +do { \ + char *_hs_saved_head = (char*)(head); \ + do { \ + DECLTYPE_ASSIGN(head, _hs_iter); \ + if (cmpfcn(head, add) > 0) { \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + break; \ + } \ + DECLTYPE_ASSIGN(head, _hs_saved_head); \ + } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ +} while (0) +#endif + +#if HASH_NONFATAL_OOM + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + if (!(oomed)) { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + if (oomed) { \ + HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ + HASH_DELETE_HH(hh, head, &(add)->hh); \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } else { \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ + } \ + } else { \ + (add)->hh.tbl = NULL; \ + uthash_nonfatal_oom(add); \ + } \ +} while (0) + +#else + +#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ +do { \ + unsigned _ha_bkt; \ + (head)->hh.tbl->num_items++; \ + HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ + HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ + HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ +} while (0) + +#endif + + +#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + void *_hs_iter = (head); \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ + if (_hs_iter) { \ + (add)->hh.next = _hs_iter; \ + if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ + HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ + } else { \ + (head) = (add); \ + } \ + HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ + } else { \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ +} while (0) + +#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ +do { \ + unsigned _hs_hashv; \ + HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ + HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) + +#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ + HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) + +#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ +do { \ + IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ + (add)->hh.hashv = (hashval); \ + (add)->hh.key = (char*) (keyptr); \ + (add)->hh.keylen = (unsigned) (keylen_in); \ + if (!(head)) { \ + (add)->hh.next = NULL; \ + (add)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh, add, _ha_oomed); \ + IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ + (head) = (add); \ + IF_HASH_NONFATAL_OOM( } ) \ + } else { \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_APPEND_LIST(hh, head, add); \ + } \ + HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ + HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ +} while (0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_hashv; \ + HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ +} while (0) + +#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ + HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) + +#define HASH_TO_BKT(hashv,num_bkts,bkt) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1U)); \ +} while (0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ + HASH_DELETE_HH(hh, head, &(delptr)->hh) + +#define HASH_DELETE_HH(hh,head,delptrhh) \ +do { \ + struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } else { \ + unsigned _hd_bkt; \ + if (_hd_hh_del == (head)->hh.tbl->tail) { \ + (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ + } \ + if (_hd_hh_del->prev != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ + } else { \ + DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ + } \ + if (_hd_hh_del->next != NULL) { \ + HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ + } \ + HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ +} while (0) + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ +do { \ + unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ + HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ +} while (0) +#define HASH_ADD_STR(head,strfield,add) \ +do { \ + unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ +} while (0) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ +do { \ + unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ + HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ +} while (0) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head,where) \ +do { \ + struct UT_hash_handle *_thh; \ + if (head) { \ + unsigned _bkt_i; \ + unsigned _count = 0; \ + char *_prev; \ + for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ + unsigned _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ + (where), (void*)_thh->hh_prev, (void*)_prev); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ + (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev != (char*)_thh->prev) { \ + HASH_OOPS("%s: invalid prev %p, actual %p\n", \ + (where), (void*)_thh->prev, (void*)_prev); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ + (where), (head)->hh.tbl->num_items, _count); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head,where) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ +#define HASH_BER(key,keylen,hashv) \ +do { \ + unsigned _hb_keylen = (unsigned)keylen; \ + const unsigned char *_hb_key = (const unsigned char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen-- != 0U) { \ + (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ + } \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,hashv) \ +do { \ + unsigned _sx_i; \ + const unsigned char *_hs_key = (const unsigned char*)(key); \ + hashv = 0; \ + for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + } \ +} while (0) +/* FNV-1a variation */ +#define HASH_FNV(key,keylen,hashv) \ +do { \ + unsigned _fn_i; \ + const unsigned char *_hf_key = (const unsigned char*)(key); \ + (hashv) = 2166136261U; \ + for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ + hashv = hashv ^ _hf_key[_fn_i]; \ + hashv = hashv * 16777619U; \ + } \ +} while (0) + +#define HASH_OAT(key,keylen,hashv) \ +do { \ + unsigned _ho_i; \ + const unsigned char *_ho_key=(const unsigned char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ +} while (0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,hashv) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned const char *_hj_key=(unsigned const char*)(key); \ + hashv = 0xfeedbeefu; \ + _hj_i = _hj_j = 0x9e3779b9u; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12U) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12U; \ + } \ + hashv += (unsigned)(keylen); \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ + case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ +} while (0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,hashv) \ +do { \ + unsigned const char *_sfh_key=(unsigned const char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ + \ + unsigned _sfh_rem = _sfh_len & 3U; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabeu; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0U; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2U*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ +} while (0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 3UL) == 0UL) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 3UL) == 1UL) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6bu; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35u; \ + _h ^= _h >> 16; \ +} while (0) + +#define HASH_MUR(key,keylen,hashv) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (int)(keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353u; \ + uint32_t _mur_c1 = 0xcc9e2d51u; \ + uint32_t _mur_c2 = 0x1b873593u; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \ + int _mur_i; \ + for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \ + _mur_k1=0; \ + switch ((keylen) & 3U) { \ + case 0: break; \ + case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \ + case 2: _mur_k1 ^= (uint32_t)_mur_tail[1] << 8; /* FALLTHROUGH */ \ + case 1: _mur_k1 ^= (uint32_t)_mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (uint32_t)(keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ +} while (0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ +do { \ + if ((head).hh_head != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ + } else { \ + (out) = NULL; \ + } \ + while ((out) != NULL) { \ + if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ + if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ + break; \ + } \ + } \ + if ((out)->hh.hh_next != NULL) { \ + DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ + } else { \ + (out) = NULL; \ + } \ + } \ +} while (0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ +do { \ + UT_hash_bucket *_ha_head = &(head); \ + _ha_head->count++; \ + (addhh)->hh_next = _ha_head->hh_head; \ + (addhh)->hh_prev = NULL; \ + if (_ha_head->hh_head != NULL) { \ + _ha_head->hh_head->hh_prev = (addhh); \ + } \ + _ha_head->hh_head = (addhh); \ + if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ + && !(addhh)->tbl->noexpand) { \ + HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (oomed) { \ + HASH_DEL_IN_BKT(head,addhh); \ + } \ + ) \ + } \ +} while (0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(head,delhh) \ +do { \ + UT_hash_bucket *_hd_head = &(head); \ + _hd_head->count--; \ + if (_hd_head->hh_head == (delhh)) { \ + _hd_head->hh_head = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_prev) { \ + (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ + } \ + if ((delhh)->hh_next) { \ + (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ + } \ +} while (0) + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { \ + HASH_RECORD_OOM(oomed); \ + } else { \ + uthash_bzero(_he_new_buckets, \ + 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->ideal_chain_maxlen = \ + ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ + ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ + (tbl)->nonideal_items = 0; \ + for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ + _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh != NULL) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[_he_bkt]); \ + if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ + (tbl)->nonideal_items++; \ + if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ + _he_newbkt->expand_mult++; \ + } \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head != NULL) { \ + _he_newbkt->hh_head->hh_prev = _he_thh; \ + } \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ + (tbl)->num_buckets *= 2U; \ + (tbl)->log2_num_buckets++; \ + (tbl)->buckets = _he_new_buckets; \ + (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ + ((tbl)->ineff_expands+1U) : 0U; \ + if ((tbl)->ineff_expands > 1U) { \ + (tbl)->noexpand = 1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ + } \ +} while (0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head != NULL) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping != 0U) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p != NULL) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ + _hs_psize++; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + if (_hs_q == NULL) { \ + break; \ + } \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ + if (_hs_psize == 0U) { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else if ((cmpfcn( \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ + )) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p != NULL) { \ + _hs_p = ((_hs_p->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = ((_hs_q->next != NULL) ? \ + HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail != NULL ) { \ + _hs_tail->next = ((_hs_e != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e != NULL) { \ + _hs_e->prev = ((_hs_tail != NULL) ? \ + ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail != NULL) { \ + _hs_tail->next = NULL; \ + } \ + if (_hs_nmerges <= 1U) { \ + _hs_looping = 0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2U; \ + } \ + HASH_FSCK(hh, head, "HASH_SRT"); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt = NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if ((src) != NULL) { \ + for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh != NULL; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh != NULL) { \ + _last_elt_hh->next = _elt; \ + } \ + if ((dst) == NULL) { \ + DECLTYPE_ASSIGN(dst, _elt); \ + HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + uthash_nonfatal_oom(_elt); \ + (dst) = NULL; \ + continue; \ + } \ + ) \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ + (dst)->hh_dst.tbl->num_items++; \ + IF_HASH_NONFATAL_OOM( \ + if (_hs_oomed) { \ + HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ + HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ + _dst_hh->tbl = NULL; \ + uthash_nonfatal_oom(_elt); \ + continue; \ + } \ + ) \ + HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if ((head) != NULL) { \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head) = NULL; \ + } \ +} while (0) + +#define HASH_OVERHEAD(hh,head) \ + (((head) != NULL) ? ( \ + (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + sizeof(UT_hash_table) + \ + (HASH_BLOOM_BYTELEN))) : 0U) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ + (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1u +#define HASH_BLOOM_SIGNATURE 0xb12220f2u + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + uint8_t bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/bundles/n2n_ntop_v3/legacy/README.md b/bundles/n2n_ntop_v3/legacy/README.md new file mode 100644 index 00000000..174c1146 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/README.md @@ -0,0 +1,33 @@ +# Removed Features + +This folder contains a list N2N legacy features which have been dropped due to +maintainance cost versus effective use and benefits. + +Multiple Transops +----------------- + +N2N used to initialize all the available transops and use the "tick" function of +the transops to decide which transop to use before sending a packet. This however +has the following problems: + +- It only works with the keyfile, whereas with normal encryption we inizialize and + keep structures that we don't need. +- It is unfeasable as an edge node is required to implement all the transops in order + to properly talk with other edge nodes (via keyfile). +- It rises the complexity of the code. +- It is not clear which transop will be used. +- Mixing multiple encyptions together is not necessarily a good idea to improve security + as a vulnerability in at least one encryption method will leak some information. + +Keyfile and Key Rotation +------------------------ + +The keyfile mechanism allowed N2N users to specify a keyfile to be used to periodically +rotate keys and encryption methods. However, it has the following problems: + +- This feature is obscure for most of the users and poorly documented. +- It is tightly integrated in the core whereas it is used by only a few people (if any). + +In conclusion the main problem is the complexity that it adds to the code. In a possible +future rework this could be integrated as an extention (e.g. a specific trasop) without +rising the core complexity. diff --git a/bundles/n2n_ntop_v3/legacy/edge_keyschedule.c b/bundles/n2n_ntop_v3/legacy/edge_keyschedule.c new file mode 100644 index 00000000..5e3af35d --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/edge_keyschedule.c @@ -0,0 +1,103 @@ +typedef struct n2n_tostat { + uint8_t can_tx; /* Does this transop have a valid SA for encoding. */ + n2n_cipherspec_t tx_spec; /* If can_tx, the spec used to encode. */ +} n2n_tostat_t; + +typedef uint32_t n2n_sa_t; /* security association number */ +typedef int (*n2n_transaddspec_f)( struct n2n_trans_op * arg, + const n2n_cipherspec_t * cspec ); + +typedef n2n_tostat_t (*n2n_transtick_f)( struct n2n_trans_op * arg, + time_t now ); + +/** Read in a key-schedule file, parse the lines and pass each line to the + * appropriate trans_op for parsing of key-data and adding key-schedule + * entries. The lookup table of time->trans_op is constructed such that + * encoding can be passed to the correct trans_op. The trans_op internal table + * will then determine the best SA for that trans_op from the key schedule to + * use for encoding. */ + +static int edge_init_keyschedule(n2n_edge_t *eee) { +#define N2N_NUM_CIPHERSPECS 32 + + int retval = -1; + ssize_t numSpecs=0; + n2n_cipherspec_t specs[N2N_NUM_CIPHERSPECS]; + size_t i; + time_t now = time(NULL); + + numSpecs = n2n_read_keyfile(specs, N2N_NUM_CIPHERSPECS, eee->conf.keyschedule); + + if(numSpecs > 0) + { + traceEvent(TRACE_NORMAL, "keyfile = %s read -> %d specs.\n", optarg, (signed int)numSpecs); + + for (i=0; i < (size_t)numSpecs; ++i) + { + n2n_transform_t idx = (n2n_transform_t) specs[i].t; + if(idx != eee->transop.transform_id) { + traceEvent(TRACE_ERROR, "changing transop in keyschedule is not supported"); + retval = -1; + } + + if(eee->transop.addspec != NULL) + retval = eee->transop.addspec(&eee->transop, &(specs[i])); + + if (0 != retval) + { + traceEvent(TRACE_ERROR, "keyschedule failed to add spec[%u] to transop[%d].\n", + (unsigned int)i, idx); + + return retval; + } + } + + n2n_tick_transop(eee, now); + } + else + traceEvent(TRACE_ERROR, "Failed to process '%s'", eee->conf.keyschedule); + + return retval; +} + +#if 0 + if(recvlen >= 6) + { + if(0 == memcmp(udp_buf, "reload", 6)) + { + if(strlen(eee->conf.keyschedule) > 0) + { + if(edge_init_keyschedule(eee) == 0) + { + msg_len=0; + msg_len += snprintf((char *)(udp_buf+msg_len), (N2N_PKT_BUF_SIZE-msg_len), + "> OK\n"); + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *)&sender_sock, sizeof(struct sockaddr_in)); + } + return; + } + } + } +#endif + +#if 0 + case'K': + { + if(conf->encrypt_key) { + traceEvent(TRACE_ERROR, "Error: -K and -k options are mutually exclusive"); + exit(1); + } else { + strncpy(conf->keyschedule, optargument, N2N_PATHNAME_MAXLEN-1); + /* strncpy does not add NULL if the source has no NULL. */ + conf->keyschedule[N2N_PATHNAME_MAXLEN-1] = 0; + + traceEvent(TRACE_NORMAL, "keyfile = '%s'\n", conf->keyschedule); + } + break; + } +#endif + +#if 0 + printf("-K | Specify a key schedule file to load. Not with -k.\n"); +#endif diff --git a/bundles/n2n_ntop_v3/legacy/gen_keyfile.py b/bundles/n2n_ntop_v3/legacy/gen_keyfile.py new file mode 100644 index 00000000..b6dc3e67 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/gen_keyfile.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + +# (c) 2009 Richard Andrews + +# Program to generate a n2n_edge key schedule file for twofish keys +# Each key line consists of the following element +# +# +# where , are UNIX time_t values of key valid period +# is the transform ID (=2 for twofish) +# is twofish-specific data as follows +# _ + +import os +import sys +import time +import random + +NUM_KEYS=30 +KEY_LIFE=300 +KEY_LEN=16 + +now=time.time() +start_sa=random.randint( 0, 0xffffffff ) + +random.seed(now) # note now is a floating point time value + +def rand_key(): + key=str() + for i in range(0,KEY_LEN): + key += "%02x"%( random.randint( 0, 255) ) + + return key + +for i in range(0,NUM_KEYS): + from_time = now + (KEY_LIFE * (i-1) ) + until_time = now + (KEY_LIFE * (i+1) ) + key = rand_key() + sa_idx = start_sa + i + transform_id = random.randint( 2, 3 ) + + sys.stdout.write("%d %d %d %d_%s\n"%(from_time, until_time, transform_id,sa_idx, key) ) + + diff --git a/bundles/n2n_ntop_v3/legacy/n2n_keyfile.c b/bundles/n2n_ntop_v3/legacy/n2n_keyfile.c new file mode 100644 index 00000000..eda6c834 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/n2n_keyfile.c @@ -0,0 +1,216 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_keyfile.h" +#include +#include +#include +#include + + +#ifdef WIN32 +char *strsep( char **ppsz_string, const char *psz_delimiters ) +{ + char *p; + char *psz_string = *ppsz_string; + if( !psz_string ) + return NULL; + + p = strpbrk( psz_string, psz_delimiters ); + if( !p ) + { + *ppsz_string = NULL; + return psz_string; + } + *p++ = '\0'; + + *ppsz_string = p; + return psz_string; +} +#endif + + +/* Parse hex nibbles in ascii until a non-nibble character is found. Nibble + * characters are 0-9, a-f and A-F. + * + * Return number of bytes parsed into keyBuf or a negative error code. + */ +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyLen, + const char * textKey, + size_t textLen) +{ + ssize_t retval=0; + uint8_t * pout=keyBuf; + size_t octet=0; + const char * textEnd; + const char * pbeg; + + textEnd = textKey+textLen; + pbeg=textKey; + + while ( ( pbeg + 1 < textEnd ) && ( retval < (ssize_t)keyLen ) ) + { + if ( 1 != sscanf( pbeg, "%02x", (unsigned int*)&octet ) ) + { + retval=-1; + break; + } + + *pout = (octet & 0xff); + ++pout; + ++retval; + pbeg += 2; + } + + return retval; +} + + +static int parseKeyLine( n2n_cipherspec_t * spec, + const char * linein ) +{ + /* parameters are separated by whitespace */ + char line[N2N_KEYFILE_LINESIZE]; + char * lp=line; + const char * token; + strncpy( line, linein, N2N_KEYFILE_LINESIZE ); + + memset( spec, 0, sizeof( n2n_cipherspec_t ) ); + + /* decode valid_from time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_from = atol(token); + + /* decode valid_until time */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->valid_until = atol(token); + + /* decode the transform number */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + spec->t = atoi(token); + + /* The reset if opaque key data */ + token = strsep( &lp, DELIMITERS ); + if ( !token ) { goto error; } + strncpy( (char *)spec->opaque, token, N2N_MAX_KEYSIZE ); + spec->opaque_size=strlen( (char *)spec->opaque); + + return 0; + +error: + return -1; +} + + +#define SEP "/" + + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ) +{ + if ( k->valid_until < k->valid_from ) { goto bad; } + if ( k->valid_from > now ) { goto bad; } + if ( k->valid_until < now ) { goto bad; } + + return 0; + +bad: + return -1; +} + +/* Read key control file and return the number of specs stored or a negative + * error code. + * + * As the specs are read in the from and until time values are compared to + * present time. Only those keys which are valid are stored. + */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ) /* path to control file */ +{ + /* Each line contains one cipherspec. */ + + int retval=0; + FILE * fp=NULL; + size_t idx=0; + time_t now = time(NULL); + + traceEvent( TRACE_DEBUG, "Reading '%s'\n", ctrlfile_path ); + + fp = fopen( ctrlfile_path, "r" ); + if ( fp ) + { + /* Read the file a line a time with fgets. */ + char line[N2N_KEYFILE_LINESIZE]; + size_t lineNum=0; + + while ( idx < numspecs ) + { + n2n_cipherspec_t * k = &(specs[idx]); + fgets( line, N2N_KEYFILE_LINESIZE, fp ); + ++lineNum; + + if ( strlen(line) > 1 ) + { + if ( 0 == parseKeyLine( k, line ) ) + { + if ( k->valid_until > now ) + { + traceEvent( TRACE_INFO, " --> [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + ++retval; + ++idx; + } + else + { + traceEvent( TRACE_INFO, " --X [%u] from %lu, until %lu, transform=%hu, data=%s\n", + idx, k->valid_from, k->valid_until, k->t, k->opaque ); + + } + } + else + { + traceEvent( TRACE_WARNING, "Failed to decode line %u\n", lineNum ); + } + } + + if ( feof(fp) ) + { + break; + } + + line[0]=0; /* this line has been consumed */ + } + + fclose( fp); + fp=NULL; + } + else + { + traceEvent( TRACE_ERROR, "Failed to open '%s'\n", ctrlfile_path ); + retval = -1; + } + + return retval; +} diff --git a/bundles/n2n_ntop_v3/legacy/n2n_keyfile.h b/bundles/n2n_ntop_v3/legacy/n2n_keyfile.h new file mode 100644 index 00000000..05cdf606 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/n2n_keyfile.h @@ -0,0 +1,117 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/** Key files + * + * Edge implements a very simple interface for getting instructions about + * rolling keys. + * + * Key definitions are written as individual files in /.key. The + * format of each key is a single line of hex nibbles as follows: + * + * 0102030405060708090a0b0c0d0e0f + * + * Any external key exchange mechanism can receive the key data write it into + * the keyfiles. + * + * To control which keys are active at what times the key control file is + * used. This is a single file which is periodically reread. It contains key + * definitions in chronological order with one line per key definition as + * follows: + * + * + * + * edge reads the key control file periodically to get updates in policy. edge + * holds a number of keys in memory. Data can be decoded if it was encoded by + * any of the keys still in memory. By having at least 2 keys in memory it + * allows for clock skew and transmission delay when encoder and decoder roll + * keys at slightly different times. The amount of overlap in the valid time + * ranges provides the tolerance to timing skews in the system. + * + * The keys have the same level of secrecy as any other user file. Existing + * UNIX permission systems can be used to provide access controls. + * + */ + +/** How Edge Uses The Key Schedule + * + * Edge provides state space for a number of transform algorithms. Each + * transform uses its state space to store the SA information for its keys as + * found in the key file. When a packet is received the transform ID is in + * plain text. The packets is then sent to that transform for decoding. Each + * transform can store its SA numbers differently (or not at all). The + * transform code then finds the SA number, then finds the cipher (with key) in + * the state space and uses this to decode the packet. + * + * To support this, as edge reads each key line, it passes it to the + * appropriate transform to parse the line and store the SA information in its + * state space. + * + * When encoding a packet, edge has several transforms and potentially valid + * SAs to choose from. To keep track of which one to use for encoding edge does + * its own book-keeping as each key line is passed to the transform code: it + * stores a lookup of valid_from -> transform. When encoding a packet it then + * just calls the transform with the best valid_from in the table. The + * transform's own state space has all the SAs for its keys and the best of + * those is chosen. + */ + +#if !defined( N2N_KEYFILE_H_ ) +#define N2N_KEYFILE_H_ + + +#include "n2n_wire.h" +#include + +#define N2N_MAX_KEYSIZE 256 /* bytes */ +#define N2N_MAX_NUM_CIPHERSPECS 8 +#define N2N_KEYPATH_SIZE 256 +#define N2N_KEYFILE_LINESIZE 256 + +/** This structure stores an encryption cipher spec. */ +struct n2n_cipherspec +{ + n2n_transform_t t; /* N2N_TRANSFORM_ID_xxx for this spec. */ + time_t valid_from; /* Start using the key at this time. */ + time_t valid_until; /* Key is valid if time < valid_until. */ + uint16_t opaque_size; /* Size in bytes of key. */ + uint8_t opaque[N2N_MAX_KEYSIZE];/* Key matter. */ +}; + +typedef struct n2n_cipherspec n2n_cipherspec_t; + + +static const char * const DELIMITERS=" \t\n\r"; + + +/** @return number of cipherspec items filled. */ +int n2n_read_keyfile( n2n_cipherspec_t * specs, /* fill out this array of cipherspecs */ + size_t numspecs, /* number of slots in the array. */ + const char * ctrlfile_path ); /* path to control file */ + +int validCipherSpec( const n2n_cipherspec_t * k, + time_t now ); + +ssize_t n2n_parse_hex( uint8_t * keyBuf, + size_t keyMax, + const char * textKey, + size_t textLen ); + +/*----------------------------------------------------------------------------*/ + +#endif /* #if !defined( N2N_KEYFILE_H_ ) */ diff --git a/bundles/n2n_ntop_v3/legacy/transform_aes.c b/bundles/n2n_ntop_v3/legacy/transform_aes.c new file mode 100644 index 00000000..7b198ff4 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/transform_aes.c @@ -0,0 +1,730 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" + +#if defined(N2N_HAVE_AES) + +#include "openssl/aes.h" +#include "openssl/sha.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_AES_NUM_SA 32 /* space for SAa */ + +#define N2N_AES_TRANSFORM_VERSION 1 /* version of the transform encoding */ +#define N2N_AES_IVEC_SIZE 32 /* Enough space for biggest AES ivec */ + +#define AES256_KEY_BYTES (256/8) +#define AES192_KEY_BYTES (192/8) +#define AES128_KEY_BYTES (128/8) + +typedef unsigned char n2n_aes_ivec_t[N2N_AES_IVEC_SIZE]; + +struct sa_aes +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + AES_KEY enc_key; /* tx key */ + AES_KEY dec_key; /* tx key */ + AES_KEY iv_enc_key; /* key used to encrypt the IV */ + uint8_t iv_ext_val[AES128_KEY_BYTES]; /* key used to extend the random IV seed to full block size */ +}; + +typedef struct sa_aes sa_aes_t; + + +/** Aes transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for aes + * consists of the SA number and key material. + * + */ +struct transop_aes +{ + ssize_t tx_sa; + size_t num_sa; + sa_aes_t sa[N2N_AES_NUM_SA]; + u_int8_t psk_mode; +}; + +typedef struct transop_aes transop_aes_t; + +static ssize_t aes_find_sa( const transop_aes_t * priv, const n2n_sa_t req_id ); +static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size, size_t sa_num); + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t aes_choose_tx_sa( transop_aes_t * priv, const u_int8_t * peer_mac ) { + return priv->tx_sa; /* set in tick */ +} + +static ssize_t aes_choose_rx_sa( transop_aes_t * priv, const u_int8_t * peer_mac, ssize_t sa_rx) { + if(!priv->psk_mode) + return aes_find_sa(priv, sa_rx); + else + /* NOTE the sa_rx of the packet is ignored in this case */ + return 0; +} + +/* AES plaintext preamble */ +#define TRANSOP_AES_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_AES_SA_SIZE 4 +#define TRANSOP_AES_IV_SEED_SIZE 8 +#define TRANSOP_AES_PREAMBLE_SIZE (TRANSOP_AES_VER_SIZE + TRANSOP_AES_SA_SIZE + TRANSOP_AES_IV_SEED_SIZE) + +/* AES ciphertext preamble */ +#define TRANSOP_AES_NONCE_SIZE 4 + +/* Return the best acceptable AES key size (in bytes) given an input keysize. + * + * The value returned will be one of AES128_KEY_BYTES, AES192_KEY_BYTES or + * AES256_KEY_BYTES. + */ +static size_t aes_best_keysize(size_t numBytes) +{ + if (numBytes >= AES256_KEY_BYTES ) + { + return AES256_KEY_BYTES; + } + else if (numBytes >= AES192_KEY_BYTES) + { + return AES192_KEY_BYTES; + } + else + { + return AES128_KEY_BYTES; + } +} + +static void set_aes_cbc_iv(sa_aes_t *sa, n2n_aes_ivec_t ivec, uint64_t iv_seed) { + uint8_t iv_full[AES_BLOCK_SIZE]; + + /* Extend the seed to full block size via the fixed ext value */ + memcpy(iv_full, sa->iv_ext_val, sizeof(iv_seed)); // note: only 64bits used of 128 available + memcpy(iv_full + sizeof(iv_seed), &iv_seed, sizeof(iv_seed)); + + /* Encrypt the IV with secret key to make it unpredictable. + * As discussed in https://github.com/ntop/n2n/issues/72, it's important to + * have an unpredictable IV since the initial part of the packet plaintext + * can be easily reconstructed from plaintext headers and used by an attacker + * to perform differential analysis. + */ + AES_ecb_encrypt(iv_full, ivec, &sa->iv_enc_key, AES_ENCRYPT); +} + +/** The aes packet format consists of: + * + * - a 8-bit aes encoding version in clear text + * - a 32-bit SA number in clear text + * - a 64-bit random IV seed + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|II|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len2=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE] = {0}; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_AES_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_AES_NONCE_SIZE + TRANSOP_AES_PREAMBLE_SIZE) <= out_len ) + { + int len=-1; + size_t idx=0; + sa_aes_t * sa; + size_t tx_sa_num = 0; + uint64_t iv_seed = 0; + uint8_t padding = 0; + n2n_aes_ivec_t enc_ivec = {0}; + + /* The transmit sa is periodically updated */ + tx_sa_num = aes_choose_tx_sa( priv, peer_mac ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_aes %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the aes format version. */ + encode_uint8( outbuf, &idx, N2N_AES_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* Generate and encode the IV seed. + * Using two calls to rand() because RAND_MAX is usually < 64bit + * (e.g. linux) and sometimes < 32bit (e.g. Windows). + */ + ((uint32_t*)&iv_seed)[0] = rand(); + ((uint32_t*)&iv_seed)[1] = rand(); + encode_buf(outbuf, &idx, &iv_seed, sizeof(iv_seed)); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = in_len + TRANSOP_AES_NONCE_SIZE; + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_AES_NONCE_SIZE, inbuf, in_len ); + + /* Need at least one encrypted byte at the end for the padding. */ + len2 = ( (len / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; /* Round up to next whole AES adding at least one byte. */ + padding = (len2-len); + assembly[len2 - 1] = padding; + traceEvent( TRACE_DEBUG, "padding = %u, seed = %016lx", padding, iv_seed ); + + set_aes_cbc_iv(sa, enc_ivec, iv_seed); + + AES_cbc_encrypt( assembly, /* source */ + outbuf + TRANSOP_AES_PREAMBLE_SIZE, /* dest */ + len2, /* enc size */ + &(sa->enc_key), enc_ivec, AES_ENCRYPT ); + + len2 += TRANSOP_AES_PREAMBLE_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_aes outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_aes inbuf too big to encrypt." ); + } + + return len2; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t aes_find_sa( const transop_aes_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_aes_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/* See transop_encode_aes for packet format */ +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=0; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - TRANSOP_AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_AES_PREAMBLE_SIZE + TRANSOP_AES_NONCE_SIZE) ) /* Has at least version, SA, iv seed and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t aes_enc_ver=0; + uint64_t iv_seed=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &aes_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_AES_TRANSFORM_VERSION == aes_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = aes_choose_rx_sa(priv, peer_mac, sa_rx); + + if ( sa_idx >= 0 ) + { + sa_aes_t * sa = &(priv->sa[sa_idx]); + + /* Get the IV seed */ + decode_buf((uint8_t *)&iv_seed, sizeof(iv_seed), inbuf, &rem, &idx); + + traceEvent( TRACE_DEBUG, "decode_aes %lu with SA %lu and seed %016lx", in_len, sa->sa_id, iv_seed ); + + len = (in_len - TRANSOP_AES_PREAMBLE_SIZE); + + if ( 0 == (len % AES_BLOCK_SIZE ) ) + { + uint8_t padding; + n2n_aes_ivec_t dec_ivec = {0}; + + set_aes_cbc_iv(sa, dec_ivec, iv_seed); + + AES_cbc_encrypt( (inbuf + TRANSOP_AES_PREAMBLE_SIZE), + assembly, /* destination */ + len, + &(sa->dec_key), + dec_ivec, AES_DECRYPT ); + + /* last byte is how much was padding: max value should be + * AES_BLOCKSIZE-1 */ + padding = assembly[ len-1 ] & 0xff; + + if ( len >= (padding + TRANSOP_AES_NONCE_SIZE)) + { + /* strictly speaking for this to be an ethernet packet + * it is going to need to be even bigger; but this is + * enough to prevent segfaults. */ + traceEvent( TRACE_DEBUG, "padding = %u", padding ); + len -= padding; + + len -= TRANSOP_AES_NONCE_SIZE; /* size of ethernet packet */ + + /* Step over 4-byte random nonce value */ + memcpy( outbuf, + assembly + TRANSOP_AES_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_WARNING, "UDP payload decryption failed." ); + } + } + else + { + traceEvent( TRACE_WARNING, "Encrypted length %d is not a multiple of AES_BLOCK_SIZE (%d)", len, AES_BLOCK_SIZE ); + len = 0; + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_aes unsupported aes version %u.", aes_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_aes inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +struct sha512_keybuf { + uint8_t enc_dec_key[AES256_KEY_BYTES]; /* The key to use for AES CBC encryption/decryption */ + uint8_t iv_enc_key[AES128_KEY_BYTES]; /* The key to use to encrypt the IV with AES ECB */ + uint8_t iv_ext_val[AES128_KEY_BYTES]; /* A value to extend the IV seed */ +}; /* size: SHA512_DIGEST_LENGTH */ + +/* NOTE: the caller should adjust priv->num_sa accordingly */ +static int setup_aes_key(transop_aes_t *priv, const uint8_t *key, ssize_t key_size, size_t sa_num) { + sa_aes_t * sa = &(priv->sa[sa_num]); + size_t aes_keysize_bytes; + size_t aes_keysize_bits; + struct sha512_keybuf keybuf; + + /* Clear out any old possibly longer key matter. */ + memset( &(sa->enc_key), 0, sizeof(sa->enc_key) ); + memset( &(sa->dec_key), 0, sizeof(sa->dec_key) ); + memset( &(sa->iv_enc_key), 0, sizeof(sa->iv_enc_key) ); + memset( &(sa->iv_ext_val), 0, sizeof(sa->iv_ext_val) ); + + /* We still use aes_best_keysize (even not necessary since we hash the key + * into the 256bits enc_dec_key) to let the users choose the degree of encryption. + * Long keys will pick AES192 or AES256 with more robust but expensive encryption. + */ + aes_keysize_bytes = aes_best_keysize(key_size); + aes_keysize_bits = 8 * aes_keysize_bytes; + + /* Hash the main key to generate subkeys */ + SHA512(key, key_size, (u_char*)&keybuf); + + /* setup of enc_key/dec_key, used for the CBC encryption */ + AES_set_encrypt_key(keybuf.enc_dec_key, aes_keysize_bits, &(sa->enc_key)); + AES_set_decrypt_key(keybuf.enc_dec_key, aes_keysize_bits, &(sa->dec_key)); + + /* setup of iv_enc_key and iv_ext_val, used for generating the CBC IV */ + AES_set_encrypt_key(keybuf.iv_enc_key, sizeof(keybuf.iv_enc_key) * 8, &(sa->iv_enc_key)); + memcpy(sa->iv_ext_val, keybuf.iv_ext_val, sizeof(keybuf.iv_ext_val)); + + traceEvent( TRACE_DEBUG, "transop_addspec_aes sa_id=%u, %u bits key=%s.\n", + priv->sa[sa_num].sa_id, aes_keysize_bits, key); + + return(0); +} + +/* + * priv: pointer to transform state + * keybuf: buffer holding the key + * pstat: length of keybuf + */ +static void add_aes_key(transop_aes_t *priv, uint8_t *keybuf, ssize_t pstat) { + setup_aes_key(priv, keybuf, pstat, priv->num_sa); + ++(priv->num_sa); +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_aes_t * priv = (transop_aes_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_AES_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; + const char * sep = index( op, '_' ); + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + memset( keybuf, 0, N2N_MAX_KEYSIZE ); + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + add_aes_key(priv, keybuf, pstat); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_aes : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_aes tick num_sa=%u now=%lu", priv->num_sa, now ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_aes choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_aes tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_aes no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_AESCBC; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + +static n2n_tostat_t transop_tick_aes_psk(n2n_trans_op_t * arg, time_t now) { + transop_aes_t * priv = (transop_aes_t *)arg->priv; + n2n_tostat_t r; + + memset(&r, 0, sizeof(r)); + + // Always tx + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_AESCBC; + r.tx_spec = priv->sa[priv->tx_sa].spec; + + return r; +} + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) calloc(1, sizeof(transop_aes_t)); + + if ( NULL != priv ) + { + size_t i; + sa_aes_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + priv->psk_mode = 0; + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + memset( &(sa->enc_key), 0, sizeof(sa->enc_key) ); + memset( &(sa->dec_key), 0, sizeof(sa->dec_key) ); + memset( &(sa->iv_enc_key), 0, sizeof(sa->iv_enc_key) ); + memset( &(sa->iv_ext_val), 0, sizeof(sa->iv_ext_val) ); + } + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + +/* Setup AES in pre-shared key mode */ +int transop_aes_setup_psk(n2n_trans_op_t *ttt, + n2n_sa_t sa_num, + uint8_t *encrypt_pwd, + uint32_t encrypt_pwd_len) { + int retval = 1; + transop_aes_t *priv = (transop_aes_t *)ttt->priv; + + if(ttt->priv) { + /* Replace the tick function with the PSK version of it */ + ttt->tick = transop_tick_aes_psk; + priv->psk_mode = 1; + priv->num_sa=0; + priv->tx_sa=0; + + /* Setup the key to use for encryption/decryption */ + add_aes_key(priv, encrypt_pwd, encrypt_pwd_len); + + retval = 0; + } else + traceEvent(TRACE_ERROR, "AES priv is not allocated"); + + return retval; +} + +#else /* #if defined(N2N_HAVE_AES) */ + +struct transop_aes +{ + ssize_t tx_sa; +}; + +typedef struct transop_aes transop_aes_t; + + +static int transop_deinit_aes( n2n_trans_op_t * arg ) +{ + transop_aes_t * priv = (transop_aes_t *)arg->priv; + + if ( priv ) + { + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static int transop_encode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_decode_aes( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len ) +{ + return -1; +} + +static int transop_addspec_aes( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + traceEvent( TRACE_DEBUG, "transop_addspec_aes AES not built into edge.\n"); + + return -1; +} + +static n2n_tostat_t transop_tick_aes( n2n_trans_op_t * arg, time_t now ) +{ + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + return r; +} + +int transop_aes_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_aes_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_aes( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_aes_t *) malloc( sizeof(transop_aes_t) ); + + if ( NULL != priv ) + { + /* install the private structure. */ + ttt->priv = priv; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_AESCBC; + ttt->addspec = transop_addspec_aes; + ttt->tick = transop_tick_aes; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + retval = 0; + } + else + { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for aes" ); + } + + return retval; +} + + +int transop_aes_setup_psk(n2n_trans_op_t *ttt, + n2n_sa_t sa_num, + uint8_t *encrypt_pwd, + uint32_t encrypt_pwd_len) { + return 0; +} + +#endif /* #if defined(N2N_HAVE_AES) */ + diff --git a/bundles/n2n_ntop_v3/legacy/transform_tf.c b/bundles/n2n_ntop_v3/legacy/transform_tf.c new file mode 100644 index 00000000..6b4d6060 --- /dev/null +++ b/bundles/n2n_ntop_v3/legacy/transform_tf.c @@ -0,0 +1,467 @@ +/** + * (C) 2007-18 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "n2n_transforms.h" +#include "twofish.h" +#ifndef _MSC_VER +/* Not included in Visual Studio 2008 */ +#include /* index() */ +#endif + +#define N2N_TWOFISH_NUM_SA 32 /* space for SAa */ + +#define N2N_TWOFISH_TRANSFORM_VERSION 1 /* version of the transform encoding */ + +struct sa_twofish +{ + n2n_cipherspec_t spec; /* cipher spec parameters */ + n2n_sa_t sa_id; /* security association index */ + TWOFISH * enc_tf; /* tx state */ + TWOFISH * dec_tf; /* rx state */ +}; + +typedef struct sa_twofish sa_twofish_t; + + +/** Twofish transform state data. + * + * With a key-schedule in place this will be populated with a number of + * SAs. Each SA has a lifetime and some opque data. The opaque data for twofish + * consists of the SA number and key material. + * + */ +struct transop_tf +{ + ssize_t tx_sa; + size_t num_sa; + sa_twofish_t sa[N2N_TWOFISH_NUM_SA]; +}; + +typedef struct transop_tf transop_tf_t; + +static int transop_deinit_twofish( n2n_trans_op_t * arg ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + + if ( priv ) + { + /* Memory was previously allocated */ + for (i=0; isa[i]); + + TwoFishDestroy(sa->enc_tf); /* deallocate TWOFISH */ + sa->enc_tf=NULL; + + TwoFishDestroy(sa->dec_tf); /* deallocate TWOFISH */ + sa->dec_tf=NULL; + + sa->sa_id=0; + } + + priv->num_sa=0; + priv->tx_sa=-1; + + free(priv); + } + + arg->priv=NULL; /* return to fully uninitialised state */ + + return 0; +} + +static size_t tf_choose_tx_sa( transop_tf_t * priv ) +{ + return priv->tx_sa; /* set in tick */ +} + +#define TRANSOP_TF_VER_SIZE 1 /* Support minor variants in encoding in one module. */ +#define TRANSOP_TF_NONCE_SIZE 4 +#define TRANSOP_TF_SA_SIZE 4 + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_encode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + uint32_t * pnonce; + + if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= N2N_PKT_BUF_SIZE ) + { + if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) + { + size_t idx=0; + sa_twofish_t * sa; + size_t tx_sa_num = 0; + + /* The transmit sa is periodically updated */ + tx_sa_num = tf_choose_tx_sa( priv ); + + sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ + + traceEvent( TRACE_DEBUG, "encode_twofish %lu with SA %lu.", in_len, sa->sa_id ); + + /* Encode the twofish format version. */ + encode_uint8( outbuf, &idx, N2N_TWOFISH_TRANSFORM_VERSION ); + + /* Encode the security association (SA) number */ + encode_uint32( outbuf, &idx, sa->sa_id ); + + /* The assembly buffer is a source for encrypting data. The nonce is + * written in first followed by the packet payload. The whole + * contents of assembly are encrypted. */ + pnonce = (uint32_t *)assembly; + *pnonce = rand(); + memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len ); + + /* Encrypt the assembly contents and write the ciphertext after the SA. */ + len = TwoFishEncryptRaw( assembly, /* source */ + outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE, + in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */ + sa->enc_tf); + if ( len > 0 ) + { + len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */ + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish encryption failed." ); + } + + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." ); + } + } + else + { + traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." ); + } + + return len; +} + + +/* Search through the array of SAs to find the one with the required ID. + * + * @return array index where found or -1 if not found + */ +static ssize_t twofish_find_sa( const transop_tf_t * priv, const n2n_sa_t req_id ) +{ + size_t i; + + for (i=0; i < priv->num_sa; ++i) + { + const sa_twofish_t * sa=NULL; + + sa = &(priv->sa[i]); + if (req_id == sa->sa_id) + { + return i; + } + } + + return -1; +} + + +/** The twofish packet format consists of: + * + * - a 8-bit twofish encoding version in clear text + * - a 32-bit SA number in clear text + * - ciphertext encrypted from a 32-bit nonce followed by the payload. + * + * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] + * |<------ encrypted ------>| + */ +static int transop_decode_twofish( n2n_trans_op_t * arg, + uint8_t * outbuf, + size_t out_len, + const uint8_t * inbuf, + size_t in_len, + const uint8_t * peer_mac) +{ + int len=0; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + if ( ( (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)) <= N2N_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ + && (in_len >= (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_NONCE_SIZE) ) /* Has at least version, SA and nonce */ + ) + { + n2n_sa_t sa_rx; + ssize_t sa_idx=-1; + size_t rem=in_len; + size_t idx=0; + uint8_t tf_enc_ver=0; + + /* Get the encoding version to make sure it is supported */ + decode_uint8( &tf_enc_ver, inbuf, &rem, &idx ); + + if ( N2N_TWOFISH_TRANSFORM_VERSION == tf_enc_ver ) + { + /* Get the SA number and make sure we are decrypting with the right one. */ + decode_uint32( &sa_rx, inbuf, &rem, &idx ); + + sa_idx = twofish_find_sa(priv, sa_rx); + if ( sa_idx >= 0 ) + { + sa_twofish_t * sa = &(priv->sa[sa_idx]); + + traceEvent( TRACE_DEBUG, "decode_twofish %lu with SA %lu.", in_len, sa_rx, sa->sa_id ); + + len = TwoFishDecryptRaw( (void *)(inbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE), + assembly, /* destination */ + (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)), + sa->dec_tf); + + if ( len > 0 ) + { + /* Step over 4-byte random nonce value */ + len -= TRANSOP_TF_NONCE_SIZE; /* size of ethernet packet */ + + memcpy( outbuf, + assembly + TRANSOP_TF_NONCE_SIZE, + len ); + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish decryption failed." ); + } + + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish SA number %lu not found.", sa_rx ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + /* Wrong security association; drop the packet as it is undecodable. */ + traceEvent( TRACE_ERROR, "decode_twofish unsupported twofish version %u.", tf_enc_ver ); + + /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ + } + } + else + { + traceEvent( TRACE_ERROR, "decode_twofish inbuf wrong size (%ul) to decrypt.", in_len ); + } + + return len; +} + +static int transop_addspec_twofish( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) +{ + int retval = 1; + ssize_t pstat=-1; + transop_tf_t * priv = (transop_tf_t *)arg->priv; + uint8_t keybuf[N2N_MAX_KEYSIZE]; + + if ( priv->num_sa < N2N_TWOFISH_NUM_SA ) + { + const char * op = (const char *)cspec->opaque; +#ifdef __ANDROID_NDK__ + const char *sep = strchr(op, '_'); +#else + const char * sep = index( op, '_' ); +#endif // __ANDROID_NDK__ + + if ( sep ) + { + char tmp[256]; + size_t s; + + s = sep - op; + memcpy( tmp, cspec->opaque, s ); + tmp[s]=0; + + s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ + + priv->sa[priv->num_sa].spec = *cspec; + priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); + + pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); + if ( pstat > 0 ) + { + priv->sa[priv->num_sa].enc_tf = TwoFishInit( keybuf, pstat); + priv->sa[priv->num_sa].dec_tf = TwoFishInit( keybuf, pstat); + + traceEvent( TRACE_DEBUG, "transop_addspec_twofish sa_id=%u data=%s.\n", + priv->sa[priv->num_sa].sa_id, sep+1); + + ++(priv->num_sa); + retval = 0; + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : bad key data - missing '_'.\n"); + } + } + else + { + traceEvent( TRACE_ERROR, "transop_addspec_twofish : full.\n"); + } + + return retval; +} + + +static n2n_tostat_t transop_tick_twofish( n2n_trans_op_t * arg, time_t now ) +{ + transop_tf_t * priv = (transop_tf_t *)arg->priv; + size_t i; + int found=0; + n2n_tostat_t r; + + memset( &r, 0, sizeof(r) ); + + traceEvent( TRACE_DEBUG, "transop_tf tick num_sa=%u", priv->num_sa ); + + for ( i=0; i < priv->num_sa; ++i ) + { + if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) + { + time_t remaining = priv->sa[i].spec.valid_until - now; + + traceEvent( TRACE_INFO, "transop_tf choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); + priv->tx_sa=i; + found=1; + break; + } + else + { + traceEvent( TRACE_DEBUG, "transop_tf tick rejecting sa=%u %lu -> %lu", + priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); + } + } + + if ( 0==found) + { + traceEvent( TRACE_INFO, "transop_tf no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); + } + else + { + r.can_tx = 1; + r.tx_spec.t = N2N_TRANSFORM_ID_TWOFISH; + r.tx_spec = priv->sa[priv->tx_sa].spec; + } + + return r; +} + +int transop_twofish_setup_psk( n2n_trans_op_t * ttt, + n2n_sa_t sa_num, + uint8_t * encrypt_pwd, + uint32_t encrypt_pwd_len ) +{ + int retval = 1; + transop_tf_t * priv = (transop_tf_t *)ttt->priv; + + if(priv) { + sa_twofish_t *sa; + + priv->num_sa=1; /* There is one SA in the array. */ + priv->tx_sa=0; + sa = &(priv->sa[priv->tx_sa]); + sa->sa_id=sa_num; + sa->spec.valid_until = 0x7fffffff; + + /* This is a preshared key setup. Both Tx and Rx are using the same security association. */ + + sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); + + if ( (sa->enc_tf) && (sa->dec_tf) ) + retval = 0; + else + traceEvent( TRACE_ERROR, "transop_twofish_setup_psk" ); + } else + traceEvent( TRACE_ERROR, "twofish priv is not allocated" ); + + return retval; +} + +int transop_twofish_init( n2n_trans_op_t * ttt ) +{ + int retval = 1; + transop_tf_t * priv = NULL; + + if ( ttt->priv ) + { + transop_deinit_twofish( ttt ); + } + + memset( ttt, 0, sizeof( n2n_trans_op_t ) ); + + priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); + + if ( NULL != priv ) { + size_t i; + sa_twofish_t * sa=NULL; + + /* install the private structure. */ + ttt->priv = priv; + priv->num_sa=0; + priv->tx_sa=0; /* We will use this sa index for encoding. */ + + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + ttt->addspec = transop_addspec_twofish; + ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */ + ttt->deinit = transop_deinit_twofish; + ttt->fwd = transop_encode_twofish; + ttt->rev = transop_decode_twofish; + + for(i=0; isa[i]); + sa->sa_id=0; + memset( &(sa->spec), 0, sizeof(n2n_cipherspec_t) ); + sa->enc_tf=NULL; + sa->dec_tf=NULL; + } + + retval = 0; + } else { + memset( ttt, 0, sizeof(n2n_trans_op_t) ); + traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); + } + + return retval; +} diff --git a/bundles/n2n_ntop_v3/n2n.7 b/bundles/n2n_ntop_v3/n2n.7 new file mode 100644 index 00000000..df0f293a --- /dev/null +++ b/bundles/n2n_ntop_v3/n2n.7 @@ -0,0 +1,132 @@ +.TH "n2n_v3" 7 "Sep 27, 2021" "version 3" "Background" +.SH NAME +n2n version 3 \- version 3 of the n2n decentralised peer-to-peer network overlay +VPN. +.SH DESCRIPTION +n2n is a peer-to-peer network overlay or VPN system that provides layer 2 over +layer 3 encapsulation with data transform capabilities such as encryption and +compression. This guide also discusses the differences of version 3 of n2n from +version 2. +.SH PROTOCOLS +n2n-3 basically uses the same set of messages to communicate with edges and +supernodes. However, due to slight packet format changes, the n2n-3 messages +are not compatible with n2n-2. There is no backward compatibility for n2n-2. +.SH ENCRYPTION +n2n-3 offers four different ciphers for payload encryption as well as optional +header encryption. Earlier versions of n2n-2 provided a mechanism using a key +schedule which has been removed in n2n-3. A basic user authentication scheme +relying on asymmetric cryptography has been added to n2n-3. + +n2n-3 provides the following ciphers to chose from for payload encryption; more +can be added as required: +.TP +.B (1) NULL +Data is encapsulated unchanged. Useful for testing and high-performance, low +sensitivity applications. +.TP +.B (2) TF-CTS +Twofish AES candidate in CTS mode. +.TP +.B (3) AES-CTS +AES in CTS mode with up to 256-bit key. +.TP +.B (4) CHACHA20 +ChaCha20, a well known stream cipher developped by Daniel J. Bernstein. +.TP +.B (5) SPECK-CTR +A fast block cipher developped by the NSA used as stream cipher in CTR mode. +.TP +Full Header Encyption +The optional full header encryption also encrypts packets' header which include +some administrative data. In addition, it adds replay protection. +.TP +User Password Authentication +n2n-3 implements an optional user-password authentication scheme. A key +generator assists in generating user's public keys to be stored at the +supernode side. +.SH COPMPRESSION +LZO for payload compression is an always available option at n2n-3. If compiled with +zstdlib support, ZSTD is at optional service as well. +.SH EXTENSIBILITY +n2n-3 decouples the data transform system from the core of the edge +operation. This allows for easier addition of new data transform +operations. n2n-3 reserves some standard transform identifiers (such as TwoFish +encryption) but allocates transform identifiers for user-defined +transforms. This allows anyone to add to n2n new private transforms without +breaking compatibility with the standard offering. +.SH FEDERATED SUPERNODES +n2n-3 incorporates the capability of multiple supernodes to be federated. +Federation acts transparently and balances the workload evenly among the +federated supernodes. Supernodes keep track of edges connected to different +supernodes and forward packets as required. This feature naturally supports +fail-over and this increases redundancy and resilience. +.P +Information on additional supernodes is propagated to all edges. In addition, +the n2n-3 edge implementation allows multiple supernodes to be specified on the +command line. Edges monitor the current supernode for responses to +REGISTER_SUPER as well as PING messages. After three responses from current +supernode are missed or when a better supernode in terms of significant lower workload +is found, the edge tries to connect to another supernode. It cycles through the list +f supernodes which over and over again is sorted according to reported workload. + +.SH MANAGEMENT CONSOLE +Edge and supernode in n2n-3 provide a UDP-based management console. Both listen +on the localhost address 127.0.0.1. Commands can be sent to the programs by +sending to the UDP socket. Responses are returned to the socket from which +commands were issued. This only works from the computer on which the programs +are running. Statistics can be retrieved and commands issued. The netcat utility +is all that is required; but more sophisticated tools could be built on the +interface. + +.SH SUPERNODE AUTHENTICATION +The supernode federation name serves as private key shared between the supernodes only. +The corresponding public key can be provided to the edges. + +.SH MESSAGE SUMMARY +The following message types work within n2n-3. +.TP +REGISTER_SUPER +Sent from an edge to its local supernode to register its MAC with the community. +Also, federated supernodes use this packet format to register to each other. +.TP +REGISTER_SUPER_ACK +Sent from a supernode to an edge to confirm registration. This also carries the +definition of the edge socket as seen at the supernode so NAT can be detected +and described. Furthermore, it carries information about additional federated +supernodes. +.TP +REGISTER_SUPER_NAK +Supernode refusing to register an edge. +.TP +PACKET +Encapsulated ethernet packets sent between edges. Supernodes forward or +broadcast these and edges send them direct in peer-to-peer mode. +.TP +REGISTER +A peer-to-peer mode registration request from one edge to another. Supernodes +forward these to facilitate NAT crossing introductions. +.TP +REGISTER_ACK +Complete peer-to-peer mode setup between two edges. These messages need to +travel direct between edges. +.TP +QUERY_PEER +Queries a supernode about another edge, especially its public socket in case of +no peer-to-peer communication can be established. Additionally, it serves as PING +to query supernodes about themselves. +.TP +PEER_INFO +Answers the QUERY_PEER; it also covers the special case of the PING query, internally +called PONG. +.SH AUTHORS +.TP +Richard Andrews andrews (at) ntop.org - main author of n2n-2 +.TP +Luca Deri +deri (at) ntop.org - code inherited from n2n-1 +.SH SEE ALSO +ifconfig(8) edge(8) supernode(1) +.br +the documentation contained in the source code +.br +the extensive documentation found in n2n's \fBdoc/\fR folder diff --git a/bundles/n2n_ntop_v3/packages/centos b/bundles/n2n_ntop_v3/packages/centos new file mode 100644 index 00000000..7c88ef3c --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/centos @@ -0,0 +1 @@ +rpm \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/packages/debian/Makefile.in b/bundles/n2n_ntop_v3/packages/debian/Makefile.in new file mode 100644 index 00000000..8b8b993f --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/Makefile.in @@ -0,0 +1,41 @@ +# +# Change it according to your setup +# +N2N_HOME=$(PWD)/../.. +N2N_BUILD=${N2N_HOME}/packages/debian/n2n + +all: clean pkg + +pkg: + make -C ../../ + if test -e "${N2N_BUILD}"; then /bin/rm -fr ${N2N_BUILD}; fi + mkdir -p ${N2N_BUILD}/usr/sbin ${N2N_BUILD}/usr/share/man/man1 ${N2N_BUILD}/usr/share/man/man7 ${N2N_BUILD}/usr/share/man/man8 + mkdir -p ${N2N_BUILD}/usr/share/doc/n2n/examples + install -m755 ../../supernode ${N2N_BUILD}/usr/sbin/ + install -m755 ../../edge ${N2N_BUILD}/usr/sbin/ + install -m644 ../../edge.8.gz ${N2N_BUILD}/usr/share/man/man8/ + install -m644 ../../supernode.1.gz ${N2N_BUILD}/usr/share/man/man1/ + install -m644 ../../n2n.7.gz ${N2N_BUILD}/usr/share/man/man7/ + install -m644 ../../community.list ${N2N_BUILD}/usr/share/doc/n2n/examples/ + install -m644 ../../doc/*.md ${N2N_BUILD}/usr/share/doc/n2n/ + @/bin/rm -f ../n2n*.deb + dpkg-buildpackage -rfakeroot -d -us -uc -a@EXTN@ + -dpkg-sig --sign builder -k D1EB60BE ../n2n_*deb + @\rm -f ../n2n_*dsc ../n2n_*.gz ../n2n_*changes + @/bin/mv ../n2n_*deb . + @echo + @echo "Package built." + @/bin/ls n2n_*deb + @echo "-------------------------------" + -dpkg -I n2n_*deb + -dpkg --contents n2n_*deb + @echo "-------------------------------" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + rm -rf *~ *deb diff --git a/bundles/n2n_ntop_v3/packages/debian/README b/bundles/n2n_ntop_v3/packages/debian/README new file mode 100644 index 00000000..915a7c15 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/README @@ -0,0 +1,21 @@ +Prerequisites +------------- +apt-get install debhelper fakeroot dpkg-sig + +EdgeOS +------ +We need to replace BusyBox-implemented commands using full-fledged commands by doing +(see http://community.ubnt.com/t5/EdgeMAX/ubnt-debian-package-conflict/m-p/421325) + +curl -O http://ftp.us.debian.org/debian/pool/main/c/coreutils/coreutils_8.5-1_mips.deb +dpkg -i --force-all coreutils_8.5-1_mips.deb + +curl -O http://ftp.us.debian.org/debian/pool/main/t/tar/tar_1.23-3_mips.deb +dpkg -i --force-all tar_1.23-3_mips.deb + +wget http://ftp.us.debian.org/debian/pool/main/f/findutils/findutils_4.4.2-4_mips.deb +dpkg -i --force-all findutils_4.4.2-4_mips.deb + +wget http://ftp.us.debian.org/debian/pool/main/g/gzip/gzip_1.5-1.1_mips.deb +dpkg -i --force-all gzip_1.5-1.1_mips.deb + diff --git a/bundles/n2n_ntop_v3/packages/debian/configure.in b/bundles/n2n_ntop_v3/packages/debian/configure.in new file mode 100644 index 00000000..21ed5af1 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/configure.in @@ -0,0 +1,62 @@ +AC_INIT([Makefile.in], 1.0) + +AC_ARG_WITH(edgex, [ --with-edgex Build for Ubiquity-X]) + +# NOTE: this file is not actually used. You need to edit configure as well! +N2N_VERSION_SHORT=`grep N2N_VERSION_SHORT ../../Makefile | head -1| cut -d "=" -f 2` +GIT_COMMITS=`grep GIT_COMMITS ../../Makefile | head -1| cut -d "=" -f 2` + +DEBIAN_VERSION=`cat /etc/debian_version | grep "^8" | wc -l` + +EXTRA_DEP="" +if test $DEBIAN_VERSION = "0"; then +EXTRA_DEP=", libzstd1" +fi + +if test "${EXTN+set}" != set; then + MACHINE=`uname -m` + SHORT_MACHINE=`echo $MACHINE | cut -b1-3` + + if test $MACHINE = "x86_64"; then + EXTN="amd64" + else + if test $SHORT_MACHINE = "aar"; then + EXTN="arm64" + else + if test $SHORT_MACHINE = "arm"; then + EXTN="armhf" + else + if test $SHORT_MACHINE = "mip"; then + EXTN="mips" + else + EXTN="i386" + fi + fi + fi + fi +fi + +if test "${with_edgex+set}" = set; then + EXTN="mipsel" +fi + +APP=n2n +DATE=`date -R` + +AC_SUBST(APP) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(EXTN) +AC_SUBST(DATE) +AC_SUBST(EXTRA_DEP) + +AC_CONFIG_FILES(debian/changelog) +AC_CONFIG_FILES(debian/files) +AC_CONFIG_FILES(debian/control) +AC_CONFIG_FILES(debian/rules) +AC_CONFIG_FILES(../etc/systemd/system/edge.service) +AC_CONFIG_FILES(../etc/systemd/system/edge@.service) +AC_CONFIG_FILES(../etc/systemd/system/edge-ntopng@.service) +AC_CONFIG_FILES(../etc/systemd/system/supernode.service) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/COPYRIGHT b/bundles/n2n_ntop_v3/packages/debian/debian/COPYRIGHT new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/COPYRIGHT @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/README b/bundles/n2n_ntop_v3/packages/debian/debian/README new file mode 100644 index 00000000..8d88f8df --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/README @@ -0,0 +1,2 @@ +This directory contains the files needed to build the package +named 'n2n' for the Debian GNU/Linux distribution. diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/changelog.in b/bundles/n2n_ntop_v3/packages/debian/debian/changelog.in new file mode 100644 index 00000000..6d4e3dc2 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/changelog.in @@ -0,0 +1,4 @@ +@APP@ (@N2N_VERSION_SHORT@-@GIT_COMMITS@) table; urgency=high + * Last packaged version + + -- Luca Deri @DATE@ diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/compat b/bundles/n2n_ntop_v3/packages/debian/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/compat @@ -0,0 +1 @@ +9 diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/conffiles b/bundles/n2n_ntop_v3/packages/debian/debian/conffiles new file mode 100644 index 00000000..d467c8b7 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/conffiles @@ -0,0 +1,2 @@ +/etc/n2n/edge.conf.sample +/etc/n2n/supernode.conf.sample diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/control.in b/bundles/n2n_ntop_v3/packages/debian/debian/control.in new file mode 100644 index 00000000..9fe4aada --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/control.in @@ -0,0 +1,25 @@ +Source: n2n +Section: net +Priority: extra +Maintainer: Luca Deri +Standards-Version: @N2N_VERSION_SHORT@ +Build-Depends: + +Package: n2n +Architecture: @EXTN@ +Suggests: uml-utilities +Depends: ${shlibs:Depends}, ${misc:Depends} @EXTRA_DEP@ +Conflicts: n2n (<< 2.1.0-1) +Replaces: n2n (<< 2.1.0-1) +Description: a layer-two peer-to-peer virtual private network (VPN) + n2n is a layer-two peer-to-peer virtual private network (VPN) which allows + users to exploit features typical of P2P applications at network instead of + application level. This means that users can gain native IP visibility (e.g. + two PCs belonging to the same n2n network can ping each other) and be + reachable with the same network IP address regardless of the network where + they currently belong. In a nutshell, as OpenVPN moved SSL from application + (e.g. used to implement the https protocol) to network protocol, n2n moves + P2P from application to network level. + . + Edge is the edge node daemon for n2n which creates a TAP interface to expose + the n2n virtual LAN. diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/dirs b/bundles/n2n_ntop_v3/packages/debian/debian/dirs new file mode 100644 index 00000000..8a9632d0 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/dirs @@ -0,0 +1,3 @@ +usr/sbin +etc/systemd +etc/init.d diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/docs b/bundles/n2n_ntop_v3/packages/debian/debian/docs new file mode 100644 index 00000000..e845566c --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/docs @@ -0,0 +1 @@ +README diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/files.in b/bundles/n2n_ntop_v3/packages/debian/debian/files.in new file mode 100644 index 00000000..6128dce3 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/files.in @@ -0,0 +1 @@ +n2n_@N2N_VERSION_SHORT@_@EXTN@.deb free optional diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/n2n.substvars b/bundles/n2n_ntop_v3/packages/debian/debian/n2n.substvars new file mode 100644 index 00000000..a5957235 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/n2n.substvars @@ -0,0 +1,2 @@ +misc:Depends=debconf (>= 0.5) | debconf-2.0 +misc:Pre-Depends= diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/postinst b/bundles/n2n_ntop_v3/packages/debian/debian/postinst new file mode 100644 index 00000000..5de13e21 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/postinst @@ -0,0 +1,56 @@ +#!/bin/sh -e + +case "$1" in + configure) + # continue below + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + exit 0 + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +umask 022 + +if ! grep -q n2n /etc/group; then + echo 'Creating n2n group' + /usr/sbin/groupadd -r n2n +fi + +if ! /usr/bin/id -u n2n > /dev/null 2>&1; then + echo "Creating n2n user..." + /usr/sbin/useradd -M -N -g n2n -r -s /bin/false n2n +fi + +echo "Rebuilding ld cache..." +/sbin/ldconfig + +if [ -f /.dockerenv ]; then exit 0; fi + +# Start service after upgrade/install +systemctl daemon-reload +systemctl reset-failed + +# Enable edge +if systemctl -q is-active edge; then + # only restart edge if it's already running + echo "Restarting n2n edge..." + deb-systemd-invoke restart edge +fi + +# Restart specific services if already running +deb-systemd-invoke restart 'edge@*.service' 'edge-ntopng@*.service' + +# Enable supernode +if systemctl -q is-active supernode; then + # only restart supernode if it's already running + echo "Restarting n2n supernode..." + deb-systemd-invoke restart supernode +fi + +exit 0 diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/postrm b/bundles/n2n_ntop_v3/packages/debian/debian/postrm new file mode 100644 index 00000000..ef799a3a --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/postrm @@ -0,0 +1,11 @@ +#!/bin/sh -e + +set -e + +#case "$1" in +# purge|remove) +# +# ;; +#esac + +exit 0 diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/preinst b/bundles/n2n_ntop_v3/packages/debian/debian/preinst new file mode 100644 index 00000000..4e7a80dc --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/preinst @@ -0,0 +1,31 @@ +#! /bin/sh +# preinst script for n2n +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' + +case "$1" in + install|upgrade) + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + + +exit 0 diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/prerm b/bundles/n2n_ntop_v3/packages/debian/debian/prerm new file mode 100644 index 00000000..9e4e53d7 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/prerm @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +if [ -f /.dockerenv ]; then exit 0; fi + +. /usr/share/debconf/confmodule + +if [ "$1" = "remove" ]; then + deb-systemd-invoke stop edge.service 'edge@*.service' 'edge-ntopng@*.service' + deb-systemd-invoke disable edge.service 'edge@*.service' 'edge-ntopng@*.service' + deb-systemd-invoke stop supernode.service + deb-systemd-invoke disable supernode.service + systemctl daemon-reload + systemctl reset-failed +fi + +exit 0 diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/rules.in b/bundles/n2n_ntop_v3/packages/debian/debian/rules.in new file mode 100644 index 00000000..4e879b91 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/rules.in @@ -0,0 +1,59 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +# export DH_VERBOSE=1 + +# +# debian/compat +# We should use at least compatibility version 5 +# but this requires the whole building process +# to be remade and this is something we leave +# to when we will have more time +# http://www.tin.org/bin/man.cgi?section=7&topic=debhelper +# + +package=@APP@ + +build: build-stamp +build-stamp: + dh_testdir + +clean: + dh_testdir + dh_testroot + dh_clean + +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_prep + dh_installdirs + dh_installinit + dh_installdebconf + dh_installman + dh_strip + dh_compress + dh_fixperms + dh_installdeb + cp -r n2n debian + cp -r ../etc debian/n2n + find debian/n2n -name "*.in" -exec /bin/rm {} ';' + find debian/n2n -name "*~" -exec /bin/rm {} ';' + dh_link + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/bundles/n2n_ntop_v3/packages/debian/debian/templates b/bundles/n2n_ntop_v3/packages/debian/debian/templates new file mode 100644 index 00000000..4f354077 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/debian/debian/templates @@ -0,0 +1,7 @@ +Template: n2n/license_expired_continue_installation +Type: boolean +Default: true +Description: Do you want to continue with the installation? + License found is not valid for the new package that is going to be installed. + . + Renew the maintenance to get a valid license for the new package or cancel the installation to continue using the current package. diff --git a/bundles/n2n_ntop_v3/packages/etc/n2n/edge.conf.sample b/bundles/n2n_ntop_v3/packages/etc/n2n/edge.conf.sample new file mode 100644 index 00000000..74d50a8f --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/n2n/edge.conf.sample @@ -0,0 +1,41 @@ +# +# The configuration file is similar to the command line, with one option per line. An equal +# sign '=' should be used between key and value. Example: -c=mynetwork or --community=mynetwork +# This file contains a basic configuration example, please refer to the help (-h) for the full +# list of available options. +# +# -d|--tun-device +# Specifies the name of the TUN interface. +# +-d=n2n0 +# +# -c|--community +# Specifies the n2n community name the edge belongs to. +# +-c=mynetwork +# +# -k +# Sets the encryption key (ASCII). The environment variable N2N_KEY= can also be used. +# +-k=mypassword +# +# -m +# Specified the MAC address for the TAP interface (random otherwise). +# +# -m=DE:AD:BE:EF:99:99 +# +# -a +# Sets the interface address. For DHCP use '-r -a dhcp:0.0.0.0'. +# +-a=1.2.3.4 +# +# -p +# Sets the local UDP port to a fixed port. +# +-p=50001 +# +# -l|--supernode-list +# Specifies the supernode IP and port. +# +-l=7.8.9.0:7777 +# diff --git a/bundles/n2n_ntop_v3/packages/etc/n2n/supernode.conf.sample b/bundles/n2n_ntop_v3/packages/etc/n2n/supernode.conf.sample new file mode 100644 index 00000000..35757947 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/n2n/supernode.conf.sample @@ -0,0 +1,15 @@ +# +# The configuration file is similar to the command line, with one option per line. An equal +# sign '=' should be used between key and value. Example: -p=7777 +# This file contains a basic configuration example, please refer to the help (-h) for the full +# list of available options. +# +# -p +# Sets the UDP listening port. +# +-p=7777 +# +# -c +# Optionally specifies the allowed communities as listed in community.list file. +# +# -c=community.list diff --git a/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge-ntopng@.service.in b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge-ntopng@.service.in new file mode 100644 index 00000000..5299d227 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge-ntopng@.service.in @@ -0,0 +1,16 @@ +[Unit] +Description=n2n edge process, on %I +After=network-online.target syslog.target +Wants=network-online.target +BindsTo=ntopng.service + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge-%i.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=ntopng.service +Alias= diff --git a/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge.service.in b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge.service.in new file mode 100644 index 00000000..32f0d79d --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge.service.in @@ -0,0 +1,15 @@ +[Unit] +Description=n2n edge process +After=network-online.target syslog.target nfw.target +Wants=network-online.target + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge@.service.in b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge@.service.in new file mode 100644 index 00000000..d9123452 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/systemd/system/edge@.service.in @@ -0,0 +1,15 @@ +[Unit] +Description=n2n edge process, on %I +After=network-online.target syslog.target nfw.target +Wants=network-online.target + +[Service] +Type=simple +ExecStartPre= +ExecStart=/usr/sbin/edge /etc/n2n/edge-%i.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v3/packages/etc/systemd/system/supernode.service.in b/bundles/n2n_ntop_v3/packages/etc/systemd/system/supernode.service.in new file mode 100644 index 00000000..73e3d758 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/etc/systemd/system/supernode.service.in @@ -0,0 +1,16 @@ +[Unit] +Description=n2n supernode process +After=network-online.target syslog.target +Wants=network-online.target + +[Service] +Type=simple +User=n2n +Group=n2n +ExecStart=/usr/sbin/supernode /etc/n2n/supernode.conf -f +Restart=on-abnormal +RestartSec=5 + +[Install] +WantedBy=multi-user.target +Alias= diff --git a/bundles/n2n_ntop_v3/packages/openwrt/Makefile b/bundles/n2n_ntop_v3/packages/openwrt/Makefile new file mode 100644 index 00000000..719a4fa5 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/openwrt/Makefile @@ -0,0 +1,86 @@ +# +# Copyright (C) 2021 - ntop.org and contributors +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=n2n +PKG_SOURCE_URL:=https://github.com/ntop/n2n.git +PKG_SOURCE_VERSION:=6937640a2bc24832af7fc4ed1658d6aef192f03b +PKG_VERSION:=2.9.0_dev_git$(PKG_SOURCE_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_PROTO:=git + +PKG_MAINTAINER:=Emanuele Faranda +PKG_LICENSE:=GPL3 +PKG_BUILD_PARALLEL:=1 + +# autogen fix +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/n2n/Default + SECTION:=net + CATEGORY:=Network + TITLE:=N2N Peer-to-peer VPN + URL:=http://www.ntop.org/n2n + SUBMENU:=VPN + DEPENDS+=+libcap +endef + +define Package/n2n-edge + $(call Package/n2n/Default) + TITLE+= client (edge node) + DEPENDS+=+kmod-tun +endef + +define Package/n2n-supernode + $(call Package/n2n/Default) + TITLE+= server (supernode) +endef + +define Package/n2n-edge/description +The client node for the N2N infrastructure +endef + +define Package/n2n-supernode/description +The supernode for the N2N infrastructure +endef + +define Build/Configure + ( cd $(PKG_BUILD_DIR); ./autogen.sh ) + $(call Build/Configure/Default) +endef + +define Package/n2n-edge/conffiles +/etc/n2n/edge.conf +endef + +define Package/n2n-edge/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/edge $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/packages/openwrt/etc/init.d/edge $(1)/etc/init.d/edge + $(INSTALL_DIR) $(1)/etc/n2n + $(INSTALL_CONF) $(PKG_BUILD_DIR)/packages/etc/n2n/edge.conf.sample $(1)/etc/n2n/edge.conf +endef + +define Package/n2n-supernode/conffiles +/etc/n2n/supernode.conf +endef + +define Package/n2n-supernode/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/supernode $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/packages/openwrt/etc/init.d/supernode $(1)/etc/init.d/supernode + $(INSTALL_DIR) $(1)/etc/n2n + $(INSTALL_CONF) $(PKG_BUILD_DIR)/packages/etc/n2n/supernode.conf.sample $(1)/etc/n2n/supernode.conf +endef + +$(eval $(call BuildPackage,n2n-edge)) +$(eval $(call BuildPackage,n2n-supernode)) diff --git a/bundles/n2n_ntop_v3/packages/openwrt/README.md b/bundles/n2n_ntop_v3/packages/openwrt/README.md new file mode 100644 index 00000000..44b229fe --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/openwrt/README.md @@ -0,0 +1,39 @@ +## Prerequisites + +This instructions explain how to build an OpenWRT .ipk package for n2n. + +Before going on, it is required to have a working cross-compiling build +environment for the OpenWRT version installed into your device. This usually +comes down to the following steps: + +1. Download and extract the SDK toolchain for your device. The toolchain + must match the *exact* OpenWRT version installed in your device. Toolchain + for official OpenWRT images can be downloaded from https://downloads.openwrt.org + +2. Build the toolchain: run `make menuconfig`, save the configuration, then + run `make` to build the cross compiling tools + +3. Download the feeds with `./scripts/feeds update -a` + +## Compilation + +From the OpenWRT build directory: + +``` +git clone https://github.com/ntop/n2n n2n +cp -r n2n/packages/openwrt package/n2n +make menuconfig # select Network -> VPN -> n2n-edge and n2n-supernode +make package/n2n/compile V=s +``` + +If everything went fine, two ipk will be generated, one for the n2n-edge +and the other for n2n-supernode. They can be found with `find . -name "n2n*.ipk"`, +copied to the target device, and installed with `opkg install`. + +## Configuration + +The edge node can be started with `/etc/init.d/edge start`. +Its configuration file is `/etc/n2n/edge.conf`. + +The supernode can be started with `/etc/init.d/supernode start`. +Its configuration file is `/etc/n2n/supernode.conf`. diff --git a/bundles/n2n_ntop_v3/packages/openwrt/patches/001-fix-cc.patch b/bundles/n2n_ntop_v3/packages/openwrt/patches/001-fix-cc.patch new file mode 100644 index 00000000..c0d10737 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/openwrt/patches/001-fix-cc.patch @@ -0,0 +1,11 @@ +--- a/configure.seed ++++ b/configure.seed +@@ -13,8 +13,6 @@ + GIT_RELEASE=${N2N_VERSION_SHORT} + fi + +-CC=gcc +-AR=ar + N2N_LIBS= + + AC_PROG_CC diff --git a/bundles/n2n_ntop_v3/packages/rpm/Makefile.in b/bundles/n2n_ntop_v3/packages/rpm/Makefile.in new file mode 100644 index 00000000..68585a5b --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/rpm/Makefile.in @@ -0,0 +1,26 @@ +# +# Change it according to your setup +# +N2N_HOME=$(PWD)/../.. +N2N_BUILD=${N2N_HOME}/packages/debian/n2n +PLATFORM=@MACHINE@ +RPM_PKG=n2n-@N2N_VERSION_SHORT@-@GIT_COMMITS@.$(PLATFORM).rpm + +all: clean pkg + +pkg: + rpmbuild -bb ./n2n.spec + -@@RPM_SIGN_CMD@ $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG) + @echo "" + @echo "Package contents:" + @rpm -qpl $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG) + @echo "The package is now available in $(HOME)/rpmbuild/RPMS/$(PLATFORM)/$(RPM_PKG)" + +distclean: + echo "dummy distclean" + +install: + echo "dummy install" + +clean: + rm -rf *~ *rpm diff --git a/bundles/n2n_ntop_v3/packages/rpm/configure.in b/bundles/n2n_ntop_v3/packages/rpm/configure.in new file mode 100644 index 00000000..cce9205b --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/rpm/configure.in @@ -0,0 +1,58 @@ +AC_INIT([Makefile.in], 1.0) + +# NOTE: this file is not actually used. You need to edit configure as well! +N2N_VERSION_SHORT=`grep N2N_VERSION_SHORT ../../Makefile | head -1| cut -d "=" -f 2` +GIT_COMMITS=`grep GIT_COMMITS ../../Makefile | head -1| cut -d "=" -f 2` + +MACHINE=`uname -m` +SHORT_MACHINE=`uname -m | cut -b1-3` + +if test $MACHINE = "x86_64"; then + EXTN="amd64" +else + if test $SHORT_MACHINE = "aar"; then + EXTN="arm64" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "arm"; then + EXTN="armhf" + EXTRA_DEPS="" + else + if test $SHORT_MACHINE = "mip"; then + EXTN="mips" + EXTRA_DEPS="" + else + EXTN="i386" + fi + fi + fi +fi + +APP=n2n +DATE=`date -R` + +CENTOS_RELEASE=`cat /etc/centos-release | cut -d ' ' -f 3|cut -d '.' -f 1` +if test $CENTOS_RELEASE = "release"; then + CENTOS_RELEASE=`cat /etc/centos-release | cut -d ' ' -f 4|cut -d '.' -f 1` +fi + +RPM_SIGN_CMD="rpm --addsign" +if test "$CENTOS_RELEASE" -ne 8; then + RPM_SIGN_CMD="./rpm-sign.exp" +fi + +AC_SUBST(APP) +AC_SUBST(MACHINE) +AC_SUBST(N2N_VERSION_SHORT) +AC_SUBST(GIT_COMMITS) +AC_SUBST(EXTN) +AC_SUBST(DATE) +AC_SUBST(RPM_SIGN_CMD) + +AC_CONFIG_FILES(n2n.spec) +AC_CONFIG_FILES(../etc/systemd/system/edge.service) +AC_CONFIG_FILES(../etc/systemd/system/edge@.service) +AC_CONFIG_FILES(../etc/systemd/system/edge-ntopng@.service) +AC_CONFIG_FILES(../etc/systemd/system/supernode.service) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/bundles/n2n_ntop_v3/packages/rpm/n2n.spec.in b/bundles/n2n_ntop_v3/packages/rpm/n2n.spec.in new file mode 100644 index 00000000..8448ab49 --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/rpm/n2n.spec.in @@ -0,0 +1,107 @@ +Summary: n2n peer-to-peer VPN +Name: n2n +Version: @N2N_VERSION_SHORT@ +Release: @GIT_COMMITS@ +License: GPL +Group: Networking/Utilities +URL: http://www.ntop.org/ +Source: n2n-%{version}.tgz +Packager: Luca Deri +# Temporary location where the RPM will be built +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Requires: libzstd + +# Make sure .build-id is not part of the package +%define _build_id_links none + +%description +n2n peer-to-peer VPN + +%prep + +%build + +mkdir -p $RPM_BUILD_ROOT/usr/sbin $RPM_BUILD_ROOT/usr/share/man/man1 $RPM_BUILD_ROOT/usr/share/man/man7 $RPM_BUILD_ROOT/usr/share/man/man8 +mkdir -p $RPM_BUILD_ROOT/etc/n2n +mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system/ +cp $HOME/n2n/edge $RPM_BUILD_ROOT/usr/sbin +cp $HOME/n2n/supernode $RPM_BUILD_ROOT/usr/sbin +cp $HOME/n2n/n2n.7.gz $RPM_BUILD_ROOT/usr/share/man/man7 +cp $HOME/n2n/supernode.1.gz $RPM_BUILD_ROOT/usr/share/man/man1 +cp $HOME/n2n/edge.8.gz $RPM_BUILD_ROOT/usr/share/man/man8 +cp $HOME/n2n/packages/etc/systemd/system/*.service $RPM_BUILD_ROOT/usr/lib/systemd/system/ +cp $HOME/n2n/packages/etc/n2n/*.conf.sample $RPM_BUILD_ROOT/etc/n2n + +find $RPM_BUILD_ROOT -name ".git" | xargs /bin/rm -rf +find $RPM_BUILD_ROOT -name ".svn" | xargs /bin/rm -rf +find $RPM_BUILD_ROOT -name "*~" | xargs /bin/rm -f +# +DST=$RPM_BUILD_ROOT/usr/n2n +SRC=$RPM_BUILD_DIR/%{name}-%{version} +#mkdir -p $DST/conf +# Clean out our build directory +%clean +rm -fr $RPM_BUILD_ROOT + +%files +/usr/sbin/edge +/usr/sbin/supernode +/usr/share/man/man7/n2n.7.gz +/usr/share/man/man1/supernode.1.gz +/usr/share/man/man8/edge.8.gz +/usr/lib/systemd/system/edge.service +/usr/lib/systemd/system/edge@.service +/usr/lib/systemd/system/edge-ntopng@.service +/usr/lib/systemd/system/supernode.service +%config(noreplace) /etc/n2n/supernode.conf.sample +%config(noreplace) /etc/n2n/edge.conf.sample + +# Set the default attributes of all of the files specified to have an +# owner and group of root and to inherit the permissions of the file +# itself. +%defattr(-, root, root) + +%changelog +* Fri Aug 17 2018 Luca Deri 1.0 +- Current package version + +# Execution order: +# install: pre -> (copy) -> post +# upgrade: pre -> (copy) -> post -> preun (old) -> (delete old) -> postun (old) +# un-install: preun -> (delete) -> postun + +%pre + +if ! grep -q n2n /etc/group; then + echo 'Creating n2n group' + /usr/sbin/groupadd -r n2n +fi + +if ! /usr/bin/id -u n2n > /dev/null 2>&1; then + echo 'Creating n2n user' + /usr/sbin/useradd -M -N -g n2n -r -s /bin/false n2n +fi + +%post +if [ -f /bin/systemctl ]; then + if [ ! -f /.dockerenv ]; then + /bin/systemctl daemon-reload + # NOTE: do not enable any services during first installation + fi +fi + +%preun +if [ -f /bin/systemctl ]; then + if [ ! -f /.dockerenv ]; then + # possibly remove the installed services + %systemd_preun supernode.service edge.service 'edge-ntopng@*.service' 'edge@*.service' + fi +fi + +%postun +if [ -f /bin/systemctl ]; then + if [ ! -f /.dockerenv ]; then + # possibly restart the running services + %systemd_postun_with_restart supernode.service edge.service 'edge-ntopng@*.service' 'edge@*.service' + fi +fi diff --git a/bundles/n2n_ntop_v3/packages/rpm/rpm-sign.exp b/bundles/n2n_ntop_v3/packages/rpm/rpm-sign.exp new file mode 100644 index 00000000..7a0f88af --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/rpm/rpm-sign.exp @@ -0,0 +1,10 @@ +#!/usr/bin/expect -f + +### rpm-sign.exp -- Sign RPMs by sending the passphrase. + +spawn rpm --addsign {*}$argv + expect -exact "Enter pass phrase: " + send -- "\r" + expect eof + +## end of rpm-sign.exp diff --git a/bundles/n2n_ntop_v3/packages/ubuntu b/bundles/n2n_ntop_v3/packages/ubuntu new file mode 100644 index 00000000..b2f7fd3e --- /dev/null +++ b/bundles/n2n_ntop_v3/packages/ubuntu @@ -0,0 +1 @@ +debian \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/scripts/README.md b/bundles/n2n_ntop_v3/scripts/README.md new file mode 100644 index 00000000..380fa3c3 --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/README.md @@ -0,0 +1,9 @@ +This directory contains executables that are not compiled. Some of these may +end up installed for use by end users, but many of them are for use during +development, builds and tests. + +Nothing in this directory should need compiling to use and they should be +written such that they do not need configuring (e.g: they might probe several +directories for their requirements) + +See the [Scripts Documentation](../docs/Scripts.md) for further details diff --git a/bundles/n2n_ntop_v3/scripts/hack_fakeautoconf.sh b/bundles/n2n_ntop_v3/scripts/hack_fakeautoconf.sh new file mode 100644 index 00000000..8ec8c825 --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/hack_fakeautoconf.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Specifically for windows, where installing autoconf looks suspiciously +# like boiling the ocean. + +sed \ + -e "s%@N2N_VERSION_SHORT@%FIXME%g" \ + -e "s%@GIT_COMMITS@%FIXME%g" \ + -e "s%@CC@%gcc%g" \ + -e "s%@AR@%ar%g" \ + -e "s%@CFLAGS@%$CFLAGS%g" \ + -e "s%@LDFLAGS@%$LDFLAGS%g" \ + -e "s%@N2N_LIBS@%$LDLIBS%g" \ + < Makefile.in > Makefile + +sed \ + -e "s%@ADDITIONAL_TOOLS@%%g" \ + < tools/Makefile.in > tools/Makefile + +cat <include/config.h +#define PACKAGE_VERSION "FIXME" +#define PACKAGE_OSNAME "FIXME" +#define GIT_RELEASE "FIXME" +EOF diff --git a/bundles/n2n_ntop_v3/scripts/indent.sh b/bundles/n2n_ntop_v3/scripts/indent.sh new file mode 100644 index 00000000..50d38bac --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/indent.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Given one or more input source files, run a re-indenter on them. + +help() { + echo "Usage: scripts/indent [-i] [file...]" + echo " -i modify file in place with reindent results" + echo "" + echo "By default, will output a diff and exitcode if changed are needed" + echo "If modifying files, no exit code or diff is output" + exit 1 +} + +[ -z "$1" ] && help +[ "$1" = "-h" ] && help + +INPLACE=0 +if [ "$1" = "-i" ]; then + shift + INPLACE=1 +fi + +## indentOneClang() { +## rm -f "$1.indent" +## clang-format "$1" >"$1.indent" +## if [ $? -ne 0 ]; then +## echo "Error while formatting \"$1\"" +## RESULT=1 +## return +## fi +## diff -u "$1" "$1.indent" +## if [ $? -ne 0 ]; then +## RESULT=1 +## fi +## } + +indentOne() { + IFILE="$1" + if [ "$INPLACE" -eq 0 ]; then + OFILE="$1.indent" + rm -f "$OFILE" + else + OFILE="$1" + fi + if ! uncrustify -c uncrustify.cfg -f "$IFILE" -o "$OFILE"; then + echo "Error while formatting \"$1\"" + RESULT=1 + return + fi + if ! diff -u "$IFILE" "$OFILE"; then + RESULT=1 + fi +} + +RESULT=0 +while [ -n "$1" ]; do + indentOne "$1" + shift +done +exit $RESULT diff --git a/bundles/n2n_ntop_v3/scripts/n2n-ctl b/bundles/n2n_ntop_v3/scripts/n2n-ctl new file mode 100644 index 00000000..ab59f362 --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/n2n-ctl @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 +# Licensed under GPLv3 +# +# Simple script to query the management interface of a running n2n edge node + +import argparse +import socket +import json +import collections + + +class JsonUDP(): + """encapsulate communication with the edge""" + + def __init__(self, port): + self.address = "127.0.0.1" + self.port = port + self.tag = 0 + self.key = None + self.debug = False + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.settimeout(1) + + def _next_tag(self): + tagstr = str(self.tag) + self.tag = (self.tag + 1) % 1000 + return tagstr + + def _cmdstr(self, msgtype, cmdline): + """Create the full command string to send""" + tagstr = self._next_tag() + + options = [tagstr] + if self.key is not None: + options += ['1'] # Flags set for auth key field + options += [self.key] + optionsstr = ':'.join(options) + + return tagstr, ' '.join((msgtype, optionsstr, cmdline)) + + def _rx(self, tagstr): + """Wait for rx packets""" + + # TODO: there are no timeouts with any of the recv calls + data, _ = self.sock.recvfrom(1024) + data = json.loads(data.decode('utf8')) + + # TODO: We assume the first packet we get will be tagged for us + # and be either an "error" or a "begin" + assert(data['_tag'] == tagstr) + + if data['_type'] == 'error': + raise ValueError('Error: {}'.format(data['error'])) + + assert(data['_type'] == 'begin') + + # Ideally, we would confirm that this is our "begin", but that + # would need the cmd passed into this method, and that would + # probably require parsing the cmdline passed to us :-( + # assert(data['cmd'] == cmd) + + result = list() + error = None + + while True: + data, _ = self.sock.recvfrom(1024) + data = json.loads(data.decode('utf8')) + + if data['_tag'] != tagstr: + # this packet is not for us, ignore it + continue + + if data['_type'] == 'error': + # we still expect an end packet, so save the error + error = ValueError('Error: {}'.format(data['error'])) + continue + + if data['_type'] == 'end': + if error: + raise error + return result + + if data['_type'] != 'row': + raise ValueError('Unknown data type {} from ' + 'edge'.format(data['_type'])) + + # remove our boring metadata + del data['_tag'] + del data['_type'] + + if self.debug: + print(data) + + result.append(data) + + def _call(self, msgtype, cmdline): + """Perform a rpc call""" + tagstr, msgstr = self._cmdstr(msgtype, cmdline) + self.sock.sendto(msgstr.encode('utf8'), (self.address, self.port)) + return self._rx(tagstr) + + def read(self, cmdline): + return self._call('r', cmdline) + + def write(self, cmdline): + return self._call('w', cmdline) + + +def str_table(rows, columns): + """Given an array of dicts, do a simple table print""" + result = list() + widths = collections.defaultdict(lambda: 0) + + if len(rows) == 0: + # No data to show, be sure not to truncate the column headings + for col in columns: + widths[col] = len(col) + else: + for row in rows: + for col in columns: + if col in row: + widths[col] = max(widths[col], len(str(row[col]))) + + for col in columns: + if widths[col] == 0: + widths[col] = 1 + result += "{:{}.{}} ".format(col, widths[col], widths[col]) + result += "\n" + + for row in rows: + for col in columns: + if col in row: + data = row[col] + else: + data = '' + result += "{:{}} ".format(data, widths[col]) + result += "\n" + + return ''.join(result) + + +def subcmd_show_supernodes(rpc, args): + rows = rpc.read('supernodes') + columns = [ + 'version', + 'current', + 'macaddr', + 'sockaddr', + 'uptime', + ] + + return str_table(rows, columns) + + +def subcmd_show_edges(rpc, args): + rows = rpc.read('edges') + columns = [ + 'mode', + 'ip4addr', + 'macaddr', + 'sockaddr', + 'desc', + ] + + return str_table(rows, columns) + + +def subcmd_show_help(rpc, args): + result = 'Commands with pretty-printed output:\n\n' + for name, cmd in subcmds.items(): + result += "{:12} {}\n".format(name, cmd['help']) + + result += "\n" + result += "Possble remote commands:\n" + result += "(those without a pretty-printer will pass-through)\n\n" + rows = rpc.read('help') + for row in rows: + result += "{:12} {}\n".format(row['cmd'], row['help']) + return result + + +subcmds = { + 'help': { + 'func': subcmd_show_help, + 'help': 'Show available commands', + }, + 'supernodes': { + 'func': subcmd_show_supernodes, + 'help': 'Show the list of supernodes', + }, + 'edges': { + 'func': subcmd_show_edges, + 'help': 'Show the list of edges/peers', + }, +} + + +def subcmd_default(rpc, args): + """Just pass command through to edge""" + cmdline = ' '.join([args.cmd] + args.args) + if args.write: + rows = rpc.write(cmdline) + else: + rows = rpc.read(cmdline) + return json.dumps(rows, sort_keys=True, indent=4) + + +def main(): + ap = argparse.ArgumentParser( + description='Query the running local n2n edge') + ap.add_argument('-t', '--mgmtport', action='store', default=5644, + help='Management Port (default=5644)', type=int) + ap.add_argument('-k', '--key', action='store', + help='Password for mgmt commands') + ap.add_argument('-d', '--debug', action='store_true', + help='Also show raw internal data') + ap.add_argument('--raw', action='store_true', + help='Force cmd to avoid any pretty printing') + + group = ap.add_mutually_exclusive_group() + group.add_argument('--read', action='store_true', + help='Make a read request (default)') + group.add_argument('--write', action='store_true', + help='Make a write request (only to non pretty' + 'printed cmds)') + + ap.add_argument('cmd', action='store', + help='Command to run (try "help" for list)') + ap.add_argument('args', action='store', nargs="*", + help='Optional args for the command') + + args = ap.parse_args() + + if args.raw or (args.cmd not in subcmds): + func = subcmd_default + else: + func = subcmds[args.cmd]['func'] + + rpc = JsonUDP(args.mgmtport) + rpc.debug = args.debug + rpc.key = args.key + + try: + result = func(rpc, args) + except socket.timeout as e: + print(e) + exit(1) + + print(result) + + +if __name__ == '__main__': + main() diff --git a/bundles/n2n_ntop_v3/scripts/n2n-gateway.sh b/bundles/n2n_ntop_v3/scripts/n2n-gateway.sh new file mode 100644 index 00000000..0990d3a3 --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/n2n-gateway.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# +# This is a sample script to route all the host traffic towards a remote +# gateway, which is reacheable via the n2n virtual interface. +# +# This assumes the n2n connection is already been established and the +# VPN gateway can be pinged by this host. +# + +####################################################### +# CONFIG +####################################################### + +# The IP address of the gateway through the n2n interface +N2N_GATEWAY="192.168.100.1" + +# The IP address of the supernode as configured in n2n +N2N_SUPERNODE="1.2.3.4" + +# The n2n interface name +N2N_INTERFACE="n2n0" + +# The DNS server to use. Must be a public DNS or a DNS located on the +# N2N virtual network, otherwise DNS query information will be leaked +# outside the VPN. +DNS_SERVER="8.8.8.8" + +####################################################### +# END CONFIG +####################################################### + +if [[ $UID -ne 0 ]]; then + echo "This script must be run as root" + exit 1 +fi + +if ! ip route get $N2N_GATEWAY | grep -q $N2N_INTERFACE ; then + echo "Cannot reach the gateway ($N2N_GATEWAY) via $N2N_INTERFACE. Is edge running?" + exit 1 +fi + +# Determine the current internet gateway +internet_gateway=$(ip route get 8.8.8.8 | head -n1 | awk '{ print $3 }') + +# Backup the DNS resolver configuration and use the specified server +cp /etc/resolv.conf /etc/resolv.conf.my_bak +echo "Using DNS server $DNS_SERVER" +echo "nameserver $DNS_SERVER" > /etc/resolv.conf + +# The public IP of the supernode must be reachable via the internet gateway +# Whereas all the other traffic will go through the new VPN gateway. +ip route add $N2N_SUPERNODE via "$internet_gateway" +ip route del default +echo "Forwarding traffic via $N2N_GATEWAY" +ip route add default via $N2N_GATEWAY + +function stopService { + echo "Deleting custom routes" + ip route del default + ip route del $N2N_SUPERNODE via "$internet_gateway" + + echo "Restoring original gateway $internet_gateway" + ip route add default via "$internet_gateway" + + echo "Restoring original DNS" + mv /etc/resolv.conf.my_bak /etc/resolv.conf + + exit 0 +} + +# setup signal handlers +trap "stopService" SIGHUP SIGINT SIGTERM + +# enter wait loop +echo "VPN is now up" +while :; do sleep 300; done diff --git a/bundles/n2n_ntop_v3/scripts/n2n-httpd b/bundles/n2n_ntop_v3/scripts/n2n-httpd new file mode 100644 index 00000000..9211915a --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/n2n-httpd @@ -0,0 +1,543 @@ +#!/usr/bin/env python3 +# Licensed under GPLv3 +# +# Simple http server to allow user control of n2n edge nodes +# +# Currently only for demonstration +# - needs nicer looking html written +# - needs more json interfaces in edge +# +# Try it out with +# http://localhost:8080/ +# http://localhost:8080/edge/edges +# http://localhost:8080/edge/supernodes + +import argparse +import socket +import json +import socketserver +import http.server +import signal +import functools +import base64 + +from http import HTTPStatus + + +class JsonUDP(): + """encapsulate communication with the edge""" + + def __init__(self, port): + self.address = "127.0.0.1" + self.port = port + self.tag = 0 + self.key = None + self.debug = False + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.settimeout(1) + + def _next_tag(self): + tagstr = str(self.tag) + self.tag = (self.tag + 1) % 1000 + return tagstr + + def _cmdstr(self, msgtype, cmdline): + """Create the full command string to send""" + tagstr = self._next_tag() + + options = [tagstr] + if self.key is not None: + options += ['1'] # Flags set for auth key field + options += [self.key] + optionsstr = ':'.join(options) + + return tagstr, ' '.join((msgtype, optionsstr, cmdline)) + + def _rx(self, tagstr): + """Wait for rx packets""" + + # TODO: there are no timeouts with any of the recv calls + data, _ = self.sock.recvfrom(1024) + data = json.loads(data.decode('utf8')) + + # TODO: We assume the first packet we get will be tagged for us + # and be either an "error" or a "begin" + assert(data['_tag'] == tagstr) + + if data['_type'] == 'error': + raise ValueError('Error: {}'.format(data['error'])) + + assert(data['_type'] == 'begin') + + # Ideally, we would confirm that this is our "begin", but that + # would need the cmd passed into this method, and that would + # probably require parsing the cmdline passed to us :-( + # assert(data['cmd'] == cmd) + + result = list() + error = None + + while True: + data, _ = self.sock.recvfrom(1024) + data = json.loads(data.decode('utf8')) + + if data['_tag'] != tagstr: + # this packet is not for us, ignore it + continue + + if data['_type'] == 'error': + # we still expect an end packet, so save the error + error = ValueError('Error: {}'.format(data['error'])) + continue + + if data['_type'] == 'end': + if error: + raise error + return result + + if data['_type'] != 'row': + raise ValueError('Unknown data type {} from ' + 'edge'.format(data['_type'])) + + # remove our boring metadata + del data['_tag'] + del data['_type'] + + if self.debug: + print(data) + + result.append(data) + + def _call(self, msgtype, cmdline): + """Perform a rpc call""" + tagstr, msgstr = self._cmdstr(msgtype, cmdline) + self.sock.sendto(msgstr.encode('utf8'), (self.address, self.port)) + return self._rx(tagstr) + + def read(self, cmdline): + return self._call('r', cmdline) + + def write(self, cmdline): + return self._call('w', cmdline) + + +pages = { + "/script.js": { + "content_type": "text/javascript", + "content": """ +var verbose=-1; + +function rows2verbose(id, unused, data) { + row0 = data[0] + verbose = row0['traceLevel'] + + let div = document.getElementById(id); + div.innerHTML=verbose +} + +function rows2keyvalue(id, keys, data) { + let s = "" + data.forEach((row) => { + keys.forEach((key) => { + if (key in row) { + s += "
" + key + "" + row[key]; + } + }); + }); + + s += "
" + let div = document.getElementById(id); + div.innerHTML=s +} + +function rows2keyvalueall(id, unused, data) { + let s = "" + data.forEach((row) => { + Object.keys(row).forEach((key) => { + s += "
" + key + "" + row[key]; + }); + }); + + s += "
" + let div = document.getElementById(id); + div.innerHTML=s +} + +function rows2table(id, columns, data) { + let s = "" + s += "" + columns.forEach((col) => { + s += "" + columns.forEach((col) => { + val = row[col] + if (typeof val === "undefined") { + val = '' + } + s += "
" + col + }); + data.forEach((row) => { + s += "
" + val + }); + }); + + s += "
" + let div = document.getElementById(id); + div.innerHTML=s +} + +function do_get(url, id, handler, handler_param) { + fetch(url) + .then(function (response) { + if (!response.ok) { + throw new Error('Fetch got ' + response.status) + } + return response.json(); + }) + .then(function (data) { + handler(id,handler_param,data); + + // update the timestamp on success + let now = Math.round(new Date().getTime() / 1000); + let time = document.getElementById('time'); + time.innerHTML=now; + }) + .catch(function (err) { + console.log('error: ' + err); + }); +} + +function do_post(url, body, id, handler, handler_param) { + fetch(url, {method:'POST', body: body}) + .then(function (response) { + if (!response.ok) { + throw new Error('Fetch got ' + response.status) + } + return response.json(); + }) + .then(function (data) { + handler(id,handler_param,data); + }) + .catch(function (err) { + console.log('error: ' + err); + }); +} + +function do_stop(tracelevel) { + // FIXME: uses global in script library + fetch(nodetype + '/stop', {method:'POST'}) +} + +function setverbose(tracelevel) { + if (tracelevel < 0) { + tracelevel = 0; + } + // FIXME: uses global in script library + do_post( + nodetype + '/verbose', tracelevel, 'verbose', + rows2verbose, null + ); +} + +function refresh_setup(interval) { + var timer = setInterval(refresh_job, interval); +} +""", + }, + "/": { + "content_type": "text/html; charset=utf-8", + "content": """ + + + n2n edge management + + + + + +
Last Updated: +
+
+ +
Logging Verbosity: + +
+
+ + +
+
+

+
+ Edges/Peers: +
+
+ Supernodes: +
+
+
+
+
+ + + + + +""", + }, + "/supernode.html": { + "content_type": "text/html; charset=utf-8", + "content": """ + + + n2n supernode management + + + + + +
Last Updated: +
+
+ +
Logging Verbosity: + +
+
+ + + +
+
+ Communities: +
+
+ Edges/Peers: +
+
+
+
+
+ + + + + +""", + }, +} + + +class SimpleHandler(http.server.BaseHTTPRequestHandler): + + def __init__(self, rpc, snrpc, *args, **kwargs): + self.rpc = rpc + self.snrpc = snrpc + super().__init__(*args, **kwargs) + + def log_request(self, code='-', size='-'): + # Dont spam the output + pass + + def _simplereply(self, number, message): + self.send_response(number) + self.end_headers() + self.wfile.write(message.encode('utf8')) + + def _replyjson(self, data): + self.send_response(HTTPStatus.OK) + self.send_header('Content-type', 'application/json') + self.end_headers() + self.wfile.write(json.dumps(data).encode('utf8')) + + def _replyunauth(self): + self.send_response(HTTPStatus.UNAUTHORIZED) + self.send_header('WWW-Authenticate', 'Basic realm="n2n"') + self.end_headers() + + def _extractauth(self, rpc): + # Avoid caching the key inside the object for all clients + rpc.key = None + + header = self.headers.get('Authorization') + if header is not None: + authtype, encoded = header.split(' ') + if authtype == 'Basic': + user, key = base64.b64decode(encoded).decode('utf8').split(':') + rpc.key = key + + if rpc.key is None: + rpc.key = rpc.defaultkey + + def _rpc(self, method, cmdline): + try: + data = method(cmdline) + except ValueError as e: + if str(e) == "Error: badauth": + self._replyunauth() + return + + self._simplereply(HTTPStatus.BAD_REQUEST, 'Bad Command') + return + except socket.timeout as e: + self._simplereply(HTTPStatus.REQUEST_TIMEOUT, str(e)) + return + + self._replyjson(data) + return + + def _rpc_read(self, rpc): + self._extractauth(rpc) + tail = self.path.split('/') + cmd = tail[2] + # if reads ever need args, could use more of the tail + + self._rpc(rpc.read, cmd) + + def _rpc_write(self, rpc): + self._extractauth(rpc) + content_length = int(self.headers['Content-Length']) + post_data = self.rfile.read(content_length).decode('utf8') + + tail = self.path.split('/') + cmd = tail[2] + cmdline = cmd + ' ' + post_data + + self._rpc(rpc.write, cmdline) + + def do_GET(self): + if self.path.startswith("/edge/"): + self._rpc_read(self.rpc) + return + + if self.path.startswith("/supernode/"): + self._rpc_read(self.snrpc) + return + + if self.path in pages: + page = pages[self.path] + + self.send_response(HTTPStatus.OK) + self.send_header('Content-type', page['content_type']) + self.end_headers() + self.wfile.write(page['content'].encode('utf8')) + return + + self._simplereply(HTTPStatus.NOT_FOUND, 'Not Found') + return + + def do_POST(self): + if self.path.startswith("/edge/"): + self._rpc_write(self.rpc) + return + + if self.path.startswith("/supernode/"): + self._rpc_write(self.snrpc) + return + + +def main(): + ap = argparse.ArgumentParser( + description='Control the running local n2n edge via http') + ap.add_argument('-t', '--mgmtport', action='store', default=5644, + help='Management Port (default=5644)', type=int) + ap.add_argument('--snmgmtport', action='store', default=5645, + help='Supernode Management Port (default=5645)', type=int) + ap.add_argument('-k', '--key', action='store', + help='Password for mgmt commands') + ap.add_argument('-d', '--debug', action='store_true', + help='Also show raw internal data') + ap.add_argument('port', action='store', + default=8080, type=int, nargs='?', + help='Serve requests on TCP port (default 8080)') + + args = ap.parse_args() + + rpc = JsonUDP(args.mgmtport) + rpc.debug = args.debug + rpc.defaultkey = args.key + + snrpc = JsonUDP(args.snmgmtport) + snrpc.debug = args.debug + snrpc.defaultkey = args.key + + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + socketserver.TCPServer.allow_reuse_address = True + handler = functools.partial(SimpleHandler, rpc, snrpc) + + httpd = socketserver.TCPServer(("", args.port), handler) + try: + httpd.serve_forever() + except KeyboardInterrupt: + return + + +if __name__ == '__main__': + main() diff --git a/bundles/n2n_ntop_v3/scripts/test_harness.sh b/bundles/n2n_ntop_v3/scripts/test_harness.sh new file mode 100644 index 00000000..5f520759 --- /dev/null +++ b/bundles/n2n_ntop_v3/scripts/test_harness.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# This expects to find the tests in the tools dir and the expected results +# in the tests dir. + +TESTS=" + tests-compress + tests-elliptic + tests-hashing + tests-transform + tests-wire +" + +TOOLSDIR=tools +TESTDATA=tests + +# Allow both dirs be overidden +[ -n "$1" ] && TOOLSDIR="$1" +[ -n "$2" ] && TESTDATA="$2" + +# Confirm we have all the tools and data +for i in $TESTS; do + if [ ! -e "$TOOLSDIR/$i" ]; then + echo "Could not find test $TOOLSDIR/$i" + exit 1 + fi + if [ ! -e "$TESTDATA/$i.expected" ]; then + echo "Could not find testdata $TESTDATA/$i.expected" + exit 1 + fi +done + +# Actually run the tests +set -e +for i in $TESTS; do + echo "$TOOLSDIR/$i >$TESTDATA/$i.out" + "$TOOLSDIR/$i" >"$TESTDATA/$i.out" + cmp "$TESTDATA/$i.expected" "$TESTDATA/$i.out" +done diff --git a/bundles/n2n_ntop_v3/src/aes.c b/bundles/n2n_ntop_v3/src/aes.c new file mode 100644 index 00000000..12b161be --- /dev/null +++ b/bundles/n2n_ntop_v3/src/aes.c @@ -0,0 +1,1313 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +#if defined (HAVE_OPENSSL_1_1) // openSSL 1.1 --------------------------------------------------------------------- + + +// get any erorr message out of openssl +// taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling +static char *openssl_err_as_string (void) { + + BIO *bio = BIO_new (BIO_s_mem ()); + ERR_print_errors (bio); + char *buf = NULL; + size_t len = BIO_get_mem_data (bio, &buf); + char *ret = (char *) calloc (1, 1 + len); + + if(ret) + memcpy (ret, buf, len); + + BIO_free (bio); + + return ret; +} + + +int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + int evp_len; + int evp_ciphertext_len; + + if(1 == EVP_EncryptInit_ex(ctx->enc_ctx, ctx->cipher, NULL, ctx->key, iv)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx->enc_ctx, 0)) { + if(1 == EVP_EncryptUpdate(ctx->enc_ctx, out, &evp_len, in, in_len)) { + evp_ciphertext_len = evp_len; + if(1 == EVP_EncryptFinal_ex(ctx->enc_ctx, out + evp_len, &evp_len)) { + evp_ciphertext_len += evp_len; + if(evp_ciphertext_len != in_len) + traceEvent(TRACE_ERROR, "aes_cbc_encrypt openssl encryption: encrypted %u bytes where %u were expected", + evp_ciphertext_len, in_len); + } else + traceEvent(TRACE_ERROR, "aes_cbc_encrypt openssl final encryption: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_encrypt openssl encrpytion: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_encrypt openssl padding setup: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_encrypt openssl init: %s", + openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx->enc_ctx); + + return 0; +} + + +int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + int evp_len; + int evp_plaintext_len; + + if(1 == EVP_DecryptInit_ex(ctx->dec_ctx, ctx->cipher, NULL, ctx->key, iv)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx->dec_ctx, 0)) { + if(1 == EVP_DecryptUpdate(ctx->dec_ctx, out, &evp_len, in, in_len)) { + evp_plaintext_len = evp_len; + if(1 == EVP_DecryptFinal_ex(ctx->dec_ctx, out + evp_len, &evp_len)) { + evp_plaintext_len += evp_len; + if(evp_plaintext_len != in_len) + traceEvent(TRACE_ERROR, "aes_cbc_decrypt openssl decryption: decrypted %u bytes where %u were expected", + evp_plaintext_len, in_len); + } else + traceEvent(TRACE_ERROR, "aes_cbc_decrypt openssl final decryption: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_decrypt openssl decrpytion: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_decrypt openssl padding setup: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "aes_cbc_decrypt openssl init: %s", + openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx->dec_ctx); + + return 0; +} + + +int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { + + AES_ecb_encrypt(in, out, &(ctx->ecb_dec_key), AES_DECRYPT); + + return 0; +} + + +int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) { + + // allocate context... + *ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t)); + if(!(*ctx)) + return -1; + + // ...and fill her up: + + // initialize data structures + if(!((*ctx)->enc_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "aes_init openssl's evp_* encryption context creation failed: %s", + openssl_err_as_string()); + return -1; + } + + if(!((*ctx)->dec_ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "aes_init openssl's evp_* decryption context creation failed: %s", + openssl_err_as_string()); + return -1; + } + + // check key size and make key size (given in bytes) dependant settings + switch(key_size) { + case AES128_KEY_BYTES: // 128 bit key size + (*ctx)->cipher = EVP_aes_128_cbc(); + break; + case AES192_KEY_BYTES: // 192 bit key size + (*ctx)->cipher = EVP_aes_192_cbc(); + break; + case AES256_KEY_BYTES: // 256 bit key size + (*ctx)->cipher = EVP_aes_256_cbc(); + break; + default: + traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size); + return -1; + } + + // key materiel handling + memcpy((*ctx)->key, key, key_size); + AES_set_decrypt_key(key, key_size * 8, &((*ctx)->ecb_dec_key)); + + return 0; +} + + +#elif defined (__AES__) && defined (__SSE2__) // Intel's AES-NI --------------------------------------------------- + + +// inspired by https://gist.github.com/acapola/d5b940da024080dfaf5f +// furthered by the help of Sebastian Ramacher's implementation found at +// https://chromium.googlesource.com/external/github.com/dlitz/pycrypto/+/junk/master/src/AESNI.c +// modified along Intel's white paper on AES Instruction Set +// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf + + +static __m128i aes128_keyexpand(__m128i key, __m128i keygened, uint8_t shuf) { + + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); + + // unfortunately, shuffle expects immediate argument, thus the not-so-stylish switch ... + // REVISIT: either macrorize this whole function (and perhaps the following one) or + // use shuffle_epi8 (which would require SSSE3 instead of SSE2) + switch(shuf) { + case 0x55: + keygened = _mm_shuffle_epi32(keygened, 0x55 ); + break; + case 0xaa: + keygened = _mm_shuffle_epi32(keygened, 0xaa ); + break; + case 0xff: + keygened = _mm_shuffle_epi32(keygened, 0xff ); + break; + default: + break; + } + + return _mm_xor_si128(key, keygened); +} + + +static __m128i aes192_keyexpand_2(__m128i key, __m128i key2) { + + key = _mm_shuffle_epi32(key, 0xff); + key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4)); + + return _mm_xor_si128(key, key2); +} + + +#define KEYEXP128(K, I) aes128_keyexpand (K, _mm_aeskeygenassist_si128(K, I), 0xff) +#define KEYEXP192(K1, K2, I) aes128_keyexpand (K1, _mm_aeskeygenassist_si128(K2, I), 0x55) +#define KEYEXP192_2(K1, K2) aes192_keyexpand_2(K1, K2) +#define KEYEXP256(K1, K2, I) aes128_keyexpand (K1, _mm_aeskeygenassist_si128(K2, I), 0xff) +#define KEYEXP256_2(K1, K2) aes128_keyexpand (K1, _mm_aeskeygenassist_si128(K2, 0x00), 0xaa) + + +// key setup +static int aes_internal_key_setup (aes_context_t *ctx, const uint8_t *key, int key_bits) { + + // number of rounds + ctx->Nr = 6 + (key_bits / 32); + + // encryption keys + switch(key_bits) { + case 128: { + ctx->rk_enc[ 0] = _mm_loadu_si128((const __m128i*)key); + ctx->rk_enc[ 1] = KEYEXP128(ctx->rk_enc[0], 0x01); + ctx->rk_enc[ 2] = KEYEXP128(ctx->rk_enc[1], 0x02); + ctx->rk_enc[ 3] = KEYEXP128(ctx->rk_enc[2], 0x04); + ctx->rk_enc[ 4] = KEYEXP128(ctx->rk_enc[3], 0x08); + ctx->rk_enc[ 5] = KEYEXP128(ctx->rk_enc[4], 0x10); + ctx->rk_enc[ 6] = KEYEXP128(ctx->rk_enc[5], 0x20); + ctx->rk_enc[ 7] = KEYEXP128(ctx->rk_enc[6], 0x40); + ctx->rk_enc[ 8] = KEYEXP128(ctx->rk_enc[7], 0x80); + ctx->rk_enc[ 9] = KEYEXP128(ctx->rk_enc[8], 0x1B); + ctx->rk_enc[10] = KEYEXP128(ctx->rk_enc[9], 0x36); + break; + } + case 192: { + __m128i temp[2]; + ctx->rk_enc[ 0] = _mm_loadu_si128((const __m128i*) key); + + ctx->rk_enc[ 1] = _mm_loadu_si128((const __m128i*) (key+16)); + temp[0] = KEYEXP192(ctx->rk_enc[0], ctx->rk_enc[1], 0x01); + temp[1] = KEYEXP192_2(temp[0], ctx->rk_enc[1]); + ctx->rk_enc[ 1] = (__m128i)_mm_shuffle_pd((__m128d)ctx->rk_enc[1], (__m128d)temp[0], 0); + + ctx->rk_enc[ 2] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); + ctx->rk_enc[ 3] = KEYEXP192(temp[0], temp[1], 0x02); + + ctx->rk_enc[ 4] = KEYEXP192_2(ctx->rk_enc[3], temp[1]); + temp[0] = KEYEXP192(ctx->rk_enc[3], ctx->rk_enc[4], 0x04); + temp[1] = KEYEXP192_2(temp[0], ctx->rk_enc[4]); + ctx->rk_enc[ 4] = (__m128i)_mm_shuffle_pd((__m128d)ctx->rk_enc[4], (__m128d)temp[0], 0); + + ctx->rk_enc[ 5] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); + ctx->rk_enc[ 6] = KEYEXP192(temp[0], temp[1], 0x08); + + ctx->rk_enc[ 7] = KEYEXP192_2(ctx->rk_enc[6], temp[1]); + temp[0] = KEYEXP192(ctx->rk_enc[6], ctx->rk_enc[7], 0x10); + temp[1] = KEYEXP192_2(temp[0], ctx->rk_enc[7]); + ctx->rk_enc[ 7] = (__m128i)_mm_shuffle_pd((__m128d)ctx->rk_enc[7], (__m128d)temp[0], 0); + + ctx->rk_enc[ 8] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); + ctx->rk_enc[ 9] = KEYEXP192(temp[0], temp[1], 0x20); + + ctx->rk_enc[10] = KEYEXP192_2(ctx->rk_enc[9], temp[1]); + temp[0] = KEYEXP192(ctx->rk_enc[9], ctx->rk_enc[10], 0x40); + temp[1] = KEYEXP192_2(temp[0], ctx->rk_enc[10]); + ctx->rk_enc[10] = (__m128i)_mm_shuffle_pd((__m128d)ctx->rk_enc[10], (__m128d) temp[0], 0); + + ctx->rk_enc[11] = (__m128i)_mm_shuffle_pd((__m128d)temp[0],(__m128d) temp[1], 1); + ctx->rk_enc[12] = KEYEXP192(temp[0], temp[1], 0x80); + break; + } + case 256: { + ctx->rk_enc[ 0] = _mm_loadu_si128((const __m128i*) key); + ctx->rk_enc[ 1] = _mm_loadu_si128((const __m128i*) (key+16)); + ctx->rk_enc[ 2] = KEYEXP256(ctx->rk_enc[0], ctx->rk_enc[1], 0x01); + ctx->rk_enc[ 3] = KEYEXP256_2(ctx->rk_enc[1], ctx->rk_enc[2]); + ctx->rk_enc[ 4] = KEYEXP256(ctx->rk_enc[2], ctx->rk_enc[3], 0x02); + ctx->rk_enc[ 5] = KEYEXP256_2(ctx->rk_enc[3], ctx->rk_enc[4]); + ctx->rk_enc[ 6] = KEYEXP256(ctx->rk_enc[4], ctx->rk_enc[5], 0x04); + ctx->rk_enc[ 7] = KEYEXP256_2(ctx->rk_enc[5], ctx->rk_enc[6]); + ctx->rk_enc[ 8] = KEYEXP256(ctx->rk_enc[6], ctx->rk_enc[7], 0x08); + ctx->rk_enc[ 9] = KEYEXP256_2(ctx->rk_enc[7], ctx->rk_enc[8]); + ctx->rk_enc[10] = KEYEXP256(ctx->rk_enc[8], ctx->rk_enc[9], 0x10); + ctx->rk_enc[11] = KEYEXP256_2(ctx->rk_enc[9], ctx->rk_enc[10]); + ctx->rk_enc[12] = KEYEXP256(ctx->rk_enc[10], ctx->rk_enc[11], 0x20); + ctx->rk_enc[13] = KEYEXP256_2(ctx->rk_enc[11], ctx->rk_enc[12]); + ctx->rk_enc[14] = KEYEXP256(ctx->rk_enc[12], ctx->rk_enc[13], 0x40); + break; + } + } + + // derive decryption keys + for(int i = 1; i < ctx->Nr; ++i) { + ctx->rk_dec[ctx->Nr - i] = _mm_aesimc_si128(ctx->rk_enc[i]); + } + ctx->rk_dec[ 0] = ctx->rk_enc[ctx->Nr]; + + return ctx->Nr; +} + + +static void aes_internal_encrypt (aes_context_t *ctx, const uint8_t pt[16], uint8_t ct[16]) { + + __m128i tmp = _mm_loadu_si128((__m128i*)pt); + + tmp = _mm_xor_si128 (tmp, ctx->rk_enc[ 0]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 1]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 2]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 3]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 4]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 5]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 6]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 7]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 8]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 9]); + if(ctx->Nr > 10) { + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[10]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[11]); + if(ctx->Nr > 12) { + tmp = _mm_aesenc_si128(tmp, ctx->rk_enc[12]); + tmp = _mm_aesenc_si128(tmp, ctx->rk_enc[13]); + } + } + tmp = _mm_aesenclast_si128 (tmp, ctx->rk_enc[ctx->Nr]); + + _mm_storeu_si128((__m128i*) ct, tmp); +} + + +static void aes_internal_decrypt (aes_context_t *ctx, const uint8_t ct[16], uint8_t pt[16]) { + + __m128i tmp = _mm_loadu_si128((__m128i*)ct); + + tmp = _mm_xor_si128 (tmp, ctx->rk_dec[ 0]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 1]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 2]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 3]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 4]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 5]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 6]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 7]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 8]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 9]); + if(ctx->Nr > 10) { + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[10]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[11]); + if(ctx->Nr > 12) { + tmp = _mm_aesdec_si128(tmp, ctx->rk_dec[12]); + tmp = _mm_aesdec_si128(tmp, ctx->rk_dec[13]); + } + } + tmp = _mm_aesdeclast_si128 (tmp, ctx->rk_enc[ 0]); + + _mm_storeu_si128((__m128i*) pt, tmp); +} + + +// public API + + +int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { + + aes_internal_decrypt(ctx, in, out); + + return AES_BLOCK_SIZE; +} + + +// not used +int aes_ecb_encrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { + + aes_internal_encrypt(ctx, in, out); + + return AES_BLOCK_SIZE; +} + + +int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + int n; /* number of blocks */ + int ret = (int)in_len & 15; /* remainder */ + + __m128i ivec = _mm_loadu_si128((__m128i*)iv); + + for(n = in_len / 16; n != 0; n--) { + __m128i tmp = _mm_loadu_si128((__m128i*)in); + in += 16; + tmp = _mm_xor_si128(tmp, ivec); + + tmp = _mm_xor_si128 (tmp, ctx->rk_enc[ 0]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 1]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 2]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 3]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 4]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 5]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 6]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 7]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 8]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[ 9]); + if(ctx->Nr > 10) { + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[10]); + tmp = _mm_aesenc_si128 (tmp, ctx->rk_enc[11]); + if(ctx->Nr > 12) { + tmp = _mm_aesenc_si128(tmp, ctx->rk_enc[12]); + tmp = _mm_aesenc_si128(tmp, ctx->rk_enc[13]); + } + } + tmp = _mm_aesenclast_si128 (tmp, ctx->rk_enc[ctx->Nr]); + + ivec = tmp; + + _mm_storeu_si128((__m128i*)out, tmp); + out += 16; + } + + return ret; +} + + +int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + int n; /* number of blocks */ + int ret = (int)in_len & 15; /* remainder */ + + __m128i ivec = _mm_loadu_si128((__m128i*)iv); + + // 4 parallel rails of AES decryption to reduce data dependencies in x86's deep pipelines + for(n = in_len / 16; n > 3; n -=4) { + __m128i tmp1 = _mm_loadu_si128((__m128i*)in); in += 16; + __m128i tmp2 = _mm_loadu_si128((__m128i*)in); in += 16; + __m128i tmp3 = _mm_loadu_si128((__m128i*)in); in += 16; + __m128i tmp4 = _mm_loadu_si128((__m128i*)in); in += 16; + + __m128i old_in1 = tmp1; + __m128i old_in2 = tmp2; + __m128i old_in3 = tmp3; + __m128i old_in4 = tmp4; + + tmp1 = _mm_xor_si128 (tmp1, ctx->rk_dec[ 0]); tmp2 = _mm_xor_si128 (tmp2, ctx->rk_dec[ 0]); + tmp3 = _mm_xor_si128 (tmp3, ctx->rk_dec[ 0]); tmp4 = _mm_xor_si128 (tmp4, ctx->rk_dec[ 0]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 1]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 1]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 1]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 1]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 2]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 2]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 2]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 2]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 3]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 3]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 3]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 3]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 4]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 4]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 4]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 4]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 5]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 5]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 5]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 5]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 6]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 6]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 6]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 6]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 7]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 7]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 7]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 7]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 8]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 8]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 8]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 8]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 9]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 9]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[ 9]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[ 9]); + + if(ctx->Nr > 10) { + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[10]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[10]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[10]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[10]); + + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[11]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[11]); + tmp3 = _mm_aesdec_si128 (tmp3, ctx->rk_dec[11]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[11]); + + if(ctx->Nr > 12) { + tmp1 = _mm_aesdec_si128(tmp1, ctx->rk_dec[12]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[12]); + tmp3 = _mm_aesdec_si128(tmp3, ctx->rk_dec[12]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[12]); + + tmp1 = _mm_aesdec_si128(tmp1, ctx->rk_dec[13]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[13]); + tmp3 = _mm_aesdec_si128(tmp3, ctx->rk_dec[13]); tmp4 = _mm_aesdec_si128 (tmp4, ctx->rk_dec[13]); + } + } + tmp1 = _mm_aesdeclast_si128(tmp1, ctx->rk_enc[ 0]); tmp2 = _mm_aesdeclast_si128(tmp2, ctx->rk_enc[ 0]); + tmp3 = _mm_aesdeclast_si128(tmp3, ctx->rk_enc[ 0]); tmp4 = _mm_aesdeclast_si128(tmp4, ctx->rk_enc[ 0]); + + tmp1 = _mm_xor_si128 (tmp1, ivec); tmp2 = _mm_xor_si128 (tmp2, old_in1); + tmp3 = _mm_xor_si128 (tmp3, old_in2); tmp4 = _mm_xor_si128 (tmp4, old_in3); + + ivec = old_in4; + + _mm_storeu_si128((__m128i*) out, tmp1); out += 16; + _mm_storeu_si128((__m128i*) out, tmp2); out += 16; + _mm_storeu_si128((__m128i*) out, tmp3); out += 16; + _mm_storeu_si128((__m128i*) out, tmp4); out += 16; + } + // now: less than 4 blocks remaining + + // if 2 or 3 blocks remaining --> this code handles two of them + if(n > 1) { + n-= 2; + + __m128i tmp1 = _mm_loadu_si128((__m128i*)in); in += 16; + __m128i tmp2 = _mm_loadu_si128((__m128i*)in); in += 16; + + __m128i old_in1 = tmp1; + __m128i old_in2 = tmp2; + + tmp1 = _mm_xor_si128 (tmp1, ctx->rk_dec[ 0]); tmp2 = _mm_xor_si128 (tmp2, ctx->rk_dec[ 0]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 1]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 1]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 2]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 2]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 3]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 3]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 4]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 4]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 5]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 5]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 6]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 6]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 7]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 7]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 8]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 8]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[ 9]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[ 9]); + if(ctx->Nr > 10) { + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[10]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[10]); + tmp1 = _mm_aesdec_si128 (tmp1, ctx->rk_dec[11]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[11]); + if(ctx->Nr > 12) { + tmp1 = _mm_aesdec_si128(tmp1, ctx->rk_dec[12]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[12]); + tmp1 = _mm_aesdec_si128(tmp1, ctx->rk_dec[13]); tmp2 = _mm_aesdec_si128 (tmp2, ctx->rk_dec[13]); + } + } + tmp1 = _mm_aesdeclast_si128 (tmp1, ctx->rk_enc[ 0]); tmp2 = _mm_aesdeclast_si128(tmp2, ctx->rk_enc[ 0]); + + tmp1 = _mm_xor_si128 (tmp1, ivec); tmp2 = _mm_xor_si128 (tmp2, old_in1); + + ivec = old_in2; + + _mm_storeu_si128((__m128i*) out, tmp1); out += 16; + _mm_storeu_si128((__m128i*) out, tmp2); out += 16; + } + + // one block remaining + if(n) { + __m128i tmp = _mm_loadu_si128((__m128i*)in); + + tmp = _mm_xor_si128 (tmp, ctx->rk_dec[ 0]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 1]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 2]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 3]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 4]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 5]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 6]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 7]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 8]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[ 9]); + if(ctx->Nr > 10) { + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[10]); + tmp = _mm_aesdec_si128 (tmp, ctx->rk_dec[11]); + if(ctx->Nr > 12) { + tmp = _mm_aesdec_si128(tmp, ctx->rk_dec[12]); + tmp = _mm_aesdec_si128(tmp, ctx->rk_dec[13]); + } + } + tmp = _mm_aesdeclast_si128 (tmp, ctx->rk_enc[ 0]); + + tmp = _mm_xor_si128 (tmp, ivec); + + _mm_storeu_si128((__m128i*) out, tmp); + } + + return ret; +} + + +int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) { + + // allocate context... + *ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t)); + if(!(*ctx)) + return -1; + // ...and fill her up: + + // initialize data structures + + // check key size and make key size (given in bytes) dependant settings + switch(key_size) { + case AES128_KEY_BYTES: // 128 bit key size + break; + case AES192_KEY_BYTES: // 192 bit key size + break; + case AES256_KEY_BYTES: // 256 bit key size + break; + default: + traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size); + return -1; + } + + // key materiel handling + aes_internal_key_setup ( *ctx, key, 8 * key_size); + + return 0; +} + + +#else // plain C -------------------------------------------------------------------------- + + +// rijndael-alg-fst.c version 3.0 (December 2000) +// optimised ANSI C code for the Rijndael cipher (now AES) +// original authors: Vincent Rijmen +// Antoon Bosselaers +// Paulo Barreto +// +// was put in the public domain, taken (and modified) from +// https://fastcrypto.org/front/misc/rijndael-alg-fst.c + + +// Te0[x] = S [x].[02, 01, 01, 03]; +static const uint32_t Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU }; + +// Te1[x] = S [x].[03, 02, 01, 01]; +static const uint32_t Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U }; + +// Te2[x] = S [x].[01, 03, 02, 01]; +static const uint32_t Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U }; + +// Te3[x] = S [x].[01, 01, 03, 02]; +static const uint32_t Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU }; + +// Te4[x] = S [x].[01, 01, 01, 01]; +static const uint32_t Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U }; + +// Td0[x] = Si[x].[0e, 09, 0d, 0b]; +static const uint32_t Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U }; + +// Td1[x] = Si[x].[0b, 0e, 09, 0d]; +static const uint32_t Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U }; + +// Td2[x] = Si[x].[0d, 0b, 0e, 09]; +static const uint32_t Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U }; + +// Td3[x] = Si[x].[09, 0d, 0b, 0e]; +static const uint32_t Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U }; + +// Td4[x] = Si[x].[01, 01, 01, 01]; +static const uint32_t Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU }; + +// for 128-bit blocks, Rijndael never uses more than 10 rcon values +static const uint32_t rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000 }; + + +#define GETU32(p) (be32toh((*((uint32_t*)(p))))) +#define PUTU32(ct, st) { *((uint32_t*)(ct)) = htobe32((st)); } + +#define b0(x) ((uint8_t)(x)) +#define b1(x) ((uint8_t)((x) >> 8)) +#define b2(x) ((uint8_t)((x) >> 16)) +#define b3(x) ((uint8_t)((x) >> 24)) + +#define m0(x) ((x) & 0x000000ff) +#define m1(x) ((x) & 0x0000ff00) +#define m2(x) ((x) & 0x00ff0000) +#define m3(x) ((x) & 0xff000000) + + +// expand the cipher key into the encryption key schedule and +// return the number of rounds for the given cipher key size +static int aes_internal_key_setup_enc (uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) { + + int i = 0; + uint32_t temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + if(keyBits == 128) { + for(;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4[b2(temp)] & 0xff000000) ^ + (Te4[b1(temp)] & 0x00ff0000) ^ + (Te4[b0(temp)] & 0x0000ff00) ^ + (Te4[b3(temp)] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if(++i == 10) { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + if(keyBits == 192) { + for(;;) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te4[b2(temp)] & 0xff000000) ^ + (Te4[b1(temp)] & 0x00ff0000) ^ + (Te4[b0(temp)] & 0x0000ff00) ^ + (Te4[b3(temp)] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if(++i == 8) { + return 12; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + if(keyBits == 256) { + for(;;) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te4[b2(temp)] & 0xff000000) ^ + (Te4[b1(temp)] & 0x00ff0000) ^ + (Te4[b0(temp)] & 0x0000ff00) ^ + (Te4[b3(temp)] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if(++i == 7) { + return 14; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4[b3(temp)] & 0xff000000) ^ + (Te4[b2(temp)] & 0x00ff0000) ^ + (Te4[b1(temp)] & 0x0000ff00) ^ + (Te4[b0(temp)] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } + + return 0; +} + + +#define INVMIXCOLRK(n) rk[n] = Td0[b0(Te4[b3(rk[n])])] ^ Td1[b0(Te4[b2(rk[n])])] ^ Td2[b0(Te4[b1(rk[n])])] ^ Td3[b0(Te4[b0(rk[n])])] + + +// expand the cipher key into the decryption key schedule and +// return the number of rounds for the given cipher key size +static int aes_internal_key_setup_dec (uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) { + + int Nr, i, j; + uint32_t temp; + + // expand the cipher key + Nr = aes_internal_key_setup_enc(rk, cipherKey, keyBits); + // invert the order of the round keys + for(i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + + // apply the inverse MixColumn transform to all round keys but the first and the last + for(i = 1; i < Nr; i++) { + rk += 4; + INVMIXCOLRK(0); + INVMIXCOLRK(1); + INVMIXCOLRK(2); + INVMIXCOLRK(3); + } + + return Nr; +} + + +#define AES_ENC_ROUND(DST, SRC, round) \ + DST##0 = Te0[b3(SRC##0)] ^ Te1[b2(SRC##1)] ^ Te2[b1(SRC##2)] ^ Te3[b0(SRC##3)] ^ rk[4 * round + 0]; \ + DST##1 = Te0[b3(SRC##1)] ^ Te1[b2(SRC##2)] ^ Te2[b1(SRC##3)] ^ Te3[b0(SRC##0)] ^ rk[4 * round + 1]; \ + DST##2 = Te0[b3(SRC##2)] ^ Te1[b2(SRC##3)] ^ Te2[b1(SRC##0)] ^ Te3[b0(SRC##1)] ^ rk[4 * round + 2]; \ + DST##3 = Te0[b3(SRC##3)] ^ Te1[b2(SRC##0)] ^ Te2[b1(SRC##1)] ^ Te3[b0(SRC##2)] ^ rk[4 * round + 3]; + + +static void aes_internal_encrypt (const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t pt[16], uint8_t ct[16]) { + + uint32_t s0, s1, s2, s3, t0, t1, t2, t3; + + // map byte array block to cipher state and add initial round key + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; + + AES_ENC_ROUND(t, s, 1); + AES_ENC_ROUND(s, t, 2); + AES_ENC_ROUND(t, s, 3); + AES_ENC_ROUND(s, t, 4); + AES_ENC_ROUND(t, s, 5); + AES_ENC_ROUND(s, t, 6); + AES_ENC_ROUND(t, s, 7); + AES_ENC_ROUND(s, t, 8); + AES_ENC_ROUND(t, s, 9); + + if(Nr > 10) { + AES_ENC_ROUND(s, t, 10); + AES_ENC_ROUND(t, s, 11); + if(Nr > 12) { + AES_ENC_ROUND(s, t, 12); + AES_ENC_ROUND(t, s, 13); + } + } + + rk += Nr << 2; + // apply last round and map cipher state to byte array block + s0 = m3(Te4[b3(t0)]) ^ m2(Te4[b2(t1)]) ^ m1(Te4[b1(t2)]) ^ m0(Te4[b0(t3)]) ^ rk[0]; + PUTU32(ct , s0); + s1 = m3(Te4[b3(t1)]) ^ m2(Te4[b2(t2)]) ^ m1(Te4[b1(t3)]) ^ m0(Te4[b0(t0)]) ^ rk[1]; + PUTU32(ct + 4, s1); + s2 = m3(Te4[b3(t2)]) ^ m2(Te4[b2(t3)]) ^ m1(Te4[b1(t0)]) ^ m0(Te4[b0(t1)]) ^ rk[2]; + PUTU32(ct + 8, s2); + s3 = m3(Te4[b3(t3)]) ^ m2(Te4[b2(t0)]) ^ m1(Te4[b1(t1)]) ^ m0(Te4[b0(t2)]) ^ rk[3]; + PUTU32(ct + 12, s3); +} + + +#define AES_DEC_ROUND(DST, SRC, round) \ + DST##0 = Td0[b3(SRC##0)] ^ Td1[b2(SRC##3)] ^ Td2[b1(SRC##2)] ^ Td3[b0(SRC##1)] ^ rk[4 * round + 0]; \ + DST##1 = Td0[b3(SRC##1)] ^ Td1[b2(SRC##0)] ^ Td2[b1(SRC##3)] ^ Td3[b0(SRC##2)] ^ rk[4 * round + 1]; \ + DST##2 = Td0[b3(SRC##2)] ^ Td1[b2(SRC##1)] ^ Td2[b1(SRC##0)] ^ Td3[b0(SRC##3)] ^ rk[4 * round + 2]; \ + DST##3 = Td0[b3(SRC##3)] ^ Td1[b2(SRC##2)] ^ Td2[b1(SRC##1)] ^ Td3[b0(SRC##0)] ^ rk[4 * round + 3]; + + +static void aes_internal_decrypt (const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t ct[16], uint8_t pt[16]) { + + uint32_t s0, s1, s2, s3, t0, t1, t2, t3; + + // map byte array block to cipher state and add initial round key + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; + + AES_DEC_ROUND(t, s, 1); + AES_DEC_ROUND(s, t, 2); + AES_DEC_ROUND(t, s, 3); + AES_DEC_ROUND(s, t, 4); + AES_DEC_ROUND(t, s, 5); + AES_DEC_ROUND(s, t, 6); + AES_DEC_ROUND(t, s, 7); + AES_DEC_ROUND(s, t, 8); + AES_DEC_ROUND(t, s, 9); + + if(Nr > 10) { + AES_DEC_ROUND(s, t, 10); + AES_DEC_ROUND(t, s, 11); + if(Nr > 12) { + AES_DEC_ROUND(s, t, 12); + AES_DEC_ROUND(t, s, 13); + } + } + + rk += Nr << 2; + // apply last round and map cipher state to byte array block + s0 = m3(Td4[b3(t0)]) ^ m2(Td4[b2(t3)]) ^ m1(Td4[b1(t2)]) ^ m0(Td4[b0(t1)]) ^ rk[0]; + PUTU32(pt , s0); + s1 = m3(Td4[b3(t1)]) ^ m2(Td4[b2(t0)]) ^ m1(Td4[b1(t3)]) ^ m0(Td4[b0(t2)]) ^ rk[1]; + PUTU32(pt + 4, s1); + s2 = m3(Td4[b3(t2)]) ^ m2(Td4[b2(t1)]) ^ m1(Td4[b1(t0)]) ^ m0(Td4[b0(t3)]) ^ rk[2]; + PUTU32(pt + 8, s2); + s3 = m3(Td4[b3(t3)]) ^ m2(Td4[b2(t2)]) ^ m1(Td4[b1(t1)]) ^ m0(Td4[b0(t0)]) ^ rk[3]; + PUTU32(pt + 12, s3); +} + + +// public API + + +int aes_ecb_decrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { + + aes_internal_decrypt(ctx->dec_rk, ctx->Nr, in, out); + + return AES_BLOCK_SIZE; +} + + +// not used +int aes_ecb_encrypt (unsigned char *out, const unsigned char *in, aes_context_t *ctx) { + + aes_internal_encrypt(ctx->enc_rk, ctx->Nr, in, out); + + return AES_BLOCK_SIZE; +} + + +#define fix_xor(target, source) *(uint32_t*)&(target)[0] = *(uint32_t*)&(target)[0] ^ *(uint32_t*)&(source)[0]; *(uint32_t*)&(target)[4] = *(uint32_t*)&(target)[4] ^ *(uint32_t*)&(source)[4]; \ + *(uint32_t*)&(target)[8] = *(uint32_t*)&(target)[8] ^ *(uint32_t*)&(source)[8]; *(uint32_t*)&(target)[12] = *(uint32_t*)&(target)[12] ^ *(uint32_t*)&(source)[12]; + + +int aes_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + uint8_t tmp[AES_BLOCK_SIZE]; + size_t i; + size_t n; + + memcpy(tmp, iv, AES_BLOCK_SIZE); + + n = in_len / AES_BLOCK_SIZE; + for(i=0; i < n; i++) { + fix_xor(tmp, &in[i * AES_BLOCK_SIZE]); + aes_internal_encrypt(ctx->enc_rk, ctx->Nr, tmp, tmp); + memcpy(&out[i * AES_BLOCK_SIZE], tmp, AES_BLOCK_SIZE); + } + + return n * AES_BLOCK_SIZE; +} + + +int aes_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, aes_context_t *ctx) { + + uint8_t tmp[AES_BLOCK_SIZE]; + uint8_t old[AES_BLOCK_SIZE]; + size_t i; + size_t n; + + memcpy(tmp, iv, AES_BLOCK_SIZE); + + n = in_len / AES_BLOCK_SIZE; + for(i=0; i < n; i++) { + memcpy(old, &in[i * AES_BLOCK_SIZE], AES_BLOCK_SIZE); + aes_internal_decrypt(ctx->dec_rk, ctx->Nr, &in[i * AES_BLOCK_SIZE], &out[i * AES_BLOCK_SIZE]); + fix_xor(&out[i * AES_BLOCK_SIZE], tmp); + memcpy(tmp, old, AES_BLOCK_SIZE); + } + + return n * AES_BLOCK_SIZE; +} + + +int aes_init (const unsigned char *key, size_t key_size, aes_context_t **ctx) { + + // allocate context... + *ctx = (aes_context_t*) calloc(1, sizeof(aes_context_t)); + if(!(*ctx)) + return -1; + // ...and fill her up: + + // initialize data structures + + // check key size and make key size (given in bytes) dependant settings + switch(key_size) { + case AES128_KEY_BYTES: // 128 bit key size + break; + case AES192_KEY_BYTES: // 192 bit key size + break; + case AES256_KEY_BYTES: // 256 bit key size + break; + default: + traceEvent(TRACE_ERROR, "aes_init invalid key size %u\n", key_size); + return -1; + } + + // key materiel handling + (*ctx)->Nr = aes_internal_key_setup_enc((*ctx)->enc_rk/*[4*(Nr + 1)]*/, key, 8 * key_size); + aes_internal_key_setup_dec((*ctx)->dec_rk/*[4*(Nr + 1)]*/, key, 8 * key_size); + return 0; +} + + +#endif // openSSL 1.1, AES-NI, plain C ---------------------------------------------------------------------------- + + +int aes_deinit (aes_context_t *ctx) { + + if(ctx) free(ctx); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/auth.c b/bundles/n2n_ntop_v3/src/auth.c new file mode 100644 index 00000000..68b5694b --- /dev/null +++ b/bundles/n2n_ntop_v3/src/auth.c @@ -0,0 +1,179 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + + +#include "auth.h" + + +// mapping six binary bits to printable ascii character +static uint8_t b2a[64] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, /* 0 ... 9, A ... F */ + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, /* G ... V */ + 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* W ... Z, a ... l */ + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x2b, 0x2d }; /* m ... z, + , - */ + +// mapping ascii 0x30 ...0x7f back to 6 bit binary, invalids are mapped to 0xff +static uint8_t a2b[256] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0x3f, 0xff, 0xff, /* 0x20 ... 0x2f */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0x3e, 0xff, 0x3f, 0xff, /* 0x30 ... 0x3f */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* 0x40 ... 0x4f */ + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x50 ... 0x5f */ + 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* 0x60 ... 0x6f */ + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff }; /* 0x70 ... 0x7f */ + + +int bin_to_ascii (char *out, uint8_t *in, size_t in_len) { + + // in buffer contains binary data of length in_len + + // out buffer is already allocated and of size ceiling(in_len * 8 / 6) + 1 + // out buffer will be filled with a string including trailing 0x00 + + size_t bit_count = 0; + size_t out_count = 0; + uint8_t buf1, buf2; + + for(bit_count = 0; bit_count < 8 * in_len; bit_count += 6) { + buf1 = in[bit_count / 8]; + buf1 <<= bit_count % 8; + + buf2 = ((bit_count + 6) < (8 * in_len)) ? in[bit_count / 8 + 1] : 0; + buf2 >>= 8 - (bit_count % 8); + + buf1 |= buf2; + buf1 >>= 2; + + out[out_count++] = b2a[buf1]; + } + out[out_count] = 0; + + return 0; +} + + +int ascii_to_bin (uint8_t *out, char *in) { + + // in buffer contains 0x00-terminated string to be decoded + + // out buffer will contain decoded binary data + // out buffer is already allocated and of size floor(strlen(in) * 6 / 8) + + size_t in_count, out_count, bit_count; + uint16_t buf = 0; + + bit_count = 0; + out_count = 0; + for(in_count = 0; in_count < strlen(in); in_count++) { + buf <<= 6; + + int ch = in[in_count]; + if((ch > 0x20) && (ch < 0x80)) { + if(a2b[ch] != 0xFF) { + buf |= a2b[ch - 0x20]; + } else { + traceEvent(TRACE_NORMAL, "ascii_to_bin encountered the unknown character '%c'", in[in_count]); + } + } else { + traceEvent(TRACE_WARNING, "ascii_to_bin encountered a completely out-of-range character"); + } + bit_count += 6; + + if(bit_count / 8) { + bit_count -= 8; + out[out_count++] = ((uint8_t)(buf >> bit_count)); + } + + } + + return 0; +} + + +int generate_private_key (n2n_private_public_key_t key, char *in) { + + // hash the 0-terminated string input twice to generate private key + + pearson_hash_256(key, (uint8_t *)in, strlen(in)); + pearson_hash_256(key, key, sizeof(n2n_private_public_key_t)); + + return 0; +} + + +int generate_public_key (n2n_private_public_key_t pub, n2n_private_public_key_t prv) { + + // generator point '9' on curve + static uint8_t gen[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }; + + curve25519(pub, prv, gen); + + return 0; +} + + +int generate_shared_secret (n2n_private_public_key_t shared, n2n_private_public_key_t prv, n2n_private_public_key_t pub) { + + curve25519(shared, prv, pub); + pearson_hash_256(shared, shared, sizeof(n2n_private_public_key_t)); + + return 0; +} + + +int bind_private_key_to_username (n2n_private_public_key_t prv, char *username) { + + uint8_t tmp[32]; + + pearson_hash_256(tmp, (uint8_t *)username, strlen(username)); + memxor(prv, tmp, sizeof(n2n_private_public_key_t)); + + return 0; +} + + +// calculate SPECK ( plain = HASH³(time), key = HASH³(comm) ^ HASH³(fed) ) +int calculate_dynamic_key (uint8_t out_key[N2N_AUTH_CHALLENGE_SIZE], + uint32_t key_time, n2n_community_t comm, n2n_community_t fed) { + + uint8_t key[N2N_AUTH_CHALLENGE_SIZE]; + uint8_t tmp[N2N_AUTH_CHALLENGE_SIZE]; + speck_context_t *ctx; + + // we know that N2N_AUTH_CHALLENGE_SIZE == 16, i.e. 128 bit that can take the hash value + pearson_hash_128(key, comm, sizeof(n2n_community_t)); + pearson_hash_128(key, key, N2N_AUTH_CHALLENGE_SIZE); + pearson_hash_128(key, key, N2N_AUTH_CHALLENGE_SIZE); + + pearson_hash_128(tmp, fed, sizeof(n2n_community_t)); + pearson_hash_128(tmp, tmp, N2N_AUTH_CHALLENGE_SIZE); + pearson_hash_128(tmp, tmp, N2N_AUTH_CHALLENGE_SIZE); + + memxor(key, tmp, N2N_AUTH_CHALLENGE_SIZE); + + ctx = (speck_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)&ctx, key, 128); + + pearson_hash_128(tmp, (uint8_t*)&key_time, sizeof(key_time)); + pearson_hash_128(tmp, tmp, N2N_AUTH_CHALLENGE_SIZE); + pearson_hash_128(out_key, tmp, N2N_AUTH_CHALLENGE_SIZE); + + speck_128_encrypt(out_key, ctx); + + free(ctx); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/cc20.c b/bundles/n2n_ntop_v3/src/cc20.c new file mode 100644 index 00000000..3df65840 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/cc20.c @@ -0,0 +1,421 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "cc20.h" + + +#if defined (HAVE_OPENSSL_1_1) // openSSL 1.1 --------------------------------------------------------------------- + + +// get any erorr message out of openssl +// taken from https://en.wikibooks.org/wiki/OpenSSL/Error_handling +static char *openssl_err_as_string (void) { + + BIO *bio = BIO_new(BIO_s_mem()); + ERR_print_errors(bio); + char *buf = NULL; + size_t len = BIO_get_mem_data(bio, &buf); + char *ret = (char *)calloc(1, 1 + len); + + if(ret) + memcpy(ret, buf, len); + + BIO_free(bio); + + return ret; +} + + +// encryption == decryption +int cc20_crypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, cc20_context_t *ctx) { + + int evp_len; + int evp_ciphertext_len; + + if(1 == EVP_EncryptInit_ex(ctx->ctx, ctx->cipher, NULL, ctx->key, iv)) { + if(1 == EVP_CIPHER_CTX_set_padding(ctx->ctx, 0)) { + if(1 == EVP_EncryptUpdate(ctx->ctx, out, &evp_len, in, in_len)) { + evp_ciphertext_len = evp_len; + if(1 == EVP_EncryptFinal_ex(ctx->ctx, out + evp_len, &evp_len)) { + evp_ciphertext_len += evp_len; + if(evp_ciphertext_len != in_len) + traceEvent(TRACE_ERROR, "cc20_crypt openssl encryption: encrypted %u bytes where %u were expected", + evp_ciphertext_len, in_len); + } else + traceEvent(TRACE_ERROR, "cc20_crypt openssl final encryption: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "cc20_encrypt openssl encrpytion: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "cc20_encrypt openssl padding setup: %s", + openssl_err_as_string()); + } else + traceEvent(TRACE_ERROR, "cc20_encrypt openssl init: %s", + openssl_err_as_string()); + + EVP_CIPHER_CTX_reset(ctx->ctx); + + return 0; +} + + +#elif defined (__SSE2__) // SSE2 --------------------------------------------------------------------------------- + + +// taken (and heavily modified and enhanced) from +// https://github.com/Ginurx/chacha20-c (public domain) + + +#define SL _mm_slli_epi32 +#define SR _mm_srli_epi32 +#define XOR _mm_xor_si128 +#define AND _mm_and_si128 +#define ADD _mm_add_epi32 +#define ROL(X,r) (XOR(SL(X,r),SR(X,(32-r)))) + +#define ONE _mm_setr_epi32(1, 0, 0, 0) +#define TWO _mm_setr_epi32(2, 0, 0, 0) + +#if defined (__SSSE3__) // --- SSSE3 + +#define L8 _mm_set_epi32(0x0e0d0c0fL, 0x0a09080bL, 0x06050407L, 0x02010003L) +#define L16 _mm_set_epi32(0x0d0c0f0eL, 0x09080b0aL, 0x05040706L, 0x01000302L) +#define ROL8(X) ( _mm_shuffle_epi8(X, L8)) /* SSSE 3 */ +#define ROL16(X) ( _mm_shuffle_epi8(X, L16)) /* SSSE 3 */ + +#else // --- regular SSE2 ---------- + +#define ROL8(X) ROL(X,8) +#define ROL16(X) ROL(X,16) + +#endif // -------------------------- + + +#define CC20_PERMUTE_ROWS(A,B,C,D) \ + B = _mm_shuffle_epi32(B, _MM_SHUFFLE(0, 3, 2, 1)); \ + C = _mm_shuffle_epi32(C, _MM_SHUFFLE(1, 0, 3, 2)); \ + D = _mm_shuffle_epi32(D, _MM_SHUFFLE(2, 1, 0, 3)) + +#define CC20_PERMUTE_ROWS_INV(A,B,C,D) \ + B = _mm_shuffle_epi32(B, _MM_SHUFFLE(2, 1, 0, 3)); \ + C = _mm_shuffle_epi32(C, _MM_SHUFFLE(1, 0, 3, 2)); \ + D = _mm_shuffle_epi32(D, _MM_SHUFFLE(0, 3, 2, 1)) + +#define CC20_ODD_ROUND(A,B,C,D) \ + /* odd round */ \ + A = ADD(A, B); D = ROL16(XOR(D, A)); \ + C = ADD(C, D); B = ROL(XOR(B, C), 12); \ + A = ADD(A, B); D = ROL8(XOR(D, A)); \ + C = ADD(C, D); B = ROL(XOR(B, C), 7) + +#define CC20_EVEN_ROUND(A,B,C,D) \ + CC20_PERMUTE_ROWS (A, B, C, D); \ + CC20_ODD_ROUND (A, B, C, D); \ + CC20_PERMUTE_ROWS_INV(A, B, C, D) + +#define CC20_DOUBLE_ROUND(A,B,C,D) \ + CC20_ODD_ROUND (A, B, C, D); \ + CC20_EVEN_ROUND(A, B, C, D) + +#define STOREXOR(O,I,X) \ + _mm_storeu_si128((__m128i*)O, \ + _mm_xor_si128(_mm_loadu_si128((__m128i*)I), X)); \ + I += 16; O += 16 \ + + +int cc20_crypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, cc20_context_t *ctx) { + + __m128i a, b, c, d, k0, k1, k2, k3, k4, k5, k6, k7; + + uint8_t *keystream8 = (uint8_t*)ctx->keystream32; + + const uint8_t *magic_constant = (uint8_t*)"expand 32-byte k"; + + a = _mm_loadu_si128((__m128i*)magic_constant); + b = _mm_loadu_si128((__m128i*)(ctx->key)); + c = _mm_loadu_si128( (__m128i*)((ctx->key)+16)); + d = _mm_loadu_si128((__m128i*)iv); + + while(in_len >= 128) { + k0 = a; k1 = b; k2 = c; k3 = d; + k4 = a; k5 = b; k6 = c; k7 = ADD(d, ONE); + + // 10 double rounds -- two in parallel to make better use of all 8 SSE registers + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); CC20_DOUBLE_ROUND(k4, k5, k6, k7); + + k0 = ADD(k0, a); k1 = ADD(k1, b); k2 = ADD(k2, c); k3 = ADD(k3, d); + k4 = ADD(k4, a); k5 = ADD(k5, b); k6 = ADD(k6, c); k7 = ADD(k7, d); k7 = ADD(k7, ONE); + + STOREXOR(out, in, k0); STOREXOR(out, in, k1); STOREXOR(out, in, k2); STOREXOR(out, in, k3); + STOREXOR(out, in, k4); STOREXOR(out, in, k5); STOREXOR(out, in, k6); STOREXOR(out, in, k7); + + // increment counter, make sure it is and stays little endian in memory + d = ADD(d, TWO); + + in_len -= 128; + } + + if(in_len >= 64) { + k0 = a; k1 = b; k2 = c; k3 = d; + + // 10 double rounds + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + + k0 = ADD(k0, a); k1 = ADD(k1, b); k2 = ADD(k2, c); k3 = ADD(k3, d); + + STOREXOR(out, in, k0); STOREXOR(out, in, k1); STOREXOR(out, in, k2); STOREXOR(out, in, k3); + + // increment counter, make sure it is and stays little endian in memory + d = ADD(d, ONE); + + in_len -= 64; + } + + if(in_len) { + k0 = a; k1 = b; k2 = c; k3 = d; + + // 10 double rounds + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + CC20_DOUBLE_ROUND(k0, k1, k2, k3); + + k0 = ADD(k0, a); k1 = ADD(k1, b); k2 = ADD(k2, c); k3 = ADD(k3, d); + + _mm_storeu_si128((__m128i*)&(ctx->keystream32[ 0]), k0); + _mm_storeu_si128((__m128i*)&(ctx->keystream32[ 4]), k1); + _mm_storeu_si128((__m128i*)&(ctx->keystream32[ 8]), k2); + _mm_storeu_si128((__m128i*)&(ctx->keystream32[12]), k3); + + // keep in mind that out and in got increased inside the last loop + // and point to current position now + while(in_len > 0) { + in_len--; + out[in_len] = in[in_len] ^ keystream8[in_len]; + } + } + + return(0); +} + + +#else // plain C -------------------------------------------------------------------------------------------------- + + +// taken (and modified) from https://github.com/Ginurx/chacha20-c (public domain) + + +static void cc20_init_block(cc20_context_t *ctx, const uint8_t nonce[]) { + + const uint8_t *magic_constant = (uint8_t*)"expand 32-byte k"; + + memcpy(&(ctx->state[ 0]), magic_constant, 16); + memcpy(&(ctx->state[ 4]), ctx->key, CC20_KEY_BYTES); + memcpy(&(ctx->state[12]), nonce, CC20_IV_SIZE); +} + + +#define ROL32(x,r) (((x)<<(r))|((x)>>(32-(r)))) + +#define CC20_QUARTERROUND(x, a, b, c, d) \ + x[a] += x[b]; x[d] = ROL32(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROL32(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROL32(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROL32(x[b] ^ x[c], 7) + +#define CC20_DOUBLE_ROUND(s) \ + /* odd round */ \ + CC20_QUARTERROUND(s, 0, 4, 8, 12); \ + CC20_QUARTERROUND(s, 1, 5, 9, 13); \ + CC20_QUARTERROUND(s, 2, 6, 10, 14); \ + CC20_QUARTERROUND(s, 3, 7, 11, 15); \ + /* even round */ \ + CC20_QUARTERROUND(s, 0, 5, 10, 15); \ + CC20_QUARTERROUND(s, 1, 6, 11, 12); \ + CC20_QUARTERROUND(s, 2, 7, 8, 13); \ + CC20_QUARTERROUND(s, 3, 4, 9, 14) + + +static void cc20_block_next(cc20_context_t *ctx) { + + uint32_t *counter = ctx->state + 12; + + ctx->keystream32[ 0] = ctx->state[ 0]; + ctx->keystream32[ 1] = ctx->state[ 1]; + ctx->keystream32[ 2] = ctx->state[ 2]; + ctx->keystream32[ 3] = ctx->state[ 3]; + ctx->keystream32[ 4] = ctx->state[ 4]; + ctx->keystream32[ 5] = ctx->state[ 5]; + ctx->keystream32[ 6] = ctx->state[ 6]; + ctx->keystream32[ 7] = ctx->state[ 7]; + ctx->keystream32[ 8] = ctx->state[ 8]; + ctx->keystream32[ 9] = ctx->state[ 9]; + ctx->keystream32[10] = ctx->state[10]; + ctx->keystream32[11] = ctx->state[11]; + ctx->keystream32[12] = ctx->state[12]; + ctx->keystream32[13] = ctx->state[13]; + ctx->keystream32[14] = ctx->state[14]; + ctx->keystream32[15] = ctx->state[15]; + + // 10 double rounds + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + CC20_DOUBLE_ROUND(ctx->keystream32); + + ctx->keystream32[ 0] += ctx->state[ 0]; + ctx->keystream32[ 1] += ctx->state[ 1]; + ctx->keystream32[ 2] += ctx->state[ 2]; + ctx->keystream32[ 3] += ctx->state[ 3]; + ctx->keystream32[ 4] += ctx->state[ 4]; + ctx->keystream32[ 5] += ctx->state[ 5]; + ctx->keystream32[ 6] += ctx->state[ 6]; + ctx->keystream32[ 7] += ctx->state[ 7]; + ctx->keystream32[ 8] += ctx->state[ 8]; + ctx->keystream32[ 9] += ctx->state[ 9]; + ctx->keystream32[10] += ctx->state[10]; + ctx->keystream32[11] += ctx->state[11]; + ctx->keystream32[12] += ctx->state[12]; + ctx->keystream32[13] += ctx->state[13]; + ctx->keystream32[14] += ctx->state[14]; + ctx->keystream32[15] += ctx->state[15]; + + // increment counter, make sure it is and stays little endian in memory + *counter = htole32(le32toh(*counter)+1); +} + + +static void cc20_init_context(cc20_context_t *ctx, const uint8_t *nonce) { + + cc20_init_block(ctx, nonce); +} + + +int cc20_crypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, cc20_context_t *ctx) { + + uint8_t *keystream8 = (uint8_t*)ctx->keystream32; + uint32_t * in_p = (uint32_t*)in; + uint32_t * out_p = (uint32_t*)out; + size_t tmp_len = in_len; + + cc20_init_context(ctx, iv); + + while(in_len >= 64) { + cc20_block_next(ctx); + + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 0]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 1]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 2]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 3]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 4]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 5]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 6]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 7]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 8]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[ 9]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[10]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[11]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[12]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[13]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[14]; in_p++; out_p++; + *(uint32_t*)out_p = *(uint32_t*)in_p ^ ctx->keystream32[15]; in_p++; out_p++; + + in_len -= 64; + } + + if(in_len > 0) { + cc20_block_next(ctx); + + tmp_len -= in_len; + while(in_len > 0) { + out[tmp_len] = in[tmp_len] ^ keystream8[tmp_len%64]; + tmp_len++; + in_len--; + } + } + + return(0); +} + + +#endif // openSSL 1.1, plain C ------------------------------------------------------------------------------------ + + +int cc20_init (const unsigned char *key, cc20_context_t **ctx) { + + // allocate context... + *ctx = (cc20_context_t*)calloc(1, sizeof(cc20_context_t)); + if(!(*ctx)) + return -1; +#if defined (HAVE_OPENSSL_1_1) + if(!((*ctx)->ctx = EVP_CIPHER_CTX_new())) { + traceEvent(TRACE_ERROR, "cc20_init openssl's evp_* encryption context creation failed: %s", + openssl_err_as_string()); + return -1; + } + + (*ctx)->cipher = EVP_chacha20(); +#endif + memcpy((*ctx)->key, key, CC20_KEY_BYTES); + + return 0; +} + + +int cc20_deinit (cc20_context_t *ctx) { + +#if defined (HAVE_OPENSSL_1_1) + if(ctx->ctx) EVP_CIPHER_CTX_free(ctx->ctx); +#endif + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/curve25519.c b/bundles/n2n_ntop_v3/src/curve25519.c new file mode 100644 index 00000000..881cf734 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/curve25519.c @@ -0,0 +1,356 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +/** + * version 20081011 + * Matthew Dempsky + * Public domain. + * Derived from public domain code by D. J. Bernstein. + * 20140216 tweak: Mask top bit of point input. + * + */ + + +static void add (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { + + unsigned int j; + unsigned int u; + + u = 0; + for(j = 0; j < 31; ++j) { + u += a[j] + b[j]; + out[j] = u & 255; + u >>= 8; + } + u += a[31] + b[31]; + out[31] = u; +} + + +static void sub (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { + + unsigned int j; + unsigned int u; + + u = 218; + for(j = 0; j < 31; ++j) { + u += a[j] + 65280 - b[j]; + out[j] = u & 255; + u >>= 8; + } + u += a[31] - b[31]; + out[31] = u; +} + + +static void squeeze (unsigned int a[32]) { + + unsigned int j; + unsigned int u; + + u = 0; + for(j = 0; j < 31; ++j) { + u += a[j]; + a[j] = u & 255; + u >>= 8; + } + u += a[31]; + a[31] = u & 127; + u = 19 * (u >> 7); + for(j = 0; j < 31; ++j) { + u += a[j]; + a[j] = u & 255; + u >>= 8; + } + u += a[31]; + a[31] = u; +} + + +static const unsigned int minusp[32] = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + + +static void freeze (unsigned int a[32]) { + + unsigned int aorig[32]; + unsigned int j; + unsigned int negative; + + for(j = 0; j < 32; ++j) + aorig[j] = a[j]; + add(a, a, minusp); + negative = -((a[31] >> 7) & 1); + for(j = 0; j < 32; ++j) + a[j] ^= negative & (aorig[j] ^ a[j]); +} + + +static void mult (unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) { + + unsigned int i; + unsigned int j; + unsigned int u; + + for(i = 0; i < 32; ++i) { + u = 0; + for(j = 0; j <= i; ++j) + u += a[j] * b[i - j]; + for(j = i + 1; j < 32; ++j) + u += 38 * a[j] * b[i + 32 - j]; + out[i] = u; + } + squeeze(out); +} + + +static void mult121665 (unsigned int out[32], const unsigned int a[32]) { + + unsigned int j; + unsigned int u; + + u = 0; + for(j = 0; j < 31; ++j) { + u += 121665 * a[j]; + out[j] = u & 255; + u >>= 8; + } + u += 121665 * a[31]; + out[31] = u & 127; + u = 19 * (u >> 7); + for(j = 0; j < 31; ++j) { + u += out[j]; + out[j] = u & 255; + u >>= 8; + } + u += out[j]; + out[j] = u; +} + + +static void square (unsigned int out[32], const unsigned int a[32]) { + + unsigned int i; + unsigned int j; + unsigned int u; + + for(i = 0; i < 32; ++i) { + u = 0; + for(j = 0; j < i - j; ++j) + u += a[j] * a[i - j]; + for(j = i + 1; j < i + 32 - j; ++j) + u += 38 * a[j] * a[i + 32 - j]; + u *= 2; + if((i & 1) == 0) { + u += a[i / 2] * a[i / 2]; + u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; + } + out[i] = u; + } + squeeze(out); +} + + +static void select (unsigned int p[64], unsigned int q[64], const unsigned int r[64], + const unsigned int s[64], unsigned int b) { + + unsigned int j; + unsigned int t; + unsigned int bminus1; + + bminus1 = b - 1; + for(j = 0; j < 64; ++j) { + t = bminus1 & (r[j] ^ s[j]); + p[j] = s[j] ^ t; + q[j] = r[j] ^ t; + } +} + + +static void mainloop (unsigned int work[64], const unsigned char e[32]) { + + unsigned int xzm1[64]; + unsigned int xzm[64]; + unsigned int xzmb[64]; + unsigned int xzm1b[64]; + unsigned int xznb[64]; + unsigned int xzn1b[64]; + unsigned int a0[64]; + unsigned int a1[64]; + unsigned int b0[64]; + unsigned int b1[64]; + unsigned int c1[64]; + unsigned int r[32]; + unsigned int s[32]; + unsigned int t[32]; + unsigned int u[32]; + unsigned int j; + unsigned int b; + int pos; + + for(j = 0; j < 32; ++j) + xzm1[j] = work[j]; + xzm1[32] = 1; + for(j = 33; j < 64; ++j) + xzm1[j] = 0; + + xzm[0] = 1; + for(j = 1; j < 64; ++j) + xzm[j] = 0; + + for(pos = 254; pos >= 0; --pos) { + b = e[pos / 8] >> (pos & 7); + b &= 1; + select(xzmb, xzm1b, xzm, xzm1, b); + add(a0, xzmb, xzmb + 32); + sub(a0 + 32, xzmb, xzmb + 32); + add (a1, xzm1b, xzm1b + 32); + sub(a1 + 32, xzm1b, xzm1b + 32); + square(b0, a0); + square(b0 + 32, a0 + 32); + mult(b1, a1, a0 + 32); + mult(b1 + 32, a1 + 32, a0); + add(c1, b1, b1 + 32); + sub(c1 + 32, b1, b1 + 32); + square(r, c1 + 32); + sub(s, b0, b0 + 32); + mult121665 (t, s); + add(u, t, b0); + mult(xznb, b0, b0 + 32); + mult(xznb + 32, s, u); + square(xzn1b, c1); + mult(xzn1b + 32, r, work); + select(xzm, xzm1, xznb, xzn1b, b); + } + + for(j = 0; j < 64; ++j) + work[j] = xzm[j]; +} + + +static void recip (unsigned int out[32], const unsigned int z[32]) { + + unsigned int z2[32]; + unsigned int z9[32]; + unsigned int z11[32]; + unsigned int z2_5_0[32]; + unsigned int z2_10_0[32]; + unsigned int z2_20_0[32]; + unsigned int z2_50_0[32]; + unsigned int z2_100_0[32]; + unsigned int t0[32]; + unsigned int t1[32]; + int i; + + /* 2 */ square(z2, z); + /* 4 */ square(t1, z2); + /* 8 */ square(t0, t1); + /* 9 */ mult(z9, t0, z); + /* 11 */ mult(z11, z9, z2); + /* 22 */ square(t0, z11); + /* 2^5 - 2^0 = 31 */ mult(z2_5_0, t0, z9); + + /* 2^6 - 2^1 */ square(t0, z2_5_0); + /* 2^7 - 2^2 */ square(t1, t0); + /* 2^8 - 2^3 */ square(t0, t1); + /* 2^9 - 2^4 */ square(t1, t0); + /* 2^10 - 2^5 */ square(t0, t1); + /* 2^10 - 2^0 */ mult(z2_10_0, t0, z2_5_0); + + /* 2^11 - 2^1 */ square(t0, z2_10_0); + /* 2^12 - 2^2 */ square(t1, t0); + /* 2^20 - 2^10 */ for(i = 2; i < 10; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^20 - 2^0 */ mult(z2_20_0, t1, z2_10_0); + + /* 2^21 - 2^1 */ square(t0, z2_20_0); + /* 2^22 - 2^2 */ square(t1, t0); + /* 2^40 - 2^20 */ for(i = 2; i < 20; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^40 - 2^0 */ mult(t0, t1, z2_20_0); + + /* 2^41 - 2^1 */ square(t1, t0); + /* 2^42 - 2^2 */ square(t0, t1); + /* 2^50 - 2^10 */ for(i = 2; i < 10; i += 2) { + square(t1, t0); + square(t0, t1); + } + /* 2^50 - 2^0 */ mult(z2_50_0, t0, z2_10_0); + + /* 2^51 - 2^1 */ square(t0, z2_50_0); + /* 2^52 - 2^2 */ square(t1, t0); + /* 2^100 - 2^50 */ for(i = 2; i < 50; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^100 - 2^0 */ mult(z2_100_0, t1, z2_50_0); + + /* 2^101 - 2^1 */ square(t1, z2_100_0); + /* 2^102 - 2^2 */ square(t0, t1); + /* 2^200 - 2^100 */ for(i = 2; i < 100; i += 2) { + square(t1, t0); + square(t0, t1); + } + /* 2^200 - 2^0 */ mult(t1, t0, z2_100_0); + + /* 2^201 - 2^1 */ square(t0, t1); + /* 2^202 - 2^2 */ square(t1, t0); + /* 2^250 - 2^50 */ for(i = 2; i < 50; i += 2) { + square(t0, t1); + square(t1, t0); + } + /* 2^250 - 2^0 */ mult(t0, t1, z2_50_0); + + /* 2^251 - 2^1 */ square(t1, t0); + /* 2^252 - 2^2 */ square(t0, t1); + /* 2^253 - 2^3 */ square(t1, t0); + /* 2^254 - 2^4 */ square(t0, t1); + /* 2^255 - 2^5 */ square(t1, t0); + /* 2^255 - 21 */ mult(out, t1, z11); +} + + +void curve25519 (unsigned char *q, const unsigned char *n, const unsigned char *p) { + + unsigned int work[96]; + unsigned char e[32]; + unsigned int i; + + for (i = 0; i < 32; ++i) + e[i] = n[i]; + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + for (i = 0; i < 32; ++i) + work[i] = p[i]; + work[31] &= 127; + + mainloop(work, e); + recip(work + 32, work + 32); + mult(work + 64, work, work + 32); + freeze(work + 64); + + for(i = 0; i < 32; ++i) + q[i] = work[64 + i]; +} diff --git a/bundles/n2n_ntop_v3/src/edge.c b/bundles/n2n_ntop_v3/src/edge.c new file mode 100644 index 00000000..6ccdd28c --- /dev/null +++ b/bundles/n2n_ntop_v3/src/edge.c @@ -0,0 +1,1366 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +/* *************************************************** */ + +/** maximum length of command line arguments */ +#define MAX_CMDLINE_BUFFER_LENGTH 4096 + +/** maximum length of a line in the configuration file */ +#define MAX_CONFFILE_LINE_LENGTH 1024 + +/* ***************************************************** */ + +#ifdef HAVE_LIBCAP + +#include +#include +#include "network_traffic_filter.h" + +static cap_value_t cap_values[] = { + //CAP_NET_RAW, /* Use RAW and PACKET sockets */ + CAP_NET_ADMIN /* Needed to performs routes cleanup at exit */ +}; + +int num_cap = sizeof(cap_values)/sizeof(cap_value_t); +#endif + +// forward declaration for use in main() +void send_register_super (n2n_edge_t *eee); +void send_query_peer (n2n_edge_t *eee, const n2n_mac_t dst_mac); +int supernode_connect (n2n_edge_t *eee); +int supernode_disconnect (n2n_edge_t *eee); +int fetch_and_eventually_process_data (n2n_edge_t *eee, SOCKET sock, + uint8_t *pktbuf, uint16_t *expected, uint16_t *position, + time_t now); +int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now); +int edge_init_routes (n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); + +/* ***************************************************** */ + +/** Find the address and IP mode for the tuntap device. + * + * s is of the form: + * + * ["static"|"dhcp",":"] (|) [/] + * + * for example static:192.168.8.5/24 + * + * Fill the parts of the string into the fileds, ip_mode only if + * present. All strings are NULL terminated. + * + * return 0 on success and -1 on error + */ +static int scan_address (char * ip_addr, size_t addr_size, + char * netmask, size_t netmask_size, + char * ip_mode, size_t mode_size, + char * s) { + + int retval = -1; + char * start; + char * end; + int bitlen = N2N_EDGE_DEFAULT_CIDR_NM; + + if((NULL == s) || (NULL == ip_addr) || (NULL == netmask)) { + return -1; + } + + memset(ip_addr, 0, addr_size); + memset(netmask, 0, netmask_size); + + start = s; + end = strpbrk(s, ":"); + + if(end) { + // colon is present + if(ip_mode) { + memset(ip_mode, 0, mode_size); + strncpy(ip_mode, start, (size_t)MIN(end - start, mode_size - 1)); + } + start = end + 1; + } else { + // colon is not present + } + // start now points to first address character + retval = 0; // we have got an address + + end = strpbrk(start, "/"); + + if(!end) + // no slash present -- default end + end = s + strlen(s); + + strncpy(ip_addr, start, (size_t)MIN(end - start, addr_size - 1)); // ensure NULL term + + if(end) { + // slash is present + + // now, handle the sub-network address + sscanf(end + 1, "%u", &bitlen); + bitlen = htobe32(bitlen2mask(bitlen)); + inet_ntop(AF_INET, &bitlen, netmask, netmask_size); + } + + return retval; +} + +/* *************************************************** */ + +static void help (int level) { + + if(level == 0) return; /* no help required */ + + printf("\n"); + print_n2n_version(); + + if(level == 1) /* short help */ { + + printf(" basic usage: edge (see edge.conf)\n" + "\n" + " or edge " + " -c " + "\n " + " -l : " + "\n " + "[-a ] " + "\n " +#if defined(N2N_CAN_NAME_IFACE) + "[-d ] " + "\n " +#endif + "[-k ] " + "\n" + "\n -h shows a quick reference including all available options" + "\n --help gives a detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + + } else if(level == 2) /* quick reference */ { + + printf(" general usage: edge (see edge.conf)\n" + "\n" + " or edge " + " -c " + " -l " + "\n " + "[-p [:]] " + "\n " + +#ifdef __linux__ + "[-T ] " +#endif +#ifndef __APPLE__ + "[-D] " +#endif + "\n options for under- " + "[-i ] " + "[-L ] " + "\n lying connection " + "[-k ] " + "[-A] " + "[-H] " + "[-z] " + "\n " + "[-e ] [-S]" + "\n " + "[--select-rtt]" + "\n\n tap device and " + "[-a [static:|dhcp:][/]] " + "\n overlay network " + "[-m ] " +#if defined(N2N_CAN_NAME_IFACE) + "[-d ] " +#endif + "\n configuration " + "[-M ] " + "[-r] " + "[-E] " + "[-I ] " + "\n " + "[-J ] " + "[-P ] " + "[-R ] " +#ifdef WIN32 + "\n " + "[-x ] " +#endif + "\n\n local options " +#ifndef WIN32 + "[-f] " +#endif + "[-t ] " + "[--management-password ] " + "\n " + "[-v] " + "[-n ] " +#ifndef WIN32 + "\n " + "[-u ] " + "[-g ] " +#endif + "\n\n environment " + "N2N_KEY instead of [-k ]" + "\n variables " + "N2N_COMMUNITY instead of -c " + "\n " + "N2N_PASSWORD instead of [-J ]" + + "\n " + + "\n meaning of the " +#ifndef __APPLE__ + "[-D] enable PMTU discovery" +#endif + "\n flag options [-H] enable header encryption" + "\n [-r] enable packet forwarding through n2n community" + "\n [-E] accept multicast MAC addresses" + "\n [--select-rtt] select supernode by round trip time" + "\n [--select-mac] select supernode by MAC address" +#ifndef WIN32 + "\n [-f] do not fork but run in foreground" +#endif + "\n [-v] make more verbose, repeat as required" + "\n " + + "\n -h shows this quick reference including all available options" + "\n --help gives a detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + + } else /* long help */ { + + printf(" general usage: edge (see edge.conf)\n" + "\n" + " or edge -c -l \n" + " [further optional command line parameters]\n\n" + ); + printf (" OPTIONS FOR THE UNDERLYING NETWORK CONNECTION\n"); + printf (" ---------------------------------------------\n\n"); + printf(" -c | n2n community name the edge belongs to\n"); + printf(" -l | supernode ip address or name, and port\n"); + printf(" -p [:] | fixed local UDP port and optionally bind to the\n" + " | sepcified local IP address only (any by default)\n"); +#ifdef __linux__ + printf(" -T | TOS for packets, e.g. 0x48 for SSH like priority\n"); +#endif +#ifndef __APPLE__ + printf(" -D | enable PMTU discovery, it can reduce fragmentation but\n" + " | causes connections to stall if not properly supported\n"); +#endif + printf(" -e | advertises the provided local IP address as preferred,\n" + " | useful if multicast peer detection is not available,\n" + " | '-e auto' tries IP address auto-detection\n"); + printf(" -S1 ... -S2 | do not connect p2p, always use the supernode,\n" + " | -S1 = via UDP" + +#ifdef N2N_HAVE_TCP + ", -S2 = via TCP" +#endif +"\n"); + printf(" -i | registration interval, for NAT hole punching (default\n" + " | %u seconds)\n", REGISTER_SUPER_INTERVAL_DFL); + printf(" -L | TTL for registration packet for NAT hole punching through\n" + " | supernode (default 0 for not set)\n"); + printf(" -k | encryption key (ASCII) - also N2N_KEY=\n"); + printf(" -A1 | disable payload encryption, do not use with key, defaults\n" + " | to AES then\n"); + printf(" -A2 ... -A5 | choose a cipher for payload encryption, requires a key,\n" + " | -A2 = Twofish, -A3 = AES (default if key provided),\n" + " | -A4 = ChaCha20, -A5 = Speck-CTR\n"); + printf(" -H | use header encryption, supernode needs fixed community\n"); + printf(" -z1 ... -z2 | compress outgoing data packets, -z1 = lzo1x,\n" + " | " +#ifdef N2N_HAVE_ZSTD + "-z2 = zstd, " +#endif + "disabled by default\n"); + printf("--select-rtt | supernode selection based on round trip time\n" + "--select-mac | supernode selection based on MAC address (default:\n" + " | by load)\n"); + + printf ("\n"); + printf (" TAP DEVICE AND OVERLAY NETWORK CONFIGURATION\n"); + printf (" --------------------------------------------\n\n"); + printf(" -a [mode][/n] | interface address and optional CIDR subnet, default '/24',\n" + " | mode = [static|dhcp]:, for DHCP use '-r -a dhcp:0.0.0.0',\n" + " | edge draws IP address from supernode if no '-a ...' given\n"); + printf(" -m | fixed MAC address for the TAP interface, e.g.\n" + " | '-m 10:20:30:40:50:60', random otherwise\n"); +#if defined(N2N_CAN_NAME_IFACE) + printf(" -d | TAP device name\n"); +#endif + printf(" -M | specify n2n MTU of TAP interface, default %d\n", DEFAULT_MTU); + printf(" -r | enable packet forwarding through n2n community\n"); + printf(" -E | accept multicast MAC addresses, drop by default\n"); + printf(" -I | annotate the edge's description used for easier\n" + " | identification in management port output or username\n"); + printf(" -J | password for user-password edge authentication\n"); + printf(" -P | federation public key for user-password authentication\n"); + printf(" -R | drop or accept packets by rules, can be set multiple times\n"); + printf(" | rule format: 'src_ip/n:[s_port,e_port],...\n" + " | |on same| ...dst_ip/n:[s_port,e_port],...\n" + " | | line | ...TCP+/-,UDP+/-,ICMP+/-'\n"); +#ifdef WIN32 + printf(" -x | set TAP interface metric, defaults to 0 (auto),\n" + " | e.g. set to 1 for better multiplayer game detection\n"); +#endif + printf ("\n"); + printf (" LOCAL OPTIONS\n"); + printf (" -------------\n\n"); +#ifndef WIN32 + printf(" -f | do not fork and run as a daemon, rather run in foreground\n"); +#endif + printf(" -t | management UDP port, for multiple edges on a machine,\n" + " | defaults to %u\n", N2N_EDGE_MGMT_PORT); + printf(" --management_... | management port password, defaults to '%s'\n" + " ...password | \n", N2N_MGMT_PASSWORD); + printf(" -v | make more verbose, repeat as required\n"); + printf(" -n | route an IPv4 network via the gateway, use 0.0.0.0/0 for\n" + " | the default gateway, can be set multiple times\n"); +#ifndef WIN32 + printf(" -u | numeric user ID to use when privileges are dropped\n"); + printf(" -g | numeric group ID to use when privileges are dropped\n"); +#endif + printf ("\n"); + printf (" ENVIRONMENT VARIABLES\n"); + printf (" ---------------------\n\n"); + printf(" N2N_KEY | encryption key (ASCII), not with '-k ...'\n"); + printf(" N2N_COMMUNITY | community name (ASCII), overwritten by '-c ...'\n"); + printf(" N2N_PASSWORD | password (ASCII) for user-password authentication,\n" + " | overwritten by '-J ...'\n"); +#ifdef WIN32 + printf ("\n"); + printf (" AVAILABLE TAP ADAPTERS\n"); + printf (" ----------------------\n\n"); + win_print_available_adapters(); +#endif + printf ("\n" + "\n -h shows a quick reference including all available options" + "\n --help gives this detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + } + + exit(0); +} + +/* *************************************************** */ + +static void setPayloadCompression (n2n_edge_conf_t *conf, int compression) { + + /* even though 'compression' and 'conf->compression' share the same encoding scheme, + * a switch-statement under conditional compilation is used to sort out the + * unsupported optarguments */ + switch (compression) { + case 1: { + conf->compression = N2N_COMPRESSION_ID_LZO; + break; + } +#ifdef N2N_HAVE_ZSTD + case 2: { + conf->compression = N2N_COMPRESSION_ID_ZSTD; + break; + } +#endif + default: { + conf->compression = N2N_COMPRESSION_ID_NONE; + // internal comrpession scheme numbering differs from cli counting by one, hence plus one + // (internal: 0 == invalid, 1 == none, 2 == lzo, 3 == zstd) + traceEvent(TRACE_NORMAL, "the %s compression given by -z_ option is not supported in this version", compression_str(compression + 1)); + exit(1); // to make the user aware + } + } +} + +/* *************************************************** */ + +static void setPayloadEncryption (n2n_edge_conf_t *conf, int cipher) { + + /* even though 'cipher' and 'conf->transop_id' share the same encoding scheme, + * a switch-statement under conditional compilation is used to sort out the + * unsupported ciphers */ + switch (cipher) { + case 1: { + conf->transop_id = N2N_TRANSFORM_ID_NULL; + break; + } + + case 2: { + conf->transop_id = N2N_TRANSFORM_ID_TWOFISH; + break; + } + + case 3: { + conf->transop_id = N2N_TRANSFORM_ID_AES; + break; + } + + case 4: { + conf->transop_id = N2N_TRANSFORM_ID_CHACHA20; + break; + } + + case 5: { + conf->transop_id = N2N_TRANSFORM_ID_SPECK; + break; + } + + default: { + conf->transop_id = N2N_TRANSFORM_ID_INVAL; + traceEvent(TRACE_NORMAL, "the %s cipher given by -A_ option is not supported in this version", transop_str(cipher)); + exit(1); + } + } +} + +/* *************************************************** */ + +static int setOption (int optkey, char *optargument, n2n_tuntap_priv_config_t *ec, n2n_edge_conf_t *conf) { + + /* traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, optargument ? optargument : ""); */ + + switch(optkey) { + case 'a': /* IP address and mode of TUNTAP interface */ { + scan_address(ec->ip_addr, N2N_NETMASK_STR_SIZE, + ec->netmask, N2N_NETMASK_STR_SIZE, + ec->ip_mode, N2N_IF_MODE_SIZE, + optargument); + break; + } + + case 'c': /* community as a string */ { + strncpy((char *)conf->community_name, optargument, N2N_COMMUNITY_SIZE); + conf->community_name[N2N_COMMUNITY_SIZE - 1] = '\0'; + break; + } + + case 'E': /* multicast ethernet addresses accepted. */ { + conf->drop_multicast = 0; + traceEvent(TRACE_INFO, "enabling ethernet multicast traffic"); + break; + } + +#ifndef WIN32 + case 'u': /* unprivileged uid */ { + ec->userid = atoi(optargument); + break; + } + + case 'g': /* unprivileged uid */ { + ec->groupid = atoi(optargument); + break; + } +#endif + +#ifndef WIN32 + case 'f' : /* do not fork as daemon */ { + ec->daemon = 0; + break; + } +#endif /* #ifndef WIN32 */ + + case 'm' : /* TUNTAP MAC address */ { + strncpy(ec->device_mac, optargument, N2N_MACNAMSIZ); + ec->device_mac[N2N_MACNAMSIZ - 1] = '\0'; + break; + } + + case 'M' : /* TUNTAP MTU */ { + ec->mtu = atoi(optargument); + break; + } + +#ifndef __APPLE__ + case 'D' : /* enable PMTU discovery */ { + conf->disable_pmtu_discovery = 0; + break; + } +#endif + + case 'k': /* encrypt key */ { + if(conf->encrypt_key) free(conf->encrypt_key); + conf->encrypt_key = strdup(optargument); + traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", conf->encrypt_key); + break; + } + + case 'r': /* enable packet routing across n2n endpoints */ { + conf->allow_routing = 1; + break; + } + + case 'A': { + int cipher; + + if(optargument) { + cipher = atoi(optargument); + } else { + traceEvent(TRACE_WARNING, "the use of the solitary -A switch is deprecated and will not be supported in future versions, " + "please use -A3 instead to choose AES cipher for payload encryption"); + + cipher = N2N_TRANSFORM_ID_AES; // default, if '-A' only + } + + setPayloadEncryption(conf, cipher); + break; + } + + case 'H': /* indicate header encryption */ { + /* we cannot be sure if this gets parsed before the community name is set. + * so, only an indicator is set, action is taken later*/ + conf->header_encryption = HEADER_ENCRYPTION_ENABLED; + break; + } + + case 'z': { + int compression; + + if(optargument) { + compression = atoi(optargument); + } else { + traceEvent(TRACE_WARNING, "the use of the solitary -z switch is deprecated and will not be supported in future versions, " + "please use -z1 instead to choose LZO1X algorithm for payload compression"); + + compression = 1; // default, if '-z' only, equals -z1 + } + + setPayloadCompression(conf, compression); + break; + } + + case 'l': /* supernode-list */ { + if(optargument) { + if(edge_conf_add_supernode(conf, optargument) != 0) { + traceEvent(TRACE_WARNING, "failed to add supernode '%s'", optargument); + } + } + break; + } + + case 'i': /* supernode registration interval */ + conf->register_interval = atoi(optargument); + break; + + case 'L': /* supernode registration interval */ + conf->register_ttl = atoi(optarg); + break; + +#if defined(N2N_CAN_NAME_IFACE) + case 'd': /* TUNTAP name */ { + strncpy(ec->tuntap_dev_name, optargument, N2N_IFNAMSIZ); + ec->tuntap_dev_name[N2N_IFNAMSIZ - 1] = '\0'; + break; + } +#endif + case 'I': /* Device Description (hint) or username */ { + strncpy((char *)conf->dev_desc, optargument, N2N_DESC_SIZE); + conf->dev_desc[N2N_DESC_SIZE - 1] = '\0'; + break; + } + + case 'J': /* password for user-password authentication */ { + if(!conf->shared_secret) /* we could already have it from environment variable, see edge_init_conf_defaults() */ + conf->shared_secret = calloc(1, sizeof(n2n_private_public_key_t)); + if(conf->shared_secret) + generate_private_key(*(conf->shared_secret), optargument); + + // the hash of the username (-I) gets xored into this key later, + // we can't be sure to already have it at this point + // also, the complete shared secret will be calculated then as we + // might still be missing the federation public key as well + break; + } + + case 'P': /* federation public key for user-password authentication */ { + if(strlen(optargument) < ((N2N_PRIVATE_PUBLIC_KEY_SIZE * 8 + 5)/ 6 + 1)) { + conf->federation_public_key = calloc(1, sizeof(n2n_private_public_key_t)); + if(conf->federation_public_key) { + ascii_to_bin(*(conf->federation_public_key), optargument); + } + } else { + traceEvent(TRACE_WARNING, "public key too long"); + return 2; + } + break; + } + + case 'p': { + char* colon = strpbrk(optargument, ":"); + if(colon) { /*ip address:port */ + *colon = 0; + conf->bind_address = ntohl(inet_addr(optargument)); + conf->local_port = atoi(++colon); + + if(conf->bind_address == INADDR_NONE) { + traceEvent(TRACE_WARNING, "bad address to bind to, binding to any IP address"); + conf->bind_address = INADDR_ANY; + } + if(conf->local_port == 0) { + traceEvent(TRACE_WARNING, "bad local port format, using OS assigned port"); + } + } else { /* ip address or port only */ + char* dot = strpbrk(optargument, "."); + if(dot) { /* ip address only */ + conf->bind_address = ntohl(inet_addr(optargument)); + if(conf->bind_address == INADDR_NONE) { + traceEvent(TRACE_WARNING, "bad address to bind to, binding to any IP address"); + conf->bind_address = INADDR_ANY; + } + } else { /* port only */ + conf->local_port = atoi(optargument); + if(conf->local_port == 0) { + traceEvent(TRACE_WARNING, "bad local port format, using OS assigned port"); + } + } + } + break; + } + + case 'e': { + in_addr_t address_tmp; + + if(optargument) { + + if(!strcmp(optargument, "auto")) { + address_tmp = INADDR_ANY; + conf->preferred_sock_auto = 1; + } else { + address_tmp = inet_addr(optargument); + } + + memcpy(&(conf->preferred_sock.addr.v4), &(address_tmp), IPV4_SIZE); + + if(address_tmp == INADDR_NONE) { + traceEvent(TRACE_WARNING, "bad address for preferred local socket, skipping"); + conf->preferred_sock.family = AF_INVALID; + break; + } else { + conf->preferred_sock.family = AF_INET; + // port is set after parsing all cli parameters during supernode_connect() + } + + } + + break; + } + + case 't': { + conf->mgmt_port = atoi(optargument); + break; + } +#ifdef __linux__ + case 'T': { + if((optargument[0] == '0') && (optargument[1] == 'x')) + conf->tos = strtol(&optargument[2], NULL, 16); + else + conf->tos = atoi(optargument); + + break; + } +#endif + case 'n': { + char cidr_net[64], gateway[64]; + n2n_route_t route; + + if(sscanf(optargument, "%63[^/]/%hhd:%63s", cidr_net, &route.net_bitlen, gateway) != 3) { + traceEvent(TRACE_WARNING, "bad cidr/gateway format '%d'", optargument); + return 2; + } + + route.net_addr = inet_addr(cidr_net); + route.gateway = inet_addr(gateway); + + if((route.net_bitlen < 0) || (route.net_bitlen > 32)) { + traceEvent(TRACE_WARNING, "bad prefix '%d' in '%s'", route.net_bitlen, optargument); + return 2; + } + + if(route.net_addr == INADDR_NONE) { + traceEvent(TRACE_WARNING, "bad network '%s' in '%s'", cidr_net, optargument); + return 2; + } + + if(route.gateway == INADDR_NONE) { + traceEvent(TRACE_WARNING, "bad gateway '%s' in '%s'", gateway, optargument); + return 2; + } + + traceEvent(TRACE_NORMAL, "adding %s/%d via %s", cidr_net, route.net_bitlen, gateway); + + conf->routes = realloc(conf->routes, sizeof(struct n2n_route) * (conf->num_routes + 1)); + conf->routes[conf->num_routes] = route; + conf->num_routes++; + + break; + } + + case 'S': { + int solitude; + if(optargument) { + solitude = atoi(optargument); + } else { + traceEvent(TRACE_WARNING, "the use of the solitary -S switch is deprecated and will not be supported in future versions, " + "please use -S1 instead to choose supernode-only connection via UDP"); + + solitude = 1; + } + + // set the level + if(solitude >= 1) + conf->allow_p2p = 0; +#ifdef N2N_HAVE_TCP + if(solitude == 2) + conf->connect_tcp = 1; +#endif + break; + } + + case '[': /* round-trip-time-based supernode selection strategy */ { + // overwrites the default load-based strategy + conf->sn_selection_strategy = SN_SELECTION_STRATEGY_RTT; + + break; + } + + case ']': /* mac-address-based supernode selection strategy */ { + // overwrites the default load-based strategy + conf->sn_selection_strategy = SN_SELECTION_STRATEGY_MAC; + + break; + } + + case '{': /* password for management port */ { + conf->mgmt_password_hash = pearson_hash_64((uint8_t*)optargument, strlen(optargument)); + + break; + } + + case 'h': /* quick reference */ { + return 2; + } + + case '@': /* long help */ { + return 3; + } + + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + + case 'R': /* network traffic filter */ { + filter_rule_t *new_rule = malloc(sizeof(filter_rule_t)); + memset(new_rule, 0, sizeof(filter_rule_t)); + + if(process_traffic_filter_rule_str(optargument, new_rule)) { + HASH_ADD(hh, conf->network_traffic_filter_rules, key, sizeof(filter_rule_key_t), new_rule); + } else { + free(new_rule); + traceEvent(TRACE_WARNING, "invalid filter rule: %s", optargument); + return 2; + } + break; + } +#ifdef WIN32 + case 'x': { + conf->metric = atoi(optargument); + ec->metric = atoi(optargument); + break; + } +#endif + default: { + traceEvent(TRACE_WARNING, "unknown option -%c", (char)optkey); + return 2; + } + } + + return 0; +} + +/* *********************************************** */ + + +static const struct option long_options[] = + { + { "community", required_argument, NULL, 'c' }, + { "supernode-list", required_argument, NULL, 'l' }, + { "tap-device", required_argument, NULL, 'd' }, + { "euid", required_argument, NULL, 'u' }, + { "egid", required_argument, NULL, 'g' }, + { "verbose", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, '@' }, /* internal special character '@' to identify long help case */ + { "select-rtt", no_argument, NULL, '[' }, /* '[' rtt selection strategy */ + { "select-mac", no_argument, NULL, ']' }, /* ']' mac selection strategy */ + { "management-password", required_argument, NULL, '{' }, /* '{' management port password */ + { NULL, 0, NULL, 0 } + }; + +/* *************************************************** */ + +/* read command line options */ +static int loadFromCLI (int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) { + + u_char c; + + while ((c = getopt_long(argc, argv, + "k:a:c:Eu:g:m:M:s:d:l:p:fvhrt:i:I:J:P:S::DL:z::A::Hn:R:e:" +#ifdef __linux__ + "T:" +#endif +#ifdef WIN32 + "x:" +#endif + , + long_options, NULL)) != '?') { + + if(c == 255) break; + help(setOption(c, optarg, ec, conf)); + + } + + return 0; +} + +/* *************************************************** */ + +static char *trim (char *s) { + + char *end; + + while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) s++; + if(s[0] == 0) return s; + + end = &s[strlen(s) - 1]; + while(end > s + && (isspace(end[0])|| (end[0] == '"') || (end[0] == '\''))) + end--; + end[1] = 0; + + return s; +} + +/* *************************************************** */ + +/* parse the configuration file */ +static int loadFromFile (const char *path, n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) { + + char buffer[4096], *line; + char *line_vec[3]; + int tmp; + + FILE *fd; + + fd = fopen(path, "r"); + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "config file %s not found", path); + return -1; + } + + // we mess around with optind, better save it + tmp = optind; + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + line = trim(line); + + if(strlen(line) < 2 || line[0] == '#') + continue; + + // executable, cannot be omitted, content can be anything + line_vec[0] = line; + // first token, e.g. `-p` or `-A3', eventually followed by a whitespace or '=' delimiter + line_vec[1] = strtok(line, "\t ="); + // separate parameter option, if present + line_vec[2] = strtok(NULL, ""); + if(line_vec[2]) + line_vec[2] = trim(line_vec[2]); + // not to duplicate the option parser code, call loadFromCLI and pretend we have no option read yet at all + optind = 0; + // if second token present (optional argument, not part of first), then announce 3 vector members + loadFromCLI(line_vec[2] ? 3 : 2, line_vec, conf, ec); + } + + fclose(fd); + optind = tmp; + + return 0; +} + +/* ************************************** */ + +#ifndef WIN32 +static void daemonize () { + int childpid; + + traceEvent(TRACE_NORMAL, "parent process is exiting (this is normal)"); + + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + if((childpid = fork()) < 0) + traceEvent(TRACE_ERROR, "occurred while daemonizing (errno=%d)", + errno); + else { + if(!childpid) { /* child */ + int rc; + + //traceEvent(TRACE_NORMAL, "Bye bye: I'm becoming a daemon..."); + rc = chdir("/"); + if(rc != 0) + traceEvent(TRACE_ERROR, "error while moving to / directory"); + + setsid(); /* detach from the terminal */ + + fclose(stdin); + fclose(stdout); + /* fclose(stderr); */ + + /* + * clear any inherited file mode creation mask + */ + //umask(0); + + /* + * Use line buffered stdout + */ + /* setlinebuf (stdout); */ + setvbuf(stdout, (char *)NULL, _IOLBF, 0); + } else /* father */ + exit(0); + } +} +#endif + +/* *************************************************** */ + +static int keep_on_running; + +#if defined(__linux__) || defined(WIN32) +#ifdef WIN32 +BOOL WINAPI term_handler(DWORD sig) +#else + static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "ok, I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "shutting down..."); + called = 1; + } + + keep_on_running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} +#endif /* defined(__linux__) || defined(WIN32) */ + +/* *************************************************** */ + +/** Entry point to program from kernel. */ +int main (int argc, char* argv[]) { + + int rc; + tuntap_dev tuntap; /* a tuntap device */ + n2n_edge_t *eee; /* single instance for this program */ + n2n_edge_conf_t conf; /* generic N2N edge config */ + n2n_tuntap_priv_config_t ec; /* config used for standalone program execution */ + uint8_t runlevel = 0; /* bootstrap: runlevel */ + uint8_t seek_answer = 1; /* expecting answer from supernode */ + time_t now, last_action = 0; /* timeout */ + macstr_t mac_buf; /* output mac address */ + fd_set socket_mask; /* for supernode answer */ + struct timeval wait_time; /* timeout for sn answer */ + peer_info_t *scan, *scan_tmp; /* supernode iteration */ + + uint16_t expected = sizeof(uint16_t); + uint16_t position = 0; + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE + sizeof(uint16_t)]; /* buffer + prepended buffer length in case of tcp */ + + +#ifndef WIN32 + struct passwd *pw = NULL; +#endif +#ifdef HAVE_LIBCAP + cap_t caps; +#endif +#ifdef WIN32 + initWin32(); +#endif + + /* Defaults */ + edge_init_conf_defaults(&conf); + memset(&ec, 0, sizeof(ec)); + ec.mtu = DEFAULT_MTU; + ec.daemon = 1; /* By default run in daemon mode. */ + +#ifndef WIN32 + if(((pw = getpwnam("n2n")) != NULL) || + ((pw = getpwnam("nobody")) != NULL)) { + ec.userid = pw->pw_uid; + ec.groupid = pw->pw_gid; + } +#endif + +#ifdef WIN32 + ec.tuntap_dev_name[0] = '\0'; + ec.metric = 0; +#else + snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), N2N_EDGE_DEFAULT_DEV_NAME); +#endif + snprintf(ec.netmask, sizeof(ec.netmask), N2N_EDGE_DEFAULT_NETMASK); + + if((argc >= 2) && (argv[1][0] != '-')) { + rc = loadFromFile(argv[1], &conf, &ec); + if(argc > 2) + rc = loadFromCLI(argc, argv, &conf, &ec); + } else if(argc > 1) + rc = loadFromCLI(argc, argv, &conf, &ec); + else + +#ifdef WIN32 + // load from current directory + rc = loadFromFile("edge.conf", &conf, &ec); +#else + rc = -1; +#endif + + // --- additional crypto setup; REVISIT: move to edge_init()? + // payload + if(conf.transop_id == N2N_TRANSFORM_ID_NULL) { + if(conf.encrypt_key) { + // make sure that AES is default cipher if key only (and no cipher) is specified + traceEvent(TRACE_WARNING, "switching to AES as key was provided"); + conf.transop_id = N2N_TRANSFORM_ID_AES; + } + } + // user auth + if(conf.shared_secret /* containing private key only so far*/) { + // if user-password auth and no federation public key provided, use default + if(!conf.federation_public_key) { + conf.federation_public_key = calloc(1, sizeof(n2n_private_public_key_t)); + if(conf.federation_public_key) { + traceEvent(TRACE_WARNING, "using default federation public key; FOR TESTING ONLY, usage of a custom federation name and key (-P) is highly recommended!"); + generate_private_key(*(conf.federation_public_key), FEDERATION_NAME + 1); + generate_public_key(*(conf.federation_public_key), *(conf.federation_public_key)); + } + } + // calculate public key and shared secret + if(conf.federation_public_key) { + traceEvent(TRACE_NORMAL, "using username and password for edge authentication"); + bind_private_key_to_username(*(conf.shared_secret), (char *)conf.dev_desc); + conf.public_key = calloc(1, sizeof(n2n_private_public_key_t)); + if(conf.public_key) + generate_public_key(*conf.public_key, *(conf.shared_secret)); + generate_shared_secret(*(conf.shared_secret), *(conf.shared_secret), *(conf.federation_public_key)); + // prepare (first 128 bit) for use as key + conf.shared_secret_ctx = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)&(conf.shared_secret_ctx), *(conf.shared_secret), 128); + } + // force header encryption + if(conf.header_encryption != HEADER_ENCRYPTION_ENABLED) { + traceEvent(TRACE_NORMAL, "enabling header encryption for edge authentication"); + conf.header_encryption = HEADER_ENCRYPTION_ENABLED; + } + } + + if(rc < 0) + help(1); /* short help */ + + if(edge_verify_conf(&conf) != 0) + help(1); /* short help */ + + traceEvent(TRACE_NORMAL, "starting n2n edge %s %s", PACKAGE_VERSION, PACKAGE_BUILDDATE); + +#if defined(HAVE_OPENSSL_1_1) + traceEvent(TRACE_NORMAL, "using %s", OpenSSL_version(0)); +#endif + + traceEvent(TRACE_NORMAL, "using compression: %s.", compression_str(conf.compression)); + traceEvent(TRACE_NORMAL, "using %s cipher.", transop_str(conf.transop_id)); + + /* Random seed */ + n2n_srand (n2n_seed()); + +#ifndef WIN32 + /* If running suid root then we need to setuid before using the force. */ + if(setuid(0) != 0) + traceEvent(TRACE_ERROR, "unable to become root [%u/%s]", errno, strerror(errno)); + /* setgid(0); */ +#endif + + if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key)) + traceEvent(TRACE_WARNING, "community and encryption key must differ, otherwise security will be compromised"); + + if((eee = edge_init(&conf, &rc)) == NULL) { + traceEvent(TRACE_ERROR, "failed in edge_init"); + exit(1); + } + + memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec)); + + if((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) || + ((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) { + traceEvent(TRACE_NORMAL, "use manually set IP address"); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC; + } else if(0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) { + traceEvent(TRACE_NORMAL, "obtain IP from other edge DHCP services"); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP; + } else { + traceEvent(TRACE_NORMAL, "automatically assign IP address by supernode"); + eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; + } + + // mini main loop for bootstrap, not using main loop code because some of its mechanisms do not fit in here + // for the sake of quickly establishing connection. REVISIT when a more elegant way to re-use main loop code + // is found + + // find at least one supernode alive to faster establish connection + // exceptions: + if((HASH_COUNT(eee->conf.supernodes) <= 1) || (eee->conf.connect_tcp) || (eee->conf.shared_secret)) { + // skip the initial supernode ping + traceEvent(TRACE_DEBUG, "skip PING to supernode"); + runlevel = 2; + } + + eee->last_sup = 0; /* if it wasn't zero yet */ + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + while(runlevel < 5) { + + now = time(NULL); + + // we do not use switch-case because we also check for 'greater than' + + if(runlevel == 0) { /* PING to all known supernodes */ + last_action = now; + eee->sn_pong = 0; + // (re-)initialize the number of max concurrent pings (decreases by calling send_query_peer) + eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL; + send_query_peer(eee, null_mac); + traceEvent(TRACE_NORMAL, "send PING to supernodes"); + runlevel++; + } + + if(runlevel == 1) { /* PING has been sent to all known supernodes */ + if(eee->sn_pong) { + // first answer + eee->sn_pong = 0; + sn_selection_sort(&(eee->conf.supernodes)); + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + traceEvent(TRACE_NORMAL, "received first PONG from supernode [%s]", eee->curr_sn->ip_addr); + runlevel++; + } else if(last_action <= (now - BOOTSTRAP_TIMEOUT)) { + // timeout + runlevel--; + // skip waiting for answer to direcly go to send PING again + seek_answer = 0; + traceEvent(TRACE_DEBUG, "PONG timeout"); + } + } + + // by the way, have every later PONG cause the remaining (!) list to be sorted because the entries + // before have already been tried; as opposed to initial PONG, do not change curr_sn + if(runlevel > 1) { + if(eee->sn_pong) { + eee->sn_pong = 0; + if(eee->curr_sn->hh.next) { + sn_selection_sort((peer_info_t**)&(eee->curr_sn->hh.next)); + traceEvent(TRACE_DEBUG, "received additional PONG from supernode"); + // here, it is hard to detemine from which one, so no details to output + } + } + } + + if(runlevel == 2) { /* send REGISTER_SUPER to get auto ip address from a supernode */ + if(eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_SN_ASSIGN) { + last_action = now; + eee->sn_wait = 1; + send_register_super(eee); + runlevel++; + traceEvent(TRACE_NORMAL, "send REGISTER_SUPER to supernode [%s] asking for IP address", + eee->curr_sn->ip_addr); + } else { + runlevel += 2; /* skip waiting for TUNTAP IP address */ + traceEvent(TRACE_DEBUG, "skip auto IP address asignment"); + } + } + + if(runlevel == 3) { /* REGISTER_SUPER to get auto ip address from a sn has been sent */ + if(!eee->sn_wait) { /* TUNTAP IP address received */ + runlevel++; + traceEvent(TRACE_NORMAL, "received REGISTER_SUPER_ACK from supernode for IP address asignment"); + // it should be from curr_sn, but we can't determine definitely here, so no details to output + } else if(last_action <= (now - BOOTSTRAP_TIMEOUT)) { + // timeout, so try next supernode + if(eee->curr_sn->hh.next) + eee->curr_sn = eee->curr_sn->hh.next; + else + eee->curr_sn = eee->conf.supernodes; + supernode_connect(eee); + runlevel--; + // skip waiting for answer to direcly go to send REGISTER_SUPER again + seek_answer = 0; + traceEvent(TRACE_DEBUG, "REGISTER_SUPER_ACK timeout"); + } + } + + if(runlevel == 4) { /* configure the TUNTAP device, including routes */ + if(tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode, + eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask, + eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu +#ifdef WIN32 + , eee->tuntap_priv_conf.metric +#endif + ) < 0) + exit(1); + memcpy(&eee->device, &tuntap, sizeof(tuntap)); + traceEvent(TRACE_NORMAL, "created local tap device IP: %s, Mask: %s, MAC: %s", + eee->tuntap_priv_conf.ip_addr, + eee->tuntap_priv_conf.netmask, + macaddr_str(mac_buf, eee->device.mac_addr)); + // routes + if(edge_init_routes(eee, eee->conf.routes, eee->conf.num_routes) < 0) { + traceEvent(TRACE_ERROR, "routes setup failed"); + exit(1); + } + runlevel = 5; + // no more answers required + seek_answer = 0; + } + + // we usually wait for some answer, there however are exceptions when going back to a previous runlevel + if(seek_answer) { + FD_ZERO(&socket_mask); + FD_SET(eee->sock, &socket_mask); + wait_time.tv_sec = BOOTSTRAP_TIMEOUT; + wait_time.tv_usec = 0; + + if(select(eee->sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) { + if(FD_ISSET(eee->sock, &socket_mask)) { + + fetch_and_eventually_process_data (eee, eee->sock, + pktbuf, &expected, &position, + now); + } + } + } + seek_answer = 1; + + resolve_check(eee->resolve_parameter, 0 /* no intermediate resolution requirement at this point */, now); + } + // allow a higher number of pings for first regular round of ping + // to quicker get an inital 'supernode selection criterion overview' + eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_INITIAL; + // shape supernode list; make current one the first on the list + HASH_ITER(hh, eee->conf.supernodes, scan, scan_tmp) { + if(scan == eee->curr_sn) + sn_selection_criterion_good(&(scan->selection_criterion)); + else + sn_selection_criterion_default(&(scan->selection_criterion)); + } + sn_selection_sort(&(eee->conf.supernodes)); + // do not immediately ping again, allow some time + eee->last_sweep = now - SWEEP_TIME + 2 * BOOTSTRAP_TIMEOUT; + eee->sn_wait = 1; + eee->last_register_req = 0; + +#ifndef WIN32 + if(eee->tuntap_priv_conf.daemon) { + setUseSyslog(1); /* traceEvent output now goes to syslog. */ + daemonize(); + } + +#ifdef HAVE_LIBCAP + /* Before dropping the privileges, retain capabilities to regain them in future. */ + caps = cap_get_proc(); + + cap_set_flag(caps, CAP_PERMITTED, num_cap, cap_values, CAP_SET); + cap_set_flag(caps, CAP_EFFECTIVE, num_cap, cap_values, CAP_SET); + + if((cap_set_proc(caps) != 0) || (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0)) + traceEvent(TRACE_WARNING, "unable to retain permitted capabilities [%s]\n", strerror(errno)); +#else +#ifndef __APPLE__ + traceEvent(TRACE_WARNING, "n2n has not been compiled with libcap-dev; some commands may fail"); +#endif +#endif /* HAVE_LIBCAP */ + + if((eee->tuntap_priv_conf.userid != 0) || (eee->tuntap_priv_conf.groupid != 0)) { + traceEvent(TRACE_NORMAL, "dropping privileges to uid=%d, gid=%d", + (signed int)eee->tuntap_priv_conf.userid, (signed int)eee->tuntap_priv_conf.groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + if((setgid(eee->tuntap_priv_conf.groupid) != 0) + || (setuid(eee->tuntap_priv_conf.userid) != 0)) { + traceEvent(TRACE_ERROR, "unable to drop privileges [%u/%s]", errno, strerror(errno)); + exit(1); + } + } + + if((getuid() == 0) || (getgid() == 0)) + traceEvent(TRACE_WARNING, "running as root is discouraged, check out the -u/-g options"); +#endif + +#ifdef __linux__ + signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); +#endif +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#endif + + keep_on_running = 1; + eee->keep_running = &keep_on_running; + traceEvent(TRACE_NORMAL, "edge started"); + rc = run_edge_loop(eee); + print_edge_stats(eee); + +#ifdef HAVE_LIBCAP + /* Before completing the cleanup, regain the capabilities as some + * cleanup tasks require them (e.g. routes cleanup). */ + cap_set_flag(caps, CAP_EFFECTIVE, num_cap, cap_values, CAP_SET); + + if(cap_set_proc(caps) != 0) + traceEvent(TRACE_WARNING, "could not regain the capabilities [%s]\n", strerror(errno)); + + cap_free(caps); +#endif + + /* Cleanup */ + edge_term_conf(&eee->conf); + tuntap_close(&eee->device); + edge_term(eee); + +#ifdef WIN32 + destroyWin32(); +#endif + + return(rc); +} + +/* ************************************** */ diff --git a/bundles/n2n_ntop_v3/src/edge_management.c b/bundles/n2n_ntop_v3/src/edge_management.c new file mode 100644 index 00000000..5438ae38 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/edge_management.c @@ -0,0 +1,457 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "edge_utils_win32.h" + +#define FLAG_WROK 1 +typedef struct n2n_mgmt_handler { + int flags; + char *cmd; + char *help; + void (*func)(n2n_edge_t *eee, char *udp_buf, struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv); +} n2n_mgmt_handler_t; + +static void mgmt_error (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, char *tag, char *msg) { + size_t msg_len; + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"error\"," + "\"error\":\"%s\"}\n", + tag, + msg); + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_stop (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(type==N2N_MGMT_WRITE) { + *eee->keep_running = 0; + } + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"keep_running\":%u}\n", + tag, + *eee->keep_running); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_verbose (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(type==N2N_MGMT_WRITE) { + if(argv) { + setTraceLevel(strtoul(argv, NULL, 0)); + } + } + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"traceLevel\":%u}\n", + tag, + getTraceLevel()); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_communities (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(eee->conf.header_encryption != HEADER_ENCRYPTION_NONE) { + mgmt_error(eee, udp_buf, sender_sock, tag, "noaccess"); + return; + } + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"community\":\"%s\"}", + tag, + eee->conf.community_name); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_supernodes (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + struct peer_info *peer, *tmpPeer; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + selection_criterion_str_t sel_buf; + + HASH_ITER(hh, eee->conf.supernodes, peer, tmpPeer) { + + /* + * TODO: + * The version string provided by the remote supernode could contain + * chars that make our JSON invalid. + * - do we care? + */ + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"version\":\"%s\"," + "\"purgeable\":%i," + "\"current\":%i," + "\"macaddr\":\"%s\"," + "\"sockaddr\":\"%s\"," + "\"selection\":\"%s\"," + "\"last_seen\":%li," + "\"uptime\":%li}\n", + tag, + peer->version, + peer->purgeable, + (peer == eee->curr_sn) ? (eee->sn_wait ? 2 : 1 ) : 0, + is_null_mac(peer->mac_addr) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + sn_selection_criterion_str(eee, sel_buf, peer), + peer->last_seen, + peer->uptime); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + } +} + +static void mgmt_edges_row (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, char *tag, struct peer_info *peer, char *mode) { + size_t msg_len; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"mode\":\"%s\"," + "\"ip4addr\":\"%s\"," + "\"purgeable\":%i," + "\"local\":%i," + "\"macaddr\":\"%s\"," + "\"sockaddr\":\"%s\"," + "\"desc\":\"%s\"," + "\"last_p2p\":%li,\n" + "\"last_sent_query\":%li,\n" + "\"last_seen\":%li}\n", + tag, + mode, + (peer->dev_addr.net_addr == 0) ? "" : ip_subnet_to_str(ip_bit_str, &peer->dev_addr), + peer->purgeable, + peer->local, + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + peer->last_p2p, + peer->last_sent_query, + peer->last_seen); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0 /*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_edges (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + struct peer_info *peer, *tmpPeer; + + // dump nodes with forwarding through supernodes + HASH_ITER(hh, eee->pending_peers, peer, tmpPeer) { + mgmt_edges_row(eee, udp_buf, sender_sock, tag, peer, "pSp"); + } + + // dump peer-to-peer nodes + HASH_ITER(hh, eee->known_peers, peer, tmpPeer) { + mgmt_edges_row(eee, udp_buf, sender_sock, tag, peer, "p2p"); + } +} + +static void mgmt_timestamps (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"start_time\":%lu," + "\"last_super\":%ld," + "\"last_p2p\":%ld}\n", + tag, + eee->start_time, + eee->last_sup, + eee->last_p2p); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_packetstats (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"transop\"," + "\"tx_pkt\":%lu," + "\"rx_pkt\":%lu}\n", + tag, + eee->transop.tx_cnt, + eee->transop.rx_cnt); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"p2p\"," + "\"tx_pkt\":%u," + "\"rx_pkt\":%u}\n", + tag, + eee->stats.tx_p2p, + eee->stats.rx_p2p); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"super\"," + "\"tx_pkt\":%u," + "\"rx_pkt\":%u}\n", + tag, + eee->stats.tx_sup, + eee->stats.rx_sup); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"super_broadcast\"," + "\"tx_pkt\":%u," + "\"rx_pkt\":%u}\n", + tag, + eee->stats.tx_sup_broadcast, + eee->stats.rx_sup_broadcast); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_unimplemented (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + + mgmt_error(eee, udp_buf, sender_sock, tag, "unimplemented"); +} + +static void mgmt_help (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv); + +n2n_mgmt_handler_t mgmt_handlers[] = { + { .cmd = "reload_communities", .flags = FLAG_WROK, .help = "Reserved for supernode", .func = mgmt_unimplemented}, + + { .cmd = "stop", .flags = FLAG_WROK, .help = "Gracefully exit edge", .func = mgmt_stop}, + { .cmd = "verbose", .flags = FLAG_WROK, .help = "Manage verbosity level", .func = mgmt_verbose}, + { .cmd = "communities", .help = "Show current community", .func = mgmt_communities}, + { .cmd = "edges", .help = "List current edges/peers", .func = mgmt_edges}, + { .cmd = "supernodes", .help = "List current supernodes", .func = mgmt_supernodes}, + { .cmd = "timestamps", .help = "Event timestamps", .func = mgmt_timestamps}, + { .cmd = "packetstats", .help = "traffic counters", .func = mgmt_packetstats}, + { .cmd = "help", .flags = FLAG_WROK, .help = "Show JSON commands", .func = mgmt_help}, + { .cmd = NULL }, +}; + +static void mgmt_help (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + n2n_mgmt_handler_t *handler; + + /* + * Even though this command is readonly, we deliberately do not check + * the type - allowing help replies to both read and write requests + */ + + for( handler=mgmt_handlers; handler->cmd; handler++ ) { + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"cmd\":\"%s\"," + "\"help\":\"%s\"}\n", + tag, + handler->cmd, + handler->help); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + } +} + +/* + * Check if the user is authorised for this command. + * - this should be more configurable! + * - for the moment we use some simple heuristics: + * Reads are not dangerous, so they are simply allowed + * Writes are possibly dangerous, so they need a fake password + */ +static int mgmt_auth (n2n_edge_t *eee, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) { + + if(auth) { + /* If we have an auth key, it must match */ + if(eee->conf.mgmt_password_hash == pearson_hash_64((uint8_t*)auth, strlen(auth))) { + return 1; + } + return 0; + } + /* if we dont have an auth key, we can still read */ + if(type == N2N_MGMT_READ) { + return 1; + } + + return 0; +} + +void handleMgmtJson (n2n_edge_t *eee, char *udp_buf, const struct sockaddr_in sender_sock) { + + char cmdlinebuf[80]; + enum n2n_mgmt_type type; + char *typechar; + char *options; + char *argv0; + char *argv; + char *tag; + char *flagstr; + int flags; + char *auth; + n2n_mgmt_handler_t *handler; + size_t msg_len; + + /* save a copy of the commandline before we reuse the udp_buf */ + strncpy(cmdlinebuf, udp_buf, sizeof(cmdlinebuf)-1); + cmdlinebuf[sizeof(cmdlinebuf)-1] = 0; + + traceEvent(TRACE_DEBUG, "mgmt json %s", cmdlinebuf); + + typechar = strtok(cmdlinebuf, " \r\n"); + if(!typechar) { + /* should not happen */ + mgmt_error(eee, udp_buf, sender_sock, "-1", "notype"); + return; + } + if(*typechar == 'r') { + type=N2N_MGMT_READ; + } else if(*typechar == 'w') { + type=N2N_MGMT_WRITE; + } else { + /* dunno how we got here */ + mgmt_error(eee, udp_buf, sender_sock, "-1", "badtype"); + return; + } + + /* Extract the tag to use in all reply packets */ + options = strtok(NULL, " \r\n"); + if(!options) { + mgmt_error(eee, udp_buf, sender_sock, "-1", "nooptions"); + return; + } + + argv0 = strtok(NULL, " \r\n"); + if(!argv0) { + mgmt_error(eee, udp_buf, sender_sock, "-1", "nocmd"); + return; + } + + /* + * The entire rest of the line is the argv. We apply no processing + * or arg separation so that the cmd can use it however it needs. + */ + argv = strtok(NULL, "\r\n"); + + /* + * There might be an auth token mixed in with the tag + */ + tag = strtok(options, ":"); + flagstr = strtok(NULL, ":"); + if(flagstr) { + flags = strtoul(flagstr, NULL, 16); + } else { + flags = 0; + } + + /* Only 1 flag bit defined at the moment - "auth option present" */ + if(flags & 1) { + auth = strtok(NULL, ":"); + } else { + auth = NULL; + } + + if(!mgmt_auth(eee, sender_sock, type, auth, argv0, argv)) { + mgmt_error(eee, udp_buf, sender_sock, tag, "badauth"); + return; + } + + for( handler=mgmt_handlers; handler->cmd; handler++ ) { + if(0 == strcmp(handler->cmd, argv0)) { + break; + } + } + if(!handler->cmd) { + mgmt_error(eee, udp_buf, sender_sock, tag, "unknowncmd"); + return; + } + + if((type==N2N_MGMT_WRITE) && !(handler->flags & FLAG_WROK)) { + mgmt_error(eee, udp_buf, sender_sock, tag, "readonly"); + return; + } + + /* + * TODO: + * The tag provided by the requester could contain chars + * that make our JSON invalid. + * - do we care? + */ + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{\"_tag\":\"%s\",\"_type\":\"begin\",\"cmd\":\"%s\"}\n", tag, argv0); + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + handler->func(eee, udp_buf, sender_sock, type, tag, argv0, argv); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{\"_tag\":\"%s\",\"_type\":\"end\"}\n", tag); + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + return; +} diff --git a/bundles/n2n_ntop_v3/src/edge_utils.c b/bundles/n2n_ntop_v3/src/edge_utils.c new file mode 100644 index 00000000..781f460d --- /dev/null +++ b/bundles/n2n_ntop_v3/src/edge_utils.c @@ -0,0 +1,3829 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "network_traffic_filter.h" +#include "edge_utils_win32.h" + +/* heap allocation for compression as per lzo example doc */ +#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] +static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); + +/* ************************************** */ + +int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list); +int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now); +int resolve_cancel_thread (n2n_resolve_parameter_t *param); + +static const char * supernode_ip (const n2n_edge_t * eee); +static void send_register (n2n_edge_t *eee, const n2n_sock_t *remote_peer, const n2n_mac_t peer_mac, n2n_cookie_t cookie); + +static void check_peer_registration_needed (n2n_edge_t *eee, + uint8_t from_supernode, + uint8_t via_multicast, + const n2n_mac_t mac, + const n2n_cookie_t cookie, + const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, + const n2n_sock_t *peer); + +static int edge_init_sockets (n2n_edge_t *eee); +int edge_init_routes (n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes); +static void edge_cleanup_routes (n2n_edge_t *eee); + +static void check_known_peer_sock_change (n2n_edge_t *eee, + uint8_t from_supernode, + uint8_t via_multicast, + const n2n_mac_t mac, + const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, + const n2n_sock_t *peer, + time_t when); + +/* ************************************** */ + +int edge_verify_conf (const n2n_edge_conf_t *conf) { + + if(conf->community_name[0] == 0) + return -1; + + // REVISIT: are the following two conditions equal? if so, remove one. but note that sn_num is used elsewhere + if(conf->sn_num == 0) + return -2; + + if(HASH_COUNT(conf->supernodes) == 0) + return -5; + + if(conf->register_interval < 1) + return -3; + + if(((conf->encrypt_key == NULL) && (conf->transop_id != N2N_TRANSFORM_ID_NULL)) || + ((conf->encrypt_key != NULL) && (conf->transop_id == N2N_TRANSFORM_ID_NULL))) + return -4; + + return 0; +} + + +/* ************************************** */ + +void edge_set_callbacks (n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks) { + + memcpy(&eee->cb, callbacks, sizeof(n2n_edge_callbacks_t)); +} + +/* ************************************** */ + +void edge_set_userdata (n2n_edge_t *eee, void *user_data) { + + eee->user_data = user_data; +} + +/* ************************************** */ + +void* edge_get_userdata (n2n_edge_t *eee) { + + return(eee->user_data); +} + +/* ************************************** */ + +int edge_get_n2n_socket (n2n_edge_t *eee) { + + return(eee->sock); +} + +/* ************************************** */ + +int edge_get_management_socket (n2n_edge_t *eee) { + + return(eee->udp_mgmt_sock); +} + +/* ************************************** */ + +const char* transop_str (enum n2n_transform tr) { + + switch(tr) { + case N2N_TRANSFORM_ID_NULL: return("null"); + case N2N_TRANSFORM_ID_TWOFISH: return("Twofish"); + case N2N_TRANSFORM_ID_AES: return("AES"); + case N2N_TRANSFORM_ID_CHACHA20:return("ChaCha20"); + case N2N_TRANSFORM_ID_SPECK: return("Speck"); + default: return("invalid"); + }; +} + +/* ************************************** */ + +const char* compression_str (uint8_t cmpr) { + + switch(cmpr) { + case N2N_COMPRESSION_ID_NONE: return("none"); + case N2N_COMPRESSION_ID_LZO: return("lzo1x"); + case N2N_COMPRESSION_ID_ZSTD: return("zstd"); + default: return("invalid"); + }; +} + +/* ************************************** */ + +/** Destination 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF is multicast ethernet. + */ +static int is_ethMulticast (const void * buf, size_t bufsize) { + + int retval = 0; + + /* Match 01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF */ + if(bufsize >= sizeof(ether_hdr_t)) { + /* copy to aligned memory */ + ether_hdr_t eh; + memcpy(&eh, buf, sizeof(ether_hdr_t)); + + if((0x01 == eh.dhost[0]) && + (0x00 == eh.dhost[1]) && + (0x5E == eh.dhost[2]) && + (0 == (0x80 & eh.dhost[3]))) + retval = 1; /* This is an ethernet multicast packet [RFC1112]. */ + } + + return retval; +} + +/* ************************************** */ + +/** Destination MAC 33:33:0:00:00:00 - 33:33:FF:FF:FF:FF is reserved for IPv6 + * neighbour discovery. + */ +static int is_ip6_discovery (const void * buf, size_t bufsize) { + + int retval = 0; + + if(bufsize >= sizeof(ether_hdr_t)) { + /* copy to aligned memory */ + ether_hdr_t eh; + + memcpy(&eh, buf, sizeof(ether_hdr_t)); + + if((0x33 == eh.dhost[0]) && (0x33 == eh.dhost[1])) + retval = 1; /* This is an IPv6 multicast packet [RFC2464]. */ + } + + return retval; +} + + +/* ************************************** */ + + +// reset number of supernode connection attempts: try only once for already more realiable tcp connections +void reset_sup_attempts (n2n_edge_t *eee) { + + eee->sup_attempts = (eee->conf.connect_tcp) ? 1 : N2N_EDGE_SUP_ATTEMPTS; +} + + +// detect local IP address by probing a connection to the supernode +static int detect_local_ip_address (n2n_sock_t* out_sock, const n2n_edge_t* eee) { + + struct sockaddr_in local_sock; + struct sockaddr_in sn_sock; + socklen_t sock_len = sizeof(local_sock); + SOCKET probe_sock; + int ret = 0; + + out_sock->family = AF_INVALID; + + // always detetct local port even/especially if chosen by OS... + if((getsockname(eee->sock, (struct sockaddr *)&local_sock, &sock_len) == 0) + && (local_sock.sin_family == AF_INET) + && (sock_len == sizeof(local_sock))) + // remember the port number + out_sock->port = ntohs(local_sock.sin_port); + else + ret = -1; + + // probe for local IP address + probe_sock = socket(PF_INET, SOCK_DGRAM, 0); + // connecting the UDP socket makes getsockname read the local address it uses to connect (to the sn in this case); + // we cannot do it with the real (eee->sock) socket because socket does not accept any conenction from elsewhere then, + // e.g. from another edge instead of the supernode; as re-connecting to AF_UNSPEC might not work to release the socket + // on non-UNIXoids, we use a temporary socket + if((int)probe_sock >= 0) { + fill_sockaddr((struct sockaddr*)&sn_sock, sizeof(sn_sock), &eee->curr_sn->sock); + if(connect(probe_sock, (struct sockaddr *)&sn_sock, sizeof(sn_sock)) == 0) { + if((getsockname(probe_sock, (struct sockaddr *)&local_sock, &sock_len) == 0) + && (local_sock.sin_family == AF_INET) + && (sock_len == sizeof(local_sock))) { + memcpy(&(out_sock->addr.v4), &(local_sock.sin_addr.s_addr), IPV4_SIZE); + } else + ret = -4; + } else + ret = -3; + closesocket(probe_sock); + } else + ret = -2; + + out_sock->family = AF_INET; + + return ret; +} + + +// open socket, close it before if TCP +// in case of TCP, 'connect()' is required +int supernode_connect (n2n_edge_t *eee) { + + int sockopt; + struct sockaddr_in sn_sock; + n2n_sock_t local_sock; + n2n_sock_str_t sockbuf; + + if((eee->conf.connect_tcp) && (eee->sock >= 0)) { + closesocket(eee->sock); + eee->sock = -1; + } + + if(eee->sock < 0) { + + if(eee->conf.local_port > 0) + traceEvent(TRACE_NORMAL, "binding to local port %d", + (eee->conf.connect_tcp) ? 0 : eee->conf.local_port); + + eee->sock = open_socket((eee->conf.connect_tcp) ? 0 : eee->conf.local_port, + eee->conf.bind_address, + eee->conf.connect_tcp); + + if(eee->sock < 0) { + traceEvent(TRACE_ERROR, "failed to bind main UDP port %u", + (eee->conf.connect_tcp) ? 0 : eee->conf.local_port); + return -1; + } + + fill_sockaddr((struct sockaddr*)&sn_sock, sizeof(sn_sock), &eee->curr_sn->sock); + + // set tcp socket to O_NONBLOCK so connect does not hang + // requires checking the socket for readiness before sending and receving + if(eee->conf.connect_tcp) { +#ifdef WIN32 + u_long value = 1; + ioctlsocket(eee->sock, FIONBIO, &value); +#else + fcntl(eee->sock, F_SETFL, O_NONBLOCK); +#endif + if((connect(eee->sock, (struct sockaddr*)&(sn_sock), sizeof(struct sockaddr)) < 0) + && (errno != EINPROGRESS)) { + eee->sock = -1; + return -1; + } + } + + if(eee->conf.tos) { + /* https://www.tucny.com/Home/dscp-tos */ + sockopt = eee->conf.tos; + + if(setsockopt(eee->sock, IPPROTO_IP, IP_TOS, (char *)&sockopt, sizeof(sockopt)) == 0) + traceEvent(TRACE_INFO, "TOS set to 0x%x", eee->conf.tos); + else + traceEvent(TRACE_WARNING, "could not set TOS 0x%x[%d]: %s", eee->conf.tos, errno, strerror(errno)); + } +#ifdef IP_PMTUDISC_DO + sockopt = (eee->conf.disable_pmtu_discovery) ? IP_PMTUDISC_DONT : IP_PMTUDISC_DO; + + if(setsockopt(eee->sock, IPPROTO_IP, IP_MTU_DISCOVER, &sockopt, sizeof(sockopt)) < 0) + traceEvent(TRACE_WARNING, "could not %s PMTU discovery[%d]: %s", + (eee->conf.disable_pmtu_discovery) ? "disable" : "enable", errno, strerror(errno)); + else + traceEvent(TRACE_INFO, "PMTU discovery %s", (eee->conf.disable_pmtu_discovery) ? "disabled" : "enabled"); +#endif + + memset(&local_sock, 0, sizeof(n2n_sock_t)); + if(detect_local_ip_address(&local_sock, eee) == 0) { + // always overwrite local port even/especially if chosen by OS... + eee->conf.preferred_sock.port = local_sock.port; + // only if auto-detection mode, ... + if(eee->conf.preferred_sock_auto) { + // ... overwrite IP address, too (whole socket struct here) + memcpy(&eee->conf.preferred_sock, &local_sock, sizeof(n2n_sock_t)); + traceEvent(TRACE_INFO, "determined local socket [%s]", + sock_to_cstr(sockbuf, &local_sock)); + } + } + + if(eee->cb.sock_opened) + eee->cb.sock_opened(eee); + } + + return 0; +} + + +// always closes the socket +void supernode_disconnect (n2n_edge_t *eee) { + + if(eee->sock >= 0) { + closesocket(eee->sock); + eee->sock = -1; + } +} + + +/* ************************************** */ + +/** Initialise an edge to defaults. + * + * This also initialises the NULL transform operation opstruct. + */ +n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv) { + + n2n_transform_t transop_id = conf->transop_id; + n2n_edge_t *eee = calloc(1, sizeof(n2n_edge_t)); + int rc = -1, i = 0; + struct peer_info *scan, *tmp; + uint8_t tmp_key[N2N_AUTH_CHALLENGE_SIZE]; + + if((rc = edge_verify_conf(conf)) != 0) { + traceEvent(TRACE_ERROR, "invalid configuration"); + goto edge_init_error; + } + + if(!eee) { + traceEvent(TRACE_ERROR, "cannot allocate memory"); + goto edge_init_error; + } + + + memcpy(&eee->conf, conf, sizeof(*conf)); + eee->curr_sn = eee->conf.supernodes; + eee->start_time = time(NULL); + + eee->known_peers = NULL; + eee->pending_peers = NULL; + reset_sup_attempts(eee); + + sn_selection_criterion_common_data_default(eee); + + pearson_hash_init(); + + if(eee->conf.compression == N2N_COMPRESSION_ID_LZO) + if(lzo_init() != LZO_E_OK) { + traceEvent(TRACE_ERROR, "LZO compression error"); + goto edge_init_error; + } +#ifdef N2N_HAVE_ZSTD + // zstd does not require initialization. if it were required, this would be a good place +#endif + + traceEvent(TRACE_NORMAL, "number of supernodes in the list: %d\n", HASH_COUNT(eee->conf.supernodes)); + HASH_ITER(hh, eee->conf.supernodes, scan, tmp) { + traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (scan->ip_addr)); + i++; + } + + /* Set active transop */ + switch(transop_id) { + case N2N_TRANSFORM_ID_TWOFISH: + rc = n2n_transop_tf_init(&eee->conf, &eee->transop); + break; + + case N2N_TRANSFORM_ID_AES: + rc = n2n_transop_aes_init(&eee->conf, &eee->transop); + break; + + case N2N_TRANSFORM_ID_CHACHA20: + rc = n2n_transop_cc20_init(&eee->conf, &eee->transop); + break; + + case N2N_TRANSFORM_ID_SPECK: + rc = n2n_transop_speck_init(&eee->conf, &eee->transop); + break; + + default: + rc = n2n_transop_null_init(&eee->conf, &eee->transop); + } + + if((rc < 0) || (eee->transop.fwd == NULL) || (eee->transop.transform_id != transop_id)) { + traceEvent(TRACE_ERROR, "transop init failed"); + goto edge_init_error; + } + + // set the key schedule (context) for header encryption if enabled + if(conf->header_encryption == HEADER_ENCRYPTION_ENABLED) { + traceEvent(TRACE_NORMAL, "Header encryption is enabled."); + packet_header_setup_key((char *)(eee->conf.community_name), + &(eee->conf.header_encryption_ctx_static), + &(eee->conf.header_encryption_ctx_dynamic), + &(eee->conf.header_iv_ctx_static), + &(eee->conf.header_iv_ctx_dynamic)); + // in case of user/password auth, initialize a random dynamic key to prevent + // unintentional communication with only-header-encrypted community; will be + // overwritten by legit key later + if(conf->shared_secret) { + memrnd(tmp_key, N2N_AUTH_CHALLENGE_SIZE); + packet_header_change_dynamic_key(tmp_key, + &(eee->conf.header_encryption_ctx_dynamic), + &(eee->conf.header_iv_ctx_dynamic)); + } + } + + // setup authentication scheme + if(!conf->shared_secret) { + // id-based scheme + eee->conf.auth.scheme = n2n_auth_simple_id; + // random authentication token + memrnd(eee->conf.auth.token, N2N_AUTH_ID_TOKEN_SIZE); + eee->conf.auth.token_size = N2N_AUTH_ID_TOKEN_SIZE; + } else { + // user-password scheme + eee->conf.auth.scheme = n2n_auth_user_password; + // 'token' stores public key and the last random challenge being set upon sending REGISTER_SUPER + memcpy(eee->conf.auth.token, eee->conf.public_key, N2N_PRIVATE_PUBLIC_KEY_SIZE); + // random part of token (challenge) will be generated and filled in at each REGISTER_SUPER + eee->conf.auth.token_size = N2N_AUTH_PW_TOKEN_SIZE; + // make sure that only stream ciphers are being used + if((transop_id != N2N_TRANSFORM_ID_CHACHA20) + && (transop_id != N2N_TRANSFORM_ID_SPECK)) { + traceEvent(TRACE_ERROR, "user-password authentication requires ChaCha20 (-A4) or SPECK (-A5) to be used."); + goto edge_init_error; + } + } + + if(eee->transop.no_encryption) + traceEvent(TRACE_WARNING, "encryption is disabled in edge"); + + // first time calling edge_init_sockets needs -1 in the sockets for it does throw an error + // on trying to close them (open_sockets does so for also being able to RE-open the sockets + // if called in-between, see "Supernode not responding" in update_supernode_reg(...) + eee->sock = -1; + eee->udp_mgmt_sock = -1; +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + eee->udp_multicast_sock = -1; +#endif + if(edge_init_sockets(eee) < 0) { + traceEvent(TRACE_ERROR, "socket setup failed"); + goto edge_init_error; + } + + if(resolve_create_thread(&(eee->resolve_parameter), eee->conf.supernodes) == 0) { + traceEvent(TRACE_NORMAL, "successfully created resolver thread"); + } + + eee->network_traffic_filter = create_network_traffic_filter(); + network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.network_traffic_filter_rules); + + //edge_init_success: + *rv = 0; + return(eee); + +edge_init_error: + if(eee) + free(eee); + *rv = rc; + return(NULL); +} + +/* ************************************** */ + +static int find_and_remove_peer (struct peer_info **head, const n2n_mac_t mac) { + + struct peer_info *peer; + + HASH_FIND_PEER(*head, mac, peer); + if(peer) { + HASH_DEL(*head, peer); + free(peer); + return(1); + } + + return(0); +} + +/* ************************************** */ + +static uint32_t localhost_v4 = 0x7f000001; +static uint8_t localhost_v6[IPV6_SIZE] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + +/* Exclude localhost as it may be received when an edge node runs + * in the same supernode host. + */ +static int is_valid_peer_sock (const n2n_sock_t *sock) { + + switch(sock->family) { + case AF_INET: { + uint32_t *a = (uint32_t*)sock->addr.v4; + + if(*a != htonl(localhost_v4)) + return(1); + } + break; + + case AF_INET6: + if(memcmp(sock->addr.v6, localhost_v6, IPV6_SIZE)) + return(1); + break; + } + + return(0); +} + +/* ***************************************************** */ + + +/*** + * + * For a given packet, find the apporopriate internal last valid time stamp for lookup + * and verify it (and also update, if applicable). + */ +static int find_peer_time_stamp_and_verify (n2n_edge_t * eee, + peer_info_t *sn, const n2n_mac_t mac, + uint64_t stamp, int allow_jitter) { + + uint64_t *previous_stamp = NULL; + + if(sn) { + // from supernode + previous_stamp = &(sn->last_valid_time_stamp); + } else { + // from (peer) edge + struct peer_info *peer; + HASH_FIND_PEER(eee->pending_peers, mac, peer); + if(!peer) { + HASH_FIND_PEER(eee->known_peers, mac, peer); + } + + if(peer) { + // time_stamp_verify_and_update allows the pointer a previous stamp to be NULL + // if it is a (so far) unknown peer + previous_stamp = &(peer->last_valid_time_stamp); + } + } + + // failure --> 0; success --> 1 + return time_stamp_verify_and_update(stamp, previous_stamp, allow_jitter); +} + + +/* ************************************** */ + +/*** + * + * Register over multicast in case there is a peer on the same network listening + */ +static void register_with_local_peers (n2n_edge_t * eee) { +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if((eee->multicast_joined && eee->conf.allow_p2p) + && (eee->conf.preferred_sock.family == (uint8_t)AF_INVALID)) { + /* send registration to the local multicast group */ + traceEvent(TRACE_DEBUG, "registering with multicast group %s:%u", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + send_register(eee, &(eee->multicast_peer), NULL, N2N_MCAST_REG_COOKIE); + } +#else + traceEvent(TRACE_DEBUG, "multicast peers discovery is disabled, skipping"); +#endif +} + +/* ************************************** */ + +static struct peer_info* find_peer_by_sock (const n2n_sock_t *sock, struct peer_info *peer_list) { + + struct peer_info *scan, *tmp, *ret = NULL; + + HASH_ITER(hh, peer_list, scan, tmp) { + if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) { + ret = scan; + break; + } + } + + return ret; +} + +/* ************************************** */ + +/** Start the registration process. + * + * If the peer is already in pending_peers, ignore the request. + * If not in pending_peers, add it and send a REGISTER. + * + * If hdr is for a direct peer-to-peer packet, try to register back to sender + * even if the MAC is in pending_peers. This is because an incident direct + * packet indicates that peer-to-peer exchange should work so more aggressive + * registration can be permitted (once per incoming packet) as this should only + * last for a small number of packets.. + * + * Called from the main loop when Rx a packet for our device mac. + */ +static void register_with_new_peer (n2n_edge_t *eee, + uint8_t from_supernode, + uint8_t via_multicast, + const n2n_mac_t mac, + const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, + const n2n_sock_t *peer) { + + /* REVISIT: purge of pending_peers not yet done. */ + struct peer_info *scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + + /* NOTE: pending_peers are purged periodically with purge_expired_nodes */ + if(scan == NULL) { + scan = calloc(1, sizeof(struct peer_info)); + + memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); + scan->sock = *peer; + scan->timeout = eee->conf.register_interval; /* TODO: should correspond to the peer supernode registration timeout */ + scan->last_valid_time_stamp = initial_time_stamp(); + if(via_multicast) + scan->local = 1; + + HASH_ADD_PEER(eee->pending_peers, scan); + + traceEvent(TRACE_DEBUG, "new pending peer %s [%s]", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf, &(scan->sock))); + + traceEvent(TRACE_DEBUG, "pending peers list size=%u", + HASH_COUNT(eee->pending_peers)); + /* trace Sending REGISTER */ + if(from_supernode) { + /* UDP NAT hole punching through supernode. Send to peer first(punch local UDP hole) + * and then ask supernode to forward. Supernode then ask peer to ack. Some nat device + * drop and block ports with incoming UDP packet if out-come traffic does not exist. + * So we can alternatively set TTL so that the packet sent to peer never really reaches + * The register_ttl is basically nat level + 1. Set it to 1 means host like DMZ. + */ + if(eee->conf.register_ttl == 1) { + /* We are DMZ host or port is directly accessible. Just let peer to send back the ack */ +#ifndef WIN32 + } else if(eee->conf.register_ttl > 1) { + /* Setting register_ttl usually implies that the edge knows the internal net topology + * clearly, we can apply aggressive port prediction to support incoming Symmetric NAT + */ + int curTTL = 0; + socklen_t lenTTL = sizeof(int); + n2n_sock_t sock = scan->sock; + int alter = 16; /* TODO: set by command line or more reliable prediction method */ + + getsockopt(eee->sock, IPPROTO_IP, IP_TTL, (void *) (char *) &curTTL, &lenTTL); + setsockopt(eee->sock, IPPROTO_IP, IP_TTL, + (void *) (char *) &eee->conf.register_ttl, + sizeof(eee->conf.register_ttl)); + for(; alter > 0; alter--, sock.port++) { + send_register(eee, &sock, mac, N2N_PORT_REG_COOKIE); + } + setsockopt(eee->sock, IPPROTO_IP, IP_TTL, (void *) (char *) &curTTL, sizeof(curTTL)); +#endif + } else { /* eee->conf.register_ttl <= 0 */ + /* Normal STUN */ + send_register(eee, &(scan->sock), mac, N2N_REGULAR_REG_COOKIE); + } + send_register(eee, &(eee->curr_sn->sock), mac, N2N_FORWARDED_REG_COOKIE); + } else { + /* P2P register, send directly */ + send_register(eee, &(scan->sock), mac, N2N_REGULAR_REG_COOKIE); + } + register_with_local_peers(eee); + } else{ + scan->sock = *peer; + } + scan->last_seen = time(NULL); + if(dev_addr != NULL) { + memcpy(&(scan->dev_addr), dev_addr, sizeof(n2n_ip_subnet_t)); + } + if(dev_desc) memcpy(scan->dev_desc, dev_desc, N2N_DESC_SIZE); +} + + +/* ************************************** */ + +/** Update the last_seen time for this peer, or get registered. */ +static void check_peer_registration_needed (n2n_edge_t *eee, + uint8_t from_supernode, + uint8_t via_multicast, + const n2n_mac_t mac, + const n2n_cookie_t cookie, + const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, + const n2n_sock_t *peer) { + + struct peer_info *scan; + + HASH_FIND_PEER(eee->known_peers, mac, scan); + + /* If we were not able to find it by MAC, we try to find it by socket. */ + if(scan == NULL ) { + scan = find_peer_by_sock(peer, eee->known_peers); + + // MAC change + if(scan) { + HASH_DEL(eee->known_peers, scan); + memcpy(scan->mac_addr, mac, sizeof(n2n_mac_t)); + HASH_ADD_PEER(eee->known_peers, scan); + // reset last_local_reg to allow re-registration + scan->last_cookie = N2N_NO_REG_COOKIE; + } + } + + if(scan == NULL) { + /* Not in known_peers - start the REGISTER process. */ + register_with_new_peer(eee, from_supernode, via_multicast, mac, dev_addr, dev_desc, peer); + } else { + /* Already in known_peers. */ + time_t now = time(NULL); + + if(!from_supernode) + scan->last_p2p = now; + + if(via_multicast) + scan->local = 1; + + if(((now - scan->last_seen) > 0 /* >= 1 sec */) + ||(cookie > scan->last_cookie)) { + /* Don't register too often */ + check_known_peer_sock_change(eee, from_supernode, via_multicast, mac, dev_addr, dev_desc, peer, now); + } + } +} + +/* ************************************** */ + + +/* Confirm that a pending peer is reachable directly via P2P. + * + * peer must be a pointer to an element of the pending_peers list. + */ +static void peer_set_p2p_confirmed (n2n_edge_t * eee, + const n2n_mac_t mac, + const n2n_cookie_t cookie, + const n2n_sock_t * peer, + time_t now) { + + struct peer_info *scan, *scan_tmp; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + if(scan == NULL) { + scan = find_peer_by_sock(peer, eee->pending_peers); + // in case of MAC change, reset last_local_reg to allow re-registration + if(scan) + scan->last_cookie = N2N_NO_REG_COOKIE; + } + + if(scan) { + HASH_DEL(eee->pending_peers, scan); + + scan_tmp = find_peer_by_sock(peer, eee->known_peers); + if(scan_tmp != NULL) { + HASH_DEL(eee->known_peers, scan_tmp); + free(scan); + scan = scan_tmp; + memcpy(scan->mac_addr, mac, sizeof(n2n_mac_t)); + // in case of MAC change, reset cookie to allow immediate re-registration + scan->last_cookie = N2N_NO_REG_COOKIE; + } else { + // update sock but ... + // ... ignore ACKs's (and their socks) from lower ranked inbound ways for a while + if(((now - scan->last_seen) > REGISTRATION_TIMEOUT / 4) + ||(cookie > scan->last_cookie)) { + scan->sock = *peer; + scan->last_cookie = cookie; + } + } + + HASH_ADD_PEER(eee->known_peers, scan); + scan->last_p2p = now; + + traceEvent(TRACE_DEBUG, "p2p connection established: %s [%s]", + macaddr_str(mac_buf, mac), + sock_to_cstr(sockbuf, peer)); + + traceEvent(TRACE_DEBUG, "new peer %s [%s]", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf, &(scan->sock))); + + traceEvent(TRACE_DEBUG, "pending peers list size=%u", + HASH_COUNT(eee->pending_peers)); + + traceEvent(TRACE_DEBUG, "known peers list size=%u", + HASH_COUNT(eee->known_peers)); + + scan->last_seen = now; + } else + traceEvent(TRACE_DEBUG, "failed to find sender in pending_peers"); +} + + +/* ************************************** */ + + +// provides the current / a new local auth token +static int get_local_auth (n2n_edge_t *eee, n2n_auth_t *auth) { + + switch(eee->conf.auth.scheme) { + case n2n_auth_simple_id: + memcpy(auth, &(eee->conf.auth), sizeof(n2n_auth_t)); + break; + case n2n_auth_user_password: + // start from the locally stored complete auth token (including type and size fields) + memcpy(auth, &(eee->conf.auth), sizeof(n2n_auth_t)); + + // the token data consists of + // 32 bytes public key + // 16 bytes random challenge + + // generate a new random auth challenge every time + memrnd(auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE); + // store it in local auth token (for comparison later) + memcpy(eee->conf.auth.token + N2N_PRIVATE_PUBLIC_KEY_SIZE, auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE); + // encrypt the challenge for transmission + speck_128_encrypt(auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)eee->conf.shared_secret_ctx); + break; + default: + break; + } + + return 0; +} + + +// handles a returning (remote) auth token, takes action as required by auth scheme +static int handle_remote_auth (n2n_edge_t *eee, struct peer_info *peer, const n2n_auth_t *remote_auth) { + + uint8_t tmp_token[N2N_AUTH_MAX_TOKEN_SIZE]; + + switch(eee->conf.auth.scheme) { + case n2n_auth_simple_id: + // no action required + break; + case n2n_auth_user_password: + memcpy(tmp_token, remote_auth->token, N2N_AUTH_PW_TOKEN_SIZE); + + // the returning token data consists of + // 16 bytes double-encrypted challenge + // 16 bytes public key (second half) + // 16 bytes encrypted (original random challenge XOR shared secret XOR dynamic key) + + // decrypt double-encrypted received challenge (first half of public key field) + speck_128_decrypt(tmp_token, (speck_context_t*)eee->conf.shared_secret_ctx); + speck_128_decrypt(tmp_token, (speck_context_t*)eee->conf.shared_secret_ctx); + + // compare to original challenge + if(0 != memcmp(tmp_token, eee->conf.auth.token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE)) + return -1; + + // decrypt the received challenge in which the dynamic key is wrapped + speck_128_decrypt(tmp_token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)eee->conf.shared_secret_ctx); + // un-XOR the original challenge + memxor(tmp_token + N2N_PRIVATE_PUBLIC_KEY_SIZE, eee->conf.auth.token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE); + // un-XOR the shared secret + memxor(tmp_token + N2N_PRIVATE_PUBLIC_KEY_SIZE, *(eee->conf.shared_secret), N2N_AUTH_CHALLENGE_SIZE); + // setup for use as dynamic key + packet_header_change_dynamic_key(tmp_token + N2N_PRIVATE_PUBLIC_KEY_SIZE, + &(eee->conf.header_encryption_ctx_dynamic), + &(eee->conf.header_iv_ctx_dynamic)); + break; + default: + break; + } + + return 0; +} + + +/* ************************************** */ + + +int is_empty_ip_address (const n2n_sock_t * sock) { + + const uint8_t * ptr = NULL; + size_t len = 0; + size_t i; + + if(AF_INET6 == sock->family) { + ptr = sock->addr.v6; + len = 16; + } else { + ptr = sock->addr.v4; + len = 4; + } + + for(i = 0; i < len; ++i) { + if(0 != ptr[i]) { + /* found a non-zero byte in address */ + return 0; + } + } + + return 1; +} + +/* ************************************** */ + + +/** Check if a known peer socket has changed and possibly register again. + */ +static void check_known_peer_sock_change (n2n_edge_t *eee, + uint8_t from_supernode, + uint8_t via_multicast, + const n2n_mac_t mac, + const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, + const n2n_sock_t *peer, + time_t when) { + + struct peer_info *scan; + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ + macstr_t mac_buf; + + if(is_empty_ip_address(peer)) + return; + + if(is_multi_broadcast(mac)) + return; + + /* Search the peer in known_peers */ + HASH_FIND_PEER(eee->known_peers, mac, scan); + + if(!scan) + /* Not in known_peers */ + return; + + if(!sock_equal(&(scan->sock), peer)) { + if(!from_supernode) { + /* This is a P2P packet */ + traceEvent(TRACE_NORMAL, "peer %s changed [%s] -> [%s]", + macaddr_str(mac_buf, scan->mac_addr), + sock_to_cstr(sockbuf1, &(scan->sock)), + sock_to_cstr(sockbuf2, peer)); + /* The peer has changed public socket. It can no longer be assumed to be reachable. */ + HASH_DEL(eee->known_peers, scan); + free(scan); + + register_with_new_peer(eee, from_supernode, via_multicast, mac, dev_addr, dev_desc, peer); + } else { + /* Don't worry about what the supernode reports, it could be seeing a different socket. */ + } + } else + scan->last_seen = when; +} + +/* ************************************** */ + +/** Send a datagram to a socket file descriptor */ +static ssize_t sendto_fd (n2n_edge_t *eee, const void *buf, + size_t len, struct sockaddr_in *dest) { + + ssize_t sent = 0; + int rc = 1; + + // if required (tcp), wait until writeable as soket is set to O_NONBLOCK, could require + // some wait time directly after re-opening + if(eee->conf.connect_tcp) { + fd_set socket_mask; + struct timeval wait_time; + + FD_ZERO(&socket_mask); + FD_SET(eee->sock, &socket_mask); + wait_time.tv_sec = 0; + wait_time.tv_usec = 500000; + rc = select(eee->sock + 1, NULL, &socket_mask, NULL, &wait_time); + } + + if(rc > 0) { + + sent = sendto(eee->sock, buf, len, 0 /*flags*/, + (struct sockaddr *)dest, sizeof(struct sockaddr_in)); + + if((sent <= 0) && (errno)) { + char * c = strerror(errno); + // downgrade to TRACE_DEBUG in case of custom AF_INVALID, i.e. supernode not resolved yet + if(errno == EAFNOSUPPORT /* 93 */) { + traceEvent(TRACE_DEBUG, "sendto failed (%d) %s", errno, c); +#ifdef WIN32 + traceEvent(TRACE_DEBUG, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + } else { + traceEvent(TRACE_WARNING, "sendto failed (%d) %s", errno, c); +#ifdef WIN32 + traceEvent(TRACE_WARNING, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + } + + if(eee->conf.connect_tcp) { + supernode_disconnect(eee); + eee->sn_wait = 1; + traceEvent(TRACE_DEBUG, "disconnected supernode due to sendto() error"); + return -1; + } + } else { + traceEvent(TRACE_DEBUG, "sent=%d to ", (signed int)sent); + } + } else { + supernode_disconnect(eee); + eee->sn_wait = 1; + traceEvent(TRACE_DEBUG, "disconnected supernode due to select() timeout"); + return -1; + } + return sent; +} + + +/** Send a datagram to a socket defined by a n2n_sock_t */ +static ssize_t sendto_sock (n2n_edge_t *eee, const void * buf, + size_t len, const n2n_sock_t * dest) { + + struct sockaddr_in peer_addr; + ssize_t sent; + int value = 0; + + if(!dest->family) + // invalid socket + return 0; + + if(eee->sock < 0) + // invalid socket file descriptor, e.g. TCP unconnected has fd of '-1' + return 0; + + // network order socket + fill_sockaddr((struct sockaddr *) &peer_addr, sizeof(peer_addr), dest); + + // if the connection is tcp, i.e. not the regular sock... + if(eee->conf.connect_tcp) { + + setsockopt(eee->sock, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); + value = 1; +#ifdef LINUX + setsockopt(eee->sock, IPPROTO_TCP, TCP_CORK, &value, sizeof(value)); +#endif + + // prepend packet length... + uint16_t pktsize16 = htobe16(len); + sent = sendto_fd(eee, (uint8_t*)&pktsize16, sizeof(pktsize16), &peer_addr); + + if(sent <= 0) + return -1; + // ...before sending the actual data + } + sent = sendto_fd(eee, buf, len, &peer_addr); + + // if the connection is tcp, i.e. not the regular sock... + if(eee->conf.connect_tcp) { + value = 1; /* value should still be set to 1 */ + setsockopt(eee->sock, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); +#ifdef LINUX + value = 0; + setsockopt(eee->sock, IPPROTO_TCP, TCP_CORK, &value, sizeof(value)); +#endif + } + + return sent; +} + + +/* ************************************** */ + + +/* Bind eee->udp_multicast_sock to multicast group */ +static void check_join_multicast_group (n2n_edge_t *eee) { + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if((eee->conf.allow_p2p) + && (eee->conf.preferred_sock.family == (uint8_t)AF_INVALID)) { + if(!eee->multicast_joined) { + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = inet_addr(N2N_MULTICAST_GROUP); +#ifdef WIN32 + dec_ip_str_t ip_addr; + get_best_interface_ip(eee, ip_addr); + mreq.imr_interface.s_addr = inet_addr(ip_addr); +#else + mreq.imr_interface.s_addr = htonl(INADDR_ANY); +#endif + + if(setsockopt(eee->udp_multicast_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { + traceEvent(TRACE_WARNING, "failed to bind to local multicast group %s:%u [errno %u]", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT, errno); + +#ifdef WIN32 + traceEvent(TRACE_WARNING, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + } else { + traceEvent(TRACE_NORMAL, "successfully joined multicast group %s:%u", + N2N_MULTICAST_GROUP, N2N_MULTICAST_PORT); + eee->multicast_joined = 1; + } + } + } +#endif +} + +/* ************************************** */ + +/** Send a QUERY_PEER packet to the current supernode. */ +void send_query_peer (n2n_edge_t * eee, + const n2n_mac_t dst_mac) { + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + n2n_common_t cmn = {0}; + n2n_QUERY_PEER_t query = {0}; + struct peer_info *peer, *tmp; + int n_o_pings = 0; + int n_o_top_sn = 0; + int n_o_rest_sn = 0; + int n_o_skip_sn = 0; + + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_query_peer; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + idx = 0; + encode_mac(query.srcMac, &idx, eee->device.mac_addr); + + idx = 0; + encode_mac(query.targetMac, &idx, dst_mac); + + idx = 0; + encode_QUERY_PEER(pktbuf, &idx, &cmn, &query); + + if(!is_null_mac(dst_mac)) { + + traceEvent(TRACE_DEBUG, "send QUERY_PEER to supernode"); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + } + + sendto_sock(eee, pktbuf, idx, &(eee->curr_sn->sock)); + + } else { + traceEvent(TRACE_DEBUG, "send PING to supernodes"); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + } + + n_o_pings = eee->conf.number_max_sn_pings; + eee->conf.number_max_sn_pings = NUMBER_SN_PINGS_REGULAR; + + // ping the 'floor(n/2)' top supernodes and 'ceiling(n/2)' of the remaining + n_o_top_sn = n_o_pings >> 1; + n_o_rest_sn = (n_o_pings + 1) >> 1; + + // skip a random number of supernodes between top and remaining + n_o_skip_sn = HASH_COUNT(eee->conf.supernodes) - n_o_pings; + n_o_skip_sn = (n_o_skip_sn < 0) ? 0 : n2n_rand_sqr(n_o_skip_sn); + HASH_ITER(hh, eee->conf.supernodes, peer, tmp) { + if(n_o_top_sn) { + n_o_top_sn--; + // fall through (send to top supernode) + } else if(n_o_skip_sn) { + n_o_skip_sn--; + // skip (do not send) + continue; + } else if(n_o_rest_sn) { + n_o_rest_sn--; + // fall through (send to remaining supernode) + } else { + // done with the remaining (do not send anymore) + break; + } + sendto_sock(eee, pktbuf, idx, &(peer->sock)); + } + } +} + +/* ******************************************************** */ + +/** Send a REGISTER_SUPER packet to the current supernode. */ +void send_register_super (n2n_edge_t *eee) { + + uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0}; + uint8_t hash_buf[16] = {0}; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_SUPER_t reg; + n2n_sock_str_t sockbuf; + + memset(&cmn, 0, sizeof(cmn)); + memset(®, 0, sizeof(reg)); + + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_register_super; + if(eee->conf.preferred_sock.family == (uint8_t)AF_INVALID) { + cmn.flags = 0; + } else { + cmn.flags = N2N_FLAGS_SOCKET; + memcpy(&(reg.sock), &(eee->conf.preferred_sock), sizeof(n2n_sock_t)); + } + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + eee->curr_sn->last_cookie = n2n_rand(); + + reg.cookie = eee->curr_sn->last_cookie; + reg.dev_addr.net_addr = ntohl(eee->device.ip_addr); + reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask)); + memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE); + get_local_auth(eee, &(reg.auth)); + + idx = 0; + encode_mac(reg.edgeMac, &idx, eee->device.mac_addr); + + idx = 0; + encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®); + + traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to [%s]", + sock_to_cstr(sockbuf, &(eee->curr_sn->sock))); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_static, eee->conf.header_iv_ctx_static, + time_stamp()); + + if(eee->conf.shared_secret) { + pearson_hash_128(hash_buf, pktbuf, idx); + speck_128_encrypt(hash_buf, (speck_context_t*)eee->conf.shared_secret_ctx); + encode_buf(pktbuf, &idx, hash_buf, N2N_REG_SUP_HASH_CHECK_LEN); + } + } + + /* sent = */ sendto_sock(eee, pktbuf, idx, &(eee->curr_sn->sock)); +} + + +static void send_unregister_super (n2n_edge_t *eee) { + + uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0}; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_UNREGISTER_SUPER_t unreg; + n2n_sock_str_t sockbuf; + + memset(&cmn, 0, sizeof(cmn)); + memset(&unreg, 0, sizeof(unreg)); + + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_unregister_super; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + get_local_auth(eee, &(unreg.auth)); + + idx = 0; + encode_mac(unreg.srcMac, &idx, eee->device.mac_addr); + + idx = 0; + encode_UNREGISTER_SUPER(pktbuf, &idx, &cmn, &unreg); + + traceEvent(TRACE_DEBUG, "send UNREGISTER_SUPER to [%s]", + sock_to_cstr(sockbuf, &(eee->curr_sn->sock))); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + + /* sent = */ sendto_sock(eee, pktbuf, idx, &(eee->curr_sn->sock)); + +} + + +static int sort_supernodes (n2n_edge_t *eee, time_t now) { + + struct peer_info *scan, *tmp; + + if(now - eee->last_sweep > SWEEP_TIME) { + // this routine gets periodically called + + if(!eee->sn_wait) { + // sort supernodes in ascending order of their selection_criterion fields + sn_selection_sort(&(eee->conf.supernodes)); + } + + if(eee->curr_sn != eee->conf.supernodes) { + // we have not been connected to the best/top one + send_unregister_super(eee); + eee->curr_sn = eee->conf.supernodes; + reset_sup_attempts(eee); + supernode_connect(eee); + + traceEvent(TRACE_INFO, "registering with supernode [%s][number of supernodes %d][attempts left %u]", + supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts); + + send_register_super(eee); + eee->last_register_req = now; + eee->sn_wait = 1; + } + + HASH_ITER(hh, eee->conf.supernodes, scan, tmp) { + if(scan == eee->curr_sn) + sn_selection_criterion_good(&(scan->selection_criterion)); + else + sn_selection_criterion_default(&(scan->selection_criterion)); + } + sn_selection_criterion_common_data_default(eee); + + // send PING to all the supernodes + if(!eee->conf.connect_tcp) + send_query_peer(eee, null_mac); + eee->last_sweep = now; + + // no answer yet (so far, unused in regular edge code; mainly used during bootstrap loading) + eee->sn_pong = 0; + } + + return 0; /* OK */ +} + +/** Send a REGISTER packet to another edge. */ +static void send_register (n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_mac_t peer_mac, + const n2n_cookie_t cookie) { + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_t reg; + n2n_sock_str_t sockbuf; + + if(!eee->conf.allow_p2p) { + traceEvent(TRACE_DEBUG, "skipping register as P2P is disabled"); + return; + } + + memset(&cmn, 0, sizeof(cmn)); + memset(®, 0, sizeof(reg)); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_register; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + reg.cookie = cookie; + idx = 0; + encode_mac(reg.srcMac, &idx, eee->device.mac_addr); + + if(peer_mac) { + // can be NULL for multicast registrations + idx = 0; + encode_mac(reg.dstMac, &idx, peer_mac); + } + reg.dev_addr.net_addr = ntohl(eee->device.ip_addr); + reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask)); + memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE); + + idx = 0; + encode_REGISTER(pktbuf, &idx, &cmn, ®); + + traceEvent(TRACE_INFO, "send REGISTER to [%s]", + sock_to_cstr(sockbuf, remote_peer)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + + /* sent = */ sendto_sock(eee, pktbuf, idx, remote_peer); +} + +/* ************************************** */ + +/** Send a REGISTER_ACK packet to a peer edge. */ +static void send_register_ack (n2n_edge_t * eee, + const n2n_sock_t * remote_peer, + const n2n_REGISTER_t * reg) { + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_ACK_t ack; + n2n_sock_str_t sockbuf; + + if(!eee->conf.allow_p2p) { + traceEvent(TRACE_DEBUG, "skipping register ACK as P2P is disabled"); + return; + } + + memset(&cmn, 0, sizeof(cmn)); + memset(&ack, 0, sizeof(reg)); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_register_ack; + cmn.flags = 0; + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + memset(&ack, 0, sizeof(ack)); + ack.cookie = reg->cookie; + memcpy(ack.srcMac, eee->device.mac_addr, N2N_MAC_SIZE); + memcpy(ack.dstMac, reg->srcMac, N2N_MAC_SIZE); + + idx = 0; + encode_REGISTER_ACK(pktbuf, &idx, &cmn, &ack); + + traceEvent(TRACE_INFO, "send REGISTER_ACK to [%s]", + sock_to_cstr(sockbuf, remote_peer)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt(pktbuf, idx, idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + + /* sent = */ sendto_sock(eee, pktbuf, idx, remote_peer); +} + +/* ************************************** */ + +static char gratuitous_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* dest MAC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* src MAC */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* hw Size */ + 0x04, /* protocol Size */ + 0x00, 0x02, /* ARP reply */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* src MAC */ + 0x00, 0x00, 0x00, 0x00, /* src IP */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* target MAC */ + 0x00, 0x00, 0x00, 0x00 /* target IP */ +}; + +// build a gratuitous ARP packet */ +static int build_gratuitous_arp (n2n_edge_t * eee, char *buffer, uint16_t buffer_len) { + + if(buffer_len < sizeof(gratuitous_arp)) return(-1); + + memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); + memcpy(&buffer[6], eee->device.mac_addr, 6); + memcpy(&buffer[22], eee->device.mac_addr, 6); + memcpy(&buffer[28], &(eee->device.ip_addr), 4); + memcpy(&buffer[38], &(eee->device.ip_addr), 4); + + return(sizeof(gratuitous_arp)); +} + +/** Called from update_supernode_reg to periodically send gratuitous ARP + * broadcasts. */ +static void send_grat_arps (n2n_edge_t * eee) { + + uint8_t buffer[48]; + size_t len; + + traceEvent(TRACE_DEBUG, "sending gratuitous ARP..."); + len = build_gratuitous_arp(eee, (char*)buffer, sizeof(buffer)); + + edge_send_packet2net(eee, buffer, len); + edge_send_packet2net(eee, buffer, len); /* Two is better than one :-) */ +} + +/* ************************************** */ + +/** @brief Check to see if we should re-register with the supernode. + * + * This is frequently called by the main loop. + */ +void update_supernode_reg (n2n_edge_t * eee, time_t now) { + + struct peer_info *peer, *tmp_peer; + int cnt = 0; + int off = 0; + + if((eee->sn_wait && (now > (eee->last_register_req + (eee->conf.register_interval / 10)))) + ||(eee->sn_wait == 2)) /* immediately re-register in case of RE_REGISTER_SUPER */ { + /* fall through */ + traceEvent(TRACE_DEBUG, "update_supernode_reg: doing fast retry."); + } else if(now < (eee->last_register_req + eee->conf.register_interval)) + return; /* Too early */ + + // determine time offset to apply on last_register_req for + // all edges's next re-registration does not happen all at once + if(eee->sn_wait == 2) { + // remaining 1/4 is greater than 1/10 fast retry allowance; + // '%' might be expensive but does not happen all too often + off = n2n_rand() % ((eee->conf.register_interval * 3) / 4); + } + + check_join_multicast_group(eee); + + if(0 == eee->sup_attempts) { + /* Give up on that supernode and try the next one. */ + sn_selection_criterion_bad(&(eee->curr_sn->selection_criterion)); + sn_selection_sort(&(eee->conf.supernodes)); + eee->curr_sn = eee->conf.supernodes; + traceEvent(TRACE_WARNING, "supernode not responding, now trying [%s]", supernode_ip(eee)); + supernode_connect(eee); + reset_sup_attempts(eee); + // trigger out-of-schedule DNS resolution + eee->resolution_request = 1; + + // in some multi-NATed scenarios communication gets stuck on losing connection to supernode + // closing and re-opening the socket allows for re-establishing communication + // this can only be done, if working on some unprivileged port and/or having sufficent + // privileges. as we are not able to check for sufficent privileges here, we only do it + // if port is sufficently high or unset. uncovered: privileged port and sufficent privileges + if((eee->conf.local_port == 0) || (eee->conf.local_port > 1024)) { + // do not explicitly disconnect every time as the condition described is rare, so ... + // ... check that there are no external peers (indicating a working socket) ... + HASH_ITER(hh, eee->known_peers, peer, tmp_peer) + if(!peer->local) { + cnt++; + break; + } + if(!cnt) { + // ... and then count the connection retries + (eee->close_socket_counter)++; + if(eee->close_socket_counter >= N2N_CLOSE_SOCKET_COUNTER_MAX) { + eee->close_socket_counter = 0; + supernode_disconnect(eee); + traceEvent(TRACE_DEBUG, "disconnected supernode"); + } + } + + supernode_connect(eee); + traceEvent(TRACE_DEBUG, "reconnected to supernode"); + } + + } else { + --(eee->sup_attempts); + } + +#ifndef HAVE_PTHREAD + if(supernode2sock(&(eee->curr_sn->sock), eee->curr_sn->ip_addr) == 0) { +#endif + traceEvent(TRACE_INFO, "registering with supernode [%s][number of supernodes %d][attempts left %u]", + supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts); + + send_register_super(eee); +#ifndef HAVE_PTHREAD + } +#endif + + register_with_local_peers(eee); + + // if supernode repeatedly not responding (already waiting), safeguard the + // current known connections to peers by re-registering + if(eee->sn_wait == 1) + HASH_ITER(hh, eee->known_peers, peer, tmp_peer) + if((now - peer->last_seen) > REGISTER_SUPER_INTERVAL_DFL) + send_register(eee, &(peer->sock), peer->mac_addr, peer->last_cookie); + + eee->sn_wait = 1; + + eee->last_register_req = now - off; +} + +/* ************************************** */ + +/** Return the IP address of the current supernode in the ring. */ +static const char * supernode_ip (const n2n_edge_t * eee) { + + return (eee->curr_sn->ip_addr); +} + +/* ************************************** */ + +/** A PACKET has arrived containing an encapsulated ethernet datagram - usually + * encrypted. */ +static int handle_PACKET (n2n_edge_t * eee, + const uint8_t from_supernode, + const n2n_PACKET_t * pkt, + const n2n_sock_t * orig_sender, + uint8_t * payload, + size_t psize) { + + ssize_t data_sent_len; + uint8_t * eth_payload = NULL; + int retval = -1; + time_t now; + ether_hdr_t * eh; + ipstr_t ip_buf; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + now = time(NULL); + + traceEvent(TRACE_DEBUG, "handle_PACKET size %u transform %u", + (unsigned int)psize, (unsigned int)pkt->transform); + /* hexdump(payload, psize); */ + + if(from_supernode) { + if(is_multi_broadcast(pkt->dstMac)) + ++(eee->stats.rx_sup_broadcast); + + ++(eee->stats.rx_sup); + eee->last_sup = now; + } else { + ++(eee->stats.rx_p2p); + eee->last_p2p=now; + } + + /* Handle transform. */ + { + uint8_t decodebuf[N2N_PKT_BUF_SIZE]; + size_t eth_size; + n2n_transform_t rx_transop_id; + uint8_t rx_compression_id; + + rx_transop_id = (n2n_transform_t)pkt->transform; + rx_compression_id = pkt->compression; + + if(rx_transop_id == eee->conf.transop_id) { + uint8_t is_multicast; + eth_payload = decodebuf; + eh = (ether_hdr_t*)eth_payload; + eth_size = eee->transop.rev(&eee->transop, + eth_payload, N2N_PKT_BUF_SIZE, + payload, psize, pkt->srcMac); + ++(eee->transop.rx_cnt); /* stats */ + + /* decompress if necessary */ + uint8_t * deflation_buffer = 0; + lzo_uint deflated_len; + switch(rx_compression_id) { + case N2N_COMPRESSION_ID_NONE: + break; // continue afterwards + + case N2N_COMPRESSION_ID_LZO: + deflation_buffer = malloc(N2N_PKT_BUF_SIZE); + lzo1x_decompress(eth_payload, eth_size, deflation_buffer, &deflated_len, NULL); + break; +#ifdef N2N_HAVE_ZSTD + case N2N_COMPRESSION_ID_ZSTD: + deflated_len = N2N_PKT_BUF_SIZE; + deflation_buffer = malloc(deflated_len); + deflated_len = ZSTD_decompress(deflation_buffer, deflated_len, eth_payload, eth_size); + if(ZSTD_isError(deflated_len)) { + traceEvent(TRACE_WARNING, "payload decompression failed with zstd error '%s'.", + ZSTD_getErrorName(deflated_len)); + free(deflation_buffer); + return(-1); // cannot help it + } + break; +#endif + default: + traceEvent(TRACE_WARNING, "payload decompression failed: received packet indicating unsupported %s compression.", + compression_str(rx_compression_id)); + return(-1); // cannot handle it + } + + if(rx_compression_id != N2N_COMPRESSION_ID_NONE) { + traceEvent(TRACE_DEBUG, "payload decompression %s: deflated %u bytes to %u bytes", + compression_str(rx_compression_id), eth_size, (int)deflated_len); + memcpy(eth_payload,deflation_buffer, deflated_len ); + eth_size = deflated_len; + free(deflation_buffer); + } + + is_multicast = (is_ip6_discovery(eth_payload, eth_size) || is_ethMulticast(eth_payload, eth_size)); + + if(eee->conf.drop_multicast && is_multicast) { + traceEvent(TRACE_INFO, "dropping RX multicast"); + return(-1); + } else if((!eee->conf.allow_routing) && (!is_multicast)) { + /* Check if it is a routed packet */ + + if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) { + uint32_t *dst = (uint32_t*)ð_payload[ETH_FRAMESIZE + IP4_DSTOFFSET]; + uint8_t *dst_mac = (uint8_t*)eth_payload; + + /* Note: all elements of the_ip are in network order */ + if(!memcmp(dst_mac, broadcast_mac, N2N_MAC_SIZE)) + traceEvent(TRACE_DEBUG, "RX broadcast packet destined to [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + else if((*dst != eee->device.ip_addr)) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "discarding routed packet destined to [%s]", + intoa(ntohl(*dst), ip_buf, sizeof(ip_buf))); + return(-1); + } else { + /* This packet is directed to us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + if(eee->network_traffic_filter->filter_packet_from_peer(eee->network_traffic_filter, eee, orig_sender, + eth_payload, eth_size) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "filtered packet of size %u", (unsigned int)eth_size); + return(0); + } + + if(eee->cb.packet_from_peer) { + uint16_t tmp_eth_size = eth_size; + if(eee->cb.packet_from_peer(eee, orig_sender, eth_payload, &tmp_eth_size) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "DROP packet of size %u", (unsigned int)eth_size); + return(0); + } + eth_size = tmp_eth_size; + } + + /* Write ethernet packet to tap device. */ + traceEvent(TRACE_DEBUG, "sending data of size %u to TAP", (unsigned int)eth_size); + data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size); + + if(data_sent_len == eth_size) { + retval = 0; + } + } else { + traceEvent(TRACE_WARNING, "invalid transop ID: expected %s (%u), got %s (%u) from %s [%s]", + transop_str(eee->conf.transop_id), eee->conf.transop_id, + transop_str(rx_transop_id), rx_transop_id, + macaddr_str(mac_buf, pkt->srcMac), + sock_to_cstr(sockbuf, orig_sender)); + } + } + + return retval; +} + +/* ************************************** */ + + +#if 0 +#ifndef WIN32 + +static char *get_ip_from_arp (dec_ip_str_t buf, const n2n_mac_t req_mac) { + + FILE *fd; + dec_ip_str_t ip_str = {'\0'}; + char dev_str[N2N_IFNAMSIZ] = {'\0'}; + macstr_t mac_str = {'\0'}; + n2n_mac_t mac = {'\0'}; + + strncpy(buf, "0.0.0.0", N2N_NETMASK_STR_SIZE - 1); + + if(is_null_mac(req_mac)) { + traceEvent(TRACE_DEBUG, "MAC address is null."); + return buf; + } + + if(!(fd = fopen("/proc/net/arp", "r"))) { + traceEvent(TRACE_WARNING, "could not open arp table: %d - %s", errno, strerror(errno)); + return buf; + } + + while(!feof(fd) && fgetc(fd) != '\n'); + while(!feof(fd) && (fscanf(fd, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %15s", ip_str, mac_str, dev_str) == 3)) { + str2mac(mac, mac_str); + if(0 == memcmp(mac, req_mac, sizeof(n2n_mac_t))) { + strncpy(buf, ip_str, N2N_NETMASK_STR_SIZE - 1); + break; + } + } + fclose(fd); + + return buf; +} + +#endif +#endif + +/** Read a datagram from the management UDP socket and take appropriate + * action. */ +static void readFromMgmtSocket (n2n_edge_t *eee) { + + char udp_buf[N2N_PKT_BUF_SIZE]; /* Compete UDP packet */ + ssize_t recvlen; + /* ssize_t sendlen; */ + struct sockaddr_in sender_sock; + socklen_t i; + size_t msg_len; + time_t now; + struct peer_info *peer, *tmpPeer; + macstr_t mac_buf; + char time_buf[10]; /* 9 digits + 1 terminating zero */ + char uptime_buf[11]; /* 10 digits + 1 terminating zero */ + /* dec_ip_bit_str_t ip_bit_str = {'\0'}; */ + /* dec_ip_str_t ip_str = {'\0'}; */ + in_addr_t net; + n2n_sock_str_t sockbuf; + uint32_t num_pending_peers = 0; + uint32_t num_known_peers = 0; + uint32_t num = 0; + selection_criterion_str_t sel_buf; + + + now = time(NULL); + i = sizeof(sender_sock); + recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0/*flags*/, + (struct sockaddr *) &sender_sock, (socklen_t *) &i); + + if(recvlen < 0) { + traceEvent(TRACE_WARNING, "mgmt recvfrom failed: %d - %s", errno, strerror(errno)); + return; /* failed to receive data from UDP */ + } + + /* avoid parsing any uninitialized junk from the stack */ + udp_buf[recvlen] = 0; + + if((0 == memcmp(udp_buf, "help", 4)) || (0 == memcmp(udp_buf, "?", 1))) { + msg_len = 0; + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "Help for edge management console:\n" + "\tstop | Gracefully exit edge\n" + "\thelp | This help message\n" + "\t+verb | Increase verbosity of logging\n" + "\t-verb | Decrease verbosity of logging\n" + "\tr ... | start query with JSON reply\n" + "\tw ... | start update with JSON reply\n" + "\t | Display statistics\n\n"); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + return; + } + + if(0 == memcmp(udp_buf, "stop", 4)) { + traceEvent(TRACE_NORMAL, "stop command received"); + *eee->keep_running = 0; + return; + } + + if(0 == memcmp(udp_buf, "+verb", 5)) { + msg_len = 0; + setTraceLevel(getTraceLevel() + 1); + + traceEvent(TRACE_NORMAL, "+verb traceLevel=%u", (unsigned int) getTraceLevel()); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "> +OK traceLevel=%u\n", (unsigned int) getTraceLevel()); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + return; + } + + if(0 == memcmp(udp_buf, "-verb", 5)) { + msg_len = 0; + + if(getTraceLevel() > 0) { + setTraceLevel(getTraceLevel() - 1); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "> -OK traceLevel=%u\n", getTraceLevel()); + } else { + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "> -NOK traceLevel=%u\n", getTraceLevel()); + } + + traceEvent(TRACE_NORMAL, "-verb traceLevel=%u", (unsigned int) getTraceLevel()); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + return; + } + + if((udp_buf[0] == 'r' || udp_buf[0] == 'w') && (udp_buf[1] == ' ')) { + /* this is a JSON request */ + handleMgmtJson(eee, udp_buf, sender_sock); + return; + } + + traceEvent(TRACE_DEBUG, "mgmt status requested"); + + msg_len = 0; + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "COMMUNITY '%s'\n\n", + (eee->conf.header_encryption == HEADER_ENCRYPTION_NONE) ? (char*)eee->conf.community_name : "-- header encrypted --"); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + " ### | TAP | MAC | EDGE | HINT | LAST SEEN | UPTIME\n"); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "=============================================================================================================\n"); + + // dump nodes with forwarding through supernodes + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "SUPERNODE FORWARD\n"); + num = 0; + HASH_ITER(hh, eee->pending_peers, peer, tmpPeer) { + ++num_pending_peers; + net = htonl(peer->dev_addr.net_addr); + snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->last_seen)); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n", + ++num, + (peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(struct in_addr *) &net), + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + (peer->last_seen) ? time_buf : ""); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + msg_len = 0; + } + + // dump peer-to-peer nodes + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "-------------------------------------------------------------------------------------------------------------\n"); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "PEER TO PEER\n"); + num = 0; + HASH_ITER(hh, eee->known_peers, peer, tmpPeer) { + ++num_known_peers; + net = htonl(peer->dev_addr.net_addr); + snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->last_seen)); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "%4u | %-15s | %-17s | %-21s | %-15s | %9s |\n", + ++num, + (peer->dev_addr.net_addr == 0) ? "" : inet_ntoa(*(struct in_addr *) &net), + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + (peer->last_seen) ? time_buf : ""); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + msg_len = 0; + } + + // dump supernodes + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "-------------------------------------------------------------------------------------------------------------\n"); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "SUPERNODES\n"); + HASH_ITER(hh, eee->conf.supernodes, peer, tmpPeer) { + net = htonl(peer->dev_addr.net_addr); + snprintf(time_buf, sizeof(time_buf), "%9u", (unsigned int)(now - peer->last_seen)); + snprintf(uptime_buf, sizeof(uptime_buf), "%10u", (unsigned int)(peer->uptime)); + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "%-19s %1s%1s | %-17s | %-21s | %-15s | %9s | %10s\n", + peer->version, + (peer->purgeable == SN_UNPURGEABLE) ? "l" : "", + (peer == eee->curr_sn) ? (eee->sn_wait ? "." : "*" ) : "", + is_null_mac(peer->mac_addr) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + sn_selection_criterion_str(eee, sel_buf, peer), + (peer->last_seen) ? time_buf : "", + (peer->uptime) ? uptime_buf : ""); + + sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + msg_len = 0; + } + + // further stats + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "=============================================================================================================\n"); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "uptime %lu | ", + time(NULL) - eee->start_time); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "pend_peers %u | ", + num_pending_peers); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "known_peers %u | ", + num_known_peers); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "transop %u,%u\n", + (unsigned int) eee->transop.tx_cnt, + (unsigned int) eee->transop.rx_cnt); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "super %u,%u | ", + (unsigned int) eee->stats.tx_sup, + (unsigned int) eee->stats.rx_sup); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "p2p %u,%u\n", + (unsigned int) eee->stats.tx_p2p, + (unsigned int) eee->stats.rx_p2p); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "last_super %ld sec ago | ", + (now - eee->last_sup)); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "last_p2p %ld sec ago\n", + (now - eee->last_p2p)); + + msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), + "\nType \"help\" to see more commands.\n\n"); + + /* sendlen = */ sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + + +/* ************************************** */ + +static int check_query_peer_info (n2n_edge_t *eee, time_t now, n2n_mac_t mac) { + + struct peer_info *scan; + + HASH_FIND_PEER(eee->pending_peers, mac, scan); + + if(!scan) { + scan = calloc(1, sizeof(struct peer_info)); + + memcpy(scan->mac_addr, mac, N2N_MAC_SIZE); + scan->timeout = eee->conf.register_interval; /* TODO: should correspond to the peer supernode registration timeout */ + scan->last_seen = now; /* Don't change this it marks the pending peer for removal. */ + scan->last_valid_time_stamp = initial_time_stamp(); + + HASH_ADD_PEER(eee->pending_peers, scan); + } + + if(now - scan->last_sent_query > eee->conf.register_interval) { + send_register(eee, &(eee->curr_sn->sock), mac, N2N_FORWARDED_REG_COOKIE); + send_query_peer(eee, scan->mac_addr); + scan->last_sent_query = now; + return(0); + } + + return(1); +} + +/* ************************************** */ + +/* @return 1 if destination is a peer, 0 if destination is supernode */ +static int find_peer_destination (n2n_edge_t * eee, + n2n_mac_t mac_address, + n2n_sock_t * destination) { + + struct peer_info *scan; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + int retval = 0; + time_t now = time(NULL); + + if(is_multi_broadcast(mac_address)) { + traceEvent(TRACE_DEBUG, "multicast or broadcast destination peer, using supernode"); + memcpy(destination, &(eee->curr_sn->sock), sizeof(struct sockaddr_in)); + return(0); + } + + traceEvent(TRACE_DEBUG, "searching destination socket for %s", + macaddr_str(mac_buf, mac_address)); + + HASH_FIND_PEER(eee->known_peers, mac_address, scan); + + if(scan && (scan->last_seen > 0)) { + if((now - scan->last_p2p) >= (scan->timeout / 2)) { + /* Too much time passed since we saw the peer, need to register again + * since the peer address may have changed. */ + traceEvent(TRACE_DEBUG, "refreshing idle known peer"); + HASH_DEL(eee->known_peers, scan); + free(scan); + /* NOTE: registration will be performed upon the receival of the next response packet */ + } else { + /* Valid known peer found */ + memcpy(destination, &scan->sock, sizeof(n2n_sock_t)); + retval = 1; + } + } + + if(retval == 0) { + memcpy(destination, &(eee->curr_sn->sock), sizeof(struct sockaddr_in)); + traceEvent(TRACE_DEBUG, "p2p peer %s not found, using supernode", + macaddr_str(mac_buf, mac_address)); + + check_query_peer_info(eee, now, mac_address); + } + + traceEvent(TRACE_DEBUG, "found peer's socket %s [%s]", + macaddr_str(mac_buf, mac_address), + sock_to_cstr(sockbuf, destination)); + + return retval; +} + +/* ***************************************************** */ + +/** Send an ecapsulated ethernet PACKET to a destination edge or broadcast MAC + * address. */ +static int send_packet (n2n_edge_t * eee, + n2n_mac_t dstMac, + const uint8_t * pktbuf, + size_t pktlen) { + + int is_p2p; + /*ssize_t s; */ + n2n_sock_str_t sockbuf; + n2n_sock_t destination; + macstr_t mac_buf; + struct peer_info *peer, *tmp_peer; + + /* hexdump(pktbuf, pktlen); */ + + is_p2p = find_peer_destination(eee, dstMac, &destination); + + traceEvent(TRACE_INFO, "Tx PACKET of %u bytes to %s [%s]", + pktlen, macaddr_str(mac_buf, dstMac), + sock_to_cstr(sockbuf, &destination)); + + if(is_p2p) + ++(eee->stats.tx_p2p); + else + ++(eee->stats.tx_sup); + + if(is_multi_broadcast(dstMac)) { + ++(eee->stats.tx_sup_broadcast); + + // if no supernode around, foward the broadcast to all known peers + if(eee->sn_wait) { + HASH_ITER(hh, eee->known_peers, peer, tmp_peer) + /* s = */ sendto_sock(eee, pktbuf, pktlen, &peer->sock); + return 0; + } + // fall through otherwise + } + + /* s = */ sendto_sock(eee, pktbuf, pktlen, &destination); + + return 0; +} + +/* ************************************** */ + +/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ +void edge_send_packet2net (n2n_edge_t * eee, + uint8_t *tap_pkt, size_t len) { + + ipstr_t ip_buf; + n2n_mac_t destMac; + n2n_common_t cmn; + n2n_PACKET_t pkt; + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + n2n_transform_t tx_transop_idx = eee->transop.transform_id; + ether_hdr_t eh; + + /* tap_pkt is not aligned so we have to copy to aligned memory */ + memcpy(&eh, tap_pkt, sizeof(ether_hdr_t)); + + /* Discard IP packets that are not originated by this hosts */ + if(!(eee->conf.allow_routing)) { + if(ntohs(eh.type) == 0x0800) { + /* This is an IP packet from the local source address - not forwarded. */ + uint32_t *src = (uint32_t*)&tap_pkt[ETH_FRAMESIZE + IP4_SRCOFFSET]; + + /* Note: all elements of the_ip are in network order */ + if(*src != eee->device.ip_addr) { + /* This is a packet that needs to be routed */ + traceEvent(TRACE_INFO, "discarding routed packet destined to [%s]", + intoa(ntohl(*src), ip_buf, sizeof(ip_buf))); + return; + } else { + /* This packet is originated by us */ + /* traceEvent(TRACE_INFO, "Sending non-routed packet"); */ + } + } + } + + /* Optionally compress then apply transforms, eg encryption. */ + + /* Once processed, send to destination in PACKET */ + + memcpy(destMac, tap_pkt, N2N_MAC_SIZE); /* dest MAC is first in ethernet header */ + + memset(&cmn, 0, sizeof(cmn)); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags = 0; /* no options, not from supernode, no socket */ + memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE); + + memset(&pkt, 0, sizeof(pkt)); + memcpy(pkt.srcMac, eee->device.mac_addr, N2N_MAC_SIZE); + memcpy(pkt.dstMac, destMac, N2N_MAC_SIZE); + + pkt.transform = tx_transop_idx; + + // compression needs to be tried before encode_PACKET is called for compression indication gets encoded there + pkt.compression = N2N_COMPRESSION_ID_NONE; + + if(eee->conf.compression) { + uint8_t * compression_buffer = NULL; + int32_t compression_len; + + switch(eee->conf.compression) { + case N2N_COMPRESSION_ID_LZO: + compression_buffer = malloc(len + len / 16 + 64 + 3); + if(lzo1x_1_compress(tap_pkt, len, compression_buffer, (lzo_uint*)&compression_len, wrkmem) == LZO_E_OK) { + if(compression_len < len) { + pkt.compression = N2N_COMPRESSION_ID_LZO; + } + } + break; +#ifdef N2N_HAVE_ZSTD + case N2N_COMPRESSION_ID_ZSTD: + compression_len = N2N_PKT_BUF_SIZE + 128; + compression_buffer = malloc(compression_len); // leaves enough room, for exact size call compression_len = ZSTD_compressBound (len); (slower) + compression_len = (int32_t)ZSTD_compress(compression_buffer, compression_len, tap_pkt, len, ZSTD_COMPRESSION_LEVEL); + if(!ZSTD_isError(compression_len)) { + if(compression_len < len) { + pkt.compression = N2N_COMPRESSION_ID_ZSTD; + } + } else { + traceEvent(TRACE_ERROR, "payload compression failed with zstd error '%s'.", + ZSTD_getErrorName(compression_len)); + free(compression_buffer); + // continue with unset without pkt.compression --> will send uncompressed + } + break; +#endif + default: + break; + } + + if(pkt.compression != N2N_COMPRESSION_ID_NONE) { + traceEvent(TRACE_DEBUG, "payload compression [%s]: compressed %u bytes to %u bytes\n", + compression_str(pkt.compression), len, compression_len); + + memcpy(tap_pkt, compression_buffer, compression_len); + len = compression_len; + } + + if(compression_buffer) { + free(compression_buffer); + } + } + + idx = 0; + encode_PACKET(pktbuf, &idx, &cmn, &pkt); + + uint16_t headerIdx = idx; + + idx += eee->transop.fwd(&eee->transop, + pktbuf + idx, N2N_PKT_BUF_SIZE - idx, + tap_pkt, len, pkt.dstMac); + + traceEvent(TRACE_DEBUG, "encode PACKET of %u bytes, %u bytes data, %u bytes overhead, transform %u", + (u_int)idx, (u_int)len, (u_int)(idx - len), tx_transop_idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) + // in case of user-password auth, also encrypt the iv of payload assuming ChaCha20 and SPECK having the same iv size + packet_header_encrypt(pktbuf, headerIdx + (NULL != eee->conf.shared_secret) * min(idx - headerIdx, N2N_SPECK_IVEC_SIZE), idx, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + time_stamp()); + +#ifdef MTU_ASSERT_VALUE + { + const u_int eth_udp_overhead = ETH_FRAMESIZE + IP4_MIN_SIZE + UDP_SIZE; + + // MTU assertion which avoids fragmentation by N2N + assert(idx + eth_udp_overhead <= MTU_ASSERT_VALUE); + } +#endif + + eee->transop.tx_cnt++; /* stats */ + + send_packet(eee, destMac, pktbuf, idx); /* to peer or supernode */ +} + +/* ************************************** */ + +/** Read a single packet from the TAP interface, process it and write out the + * corresponding packet to the cooked socket. + */ +void edge_read_from_tap (n2n_edge_t * eee) { + + /* tun -> remote */ + uint8_t eth_pkt[N2N_PKT_BUF_SIZE]; + macstr_t mac_buf; + ssize_t len; + + len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE ); + if((len <= 0) || (len > N2N_PKT_BUF_SIZE)) { + traceEvent(TRACE_WARNING, "read()=%d [%d/%s]", + (signed int)len, errno, strerror(errno)); + traceEvent(TRACE_WARNING, "TAP I/O operation aborted, restart later."); + sleep(3); + tuntap_close(&(eee->device)); + tuntap_open(&(eee->device), eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode, eee->tuntap_priv_conf.ip_addr, + eee->tuntap_priv_conf.netmask, eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu +#ifdef WIN32 + ,eee->tuntap_priv_conf.metric +#endif + ); + } else { + const uint8_t * mac = eth_pkt; + traceEvent(TRACE_DEBUG, "Rx TAP packet (%4d) for %s", + (signed int)len, macaddr_str(mac_buf, mac)); + + if(eee->conf.drop_multicast && + (is_ip6_discovery(eth_pkt, len) || + is_ethMulticast(eth_pkt, len))) { + traceEvent(TRACE_INFO, "dropping Tx multicast"); + } else { + if(!eee->last_sup) { + // drop packets before first registration with supernode + traceEvent(TRACE_DEBUG, "DROP packet before first registration with supernode"); + return; + } + + if(eee->network_traffic_filter) { + if(eee->network_traffic_filter->filter_packet_from_tap(eee->network_traffic_filter, eee, eth_pkt, + len) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "filtered packet of size %u", (unsigned int)len); + return; + } + } + + if(eee->cb.packet_from_tap) { + uint16_t tmp_len = len; + if(eee->cb.packet_from_tap(eee, eth_pkt, &tmp_len) == N2N_DROP) { + traceEvent(TRACE_DEBUG, "DROP packet of size %u", (unsigned int)len); + return; + } + len = tmp_len; + } + + edge_send_packet2net(eee, eth_pkt, len); + } + } +} + + +/* ************************************** */ + + +/** handle a datagram from the main UDP socket to the internet. */ +void process_udp (n2n_edge_t *eee, const struct sockaddr_in *sender_sock, const SOCKET in_sock, + uint8_t *udp_buf, size_t udp_size, time_t now) { + + n2n_common_t cmn; /* common fields in the packet header */ + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; /* don't clobber sockbuf1 if writing two addresses to trace */ + macstr_t mac_buf1; + macstr_t mac_buf2; + uint8_t hash_buf[16]; + size_t rem; + size_t idx; + size_t msg_type; + uint8_t from_supernode; + uint8_t via_multicast; + peer_info_t *sn = NULL; + n2n_sock_t sender; + n2n_sock_t * orig_sender = NULL; + uint32_t header_enc = 0; + uint64_t stamp = 0; + int skip_add = 0; + + /* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which + * IP transport version the packet arrived on. May need to UDP sockets. */ + + memset(&sender, 0, sizeof(n2n_sock_t)); + + if(eee->conf.connect_tcp) + // TCP expects that we know our comm partner and does not deliver the sender + memcpy(&sender, &(eee->curr_sn->sock), sizeof(struct sockaddr_in)); + else { + sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */ + sender.port = ntohs(sender_sock->sin_port); + memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + } + /* The packet may not have an orig_sender socket spec. So default to last + * hop as sender. */ + orig_sender = &sender; + +#ifdef SKIP_MULTICAST_PEERS_DISCOVERY + via_multicast = 0; +#else + via_multicast = (in_sock == eee->udp_multicast_sock); +#endif + + traceEvent(TRACE_DEBUG, "Rx N2N_UDP of size %d from [%s]", + (signed int)udp_size, sock_to_cstr(sockbuf1, &sender)); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + // match with static (1) or dynamic (2) ctx? + // check dynamic first as it is identical to static in normal header encryption mode + if(packet_header_decrypt(udp_buf, udp_size, + (char *)eee->conf.community_name, + eee->conf.header_encryption_ctx_dynamic, eee->conf.header_iv_ctx_dynamic, + &stamp)) { + header_enc = 2; /* not accurate with normal header encryption but does not matter */ + } + if(!header_enc) { + // check static now (very likely to be REGISTER_SUPER_ACK, REGISTER_SUPER_NAK or invalid) + if(eee->conf.shared_secret) { + // hash the still encrypted packet to eventually be able to check it later (required for REGISTER_SUPER_ACK with user/pw auth) + pearson_hash_128(hash_buf, udp_buf, max(0, (int)udp_size - (int)N2N_REG_SUP_HASH_CHECK_LEN)); + } + header_enc = packet_header_decrypt(udp_buf, max(0, (int)udp_size - (int)N2N_REG_SUP_HASH_CHECK_LEN), + (char *)eee->conf.community_name, + eee->conf.header_encryption_ctx_static, eee->conf.header_iv_ctx_static, + &stamp); + } + if(!header_enc) { + traceEvent(TRACE_DEBUG, "failed to decrypt header"); + return; + } + // time stamp verification follows in the packet specific section as it requires to determine the + // sender from the hash list by its MAC, or the packet might be from the supernode, this all depends + // on packet type, path taken (via supernode) and packet structure (MAC is not always in the same place) + } + + rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + if(decode_common(&cmn, udp_buf, &rem, &idx) < 0) { + if(via_multicast) { + // from some other edge on local network, possibly header encrypted + traceEvent(TRACE_DEBUG, "dropped packet arriving via multicast due to error while decoding N2N_UDP"); + } else { + traceEvent(TRACE_INFO, "failed to decode common section in N2N_UDP"); + } + return; /* failed to decode packet */ + } + + msg_type = cmn.pc; /* packet code */ + + // special case for user/pw auth + // community's auth scheme and message type need to match the used key (dynamic) + if((eee->conf.shared_secret) + && (msg_type != MSG_TYPE_REGISTER_SUPER_ACK) + && (msg_type != MSG_TYPE_REGISTER_SUPER_NAK)) { + if(header_enc != 2) { + traceEvent(TRACE_INFO, "dropped packet encrypted with static key where dynamic key expected"); + return; + } + } + + // check if packet is from supernode and find the corresponding supernode in list + from_supernode = cmn.flags & N2N_FLAGS_FROM_SUPERNODE; + if(from_supernode) { + skip_add = SN_ADD_SKIP; + sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, null_mac, &skip_add); + if(!sn) { + traceEvent(TRACE_DEBUG, "dropped incoming data from unknown supernode"); + return; + } + } + + if(0 == memcmp(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE)) { + switch(msg_type) { + case MSG_TYPE_PACKET: { + /* process PACKET - most frequent so first in list. */ + n2n_PACKET_t pkt; + + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, pkt.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped PACKET due to time stamp error"); + return; + } + } + + if(!eee->last_sup) { + // drop packets received before first registration with supernode + traceEvent(TRACE_DEBUG, "dropped PACKET recevied before first registration with supernode"); + return; + } + + if(is_valid_peer_sock(&pkt.sock)) + orig_sender = &(pkt.sock); + + if(!from_supernode) { + /* This is a P2P packet from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed in + * handle_PACKET to double check this. + */ + traceEvent(TRACE_DEBUG, "[p2p] from %s", + macaddr_str(mac_buf1, pkt.srcMac)); + find_and_remove_peer(&eee->pending_peers, pkt.srcMac); + } else { + /* [PsP] : edge Peer->Supernode->edge Peer */ + traceEvent(TRACE_DEBUG, "[pSp] from %s via [%s]", + macaddr_str(mac_buf1, pkt.srcMac), + sock_to_cstr(sockbuf1, &sender)); + } + + /* Update the sender in peer table entry */ + check_peer_registration_needed(eee, from_supernode, via_multicast, + pkt.srcMac, + // REVISIT: also consider PORT_REG_COOKIEs when implemented + from_supernode ? N2N_FORWARDED_REG_COOKIE : N2N_REGULAR_REG_COOKIE, + NULL, NULL, orig_sender); + + handle_PACKET(eee, from_supernode, &pkt, orig_sender, udp_buf + idx, udp_size - idx); + break; + } + + case MSG_TYPE_REGISTER: { + /* Another edge is registering with us */ + n2n_REGISTER_t reg; + + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + + via_multicast &= is_null_mac(reg.dstMac); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, reg.srcMac, stamp, + via_multicast ? TIME_STAMP_ALLOW_JITTER : TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER due to time stamp error"); + return; + } + } + + if(is_valid_peer_sock(®.sock)) + orig_sender = &(reg.sock); + + if(via_multicast && !memcmp(reg.srcMac, eee->device.mac_addr, N2N_MAC_SIZE)) { + traceEvent(TRACE_DEBUG, "skipping REGISTER from self"); + break; + } + + if(!via_multicast && memcmp(reg.dstMac, eee->device.mac_addr, N2N_MAC_SIZE)) { + traceEvent(TRACE_DEBUG, "skipping REGISTER for other peer"); + break; + } + + if(!from_supernode) { + /* This is a P2P registration from the peer. We purge a pending + * registration towards the possibly nat-ted peer address as we now have + * a valid channel. We still use check_peer_registration_needed below + * to double check this. + */ + traceEvent(TRACE_INFO, "[p2p] Rx REGISTER from %s [%s]%s", + macaddr_str(mac_buf1, reg.srcMac), + sock_to_cstr(sockbuf1, &sender), + (reg.cookie & N2N_LOCAL_REG_COOKIE) ? " (local)" : ""); + find_and_remove_peer(&eee->pending_peers, reg.srcMac); + + /* NOTE: only ACK to peers */ + send_register_ack(eee, orig_sender, ®); + } else { + traceEvent(TRACE_INFO, "[pSp] Rx REGISTER from %s [%s] to %s via [%s]", + macaddr_str(mac_buf1, reg.srcMac), sock_to_cstr(sockbuf2, orig_sender), + macaddr_str(mac_buf2, reg.dstMac), sock_to_cstr(sockbuf1, &sender)); + } + + check_peer_registration_needed(eee, from_supernode, via_multicast, + reg.srcMac, reg.cookie, ®.dev_addr, (const n2n_desc_t*)®.dev_desc, orig_sender); + break; + } + + case MSG_TYPE_REGISTER_ACK: { + /* Peer edge is acknowledging our register request */ + n2n_REGISTER_ACK_t ra; + + decode_REGISTER_ACK(&ra, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, ra.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_ACK due to time stamp error"); + return; + } + } + + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); + + traceEvent(TRACE_INFO, "Rx REGISTER_ACK from %s [%s] to %s via [%s]%s", + macaddr_str(mac_buf1, ra.srcMac), + sock_to_cstr(sockbuf2, orig_sender), + macaddr_str(mac_buf2, ra.dstMac), + sock_to_cstr(sockbuf1, &sender), + (ra.cookie & N2N_LOCAL_REG_COOKIE) ? " (local)" : ""); + + peer_set_p2p_confirmed(eee, ra.srcMac, + ra.cookie, + &sender, now); + break; + } + + case MSG_TYPE_REGISTER_SUPER_ACK: { + in_addr_t net; + char * ip_str = NULL; + n2n_REGISTER_SUPER_ACK_t ra; + uint8_t tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; + char ip_tmp[N2N_EDGE_SN_HOST_SIZE]; + n2n_REGISTER_SUPER_ACK_payload_t *payload; + int i; + int skip_add; + + if(!(eee->sn_wait)) { + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER"); + return; + } + + memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); + decode_REGISTER_SUPER_ACK(&ra, &cmn, udp_buf, &rem, &idx, tmpbuf); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, ra.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER_ACK due to time stamp error"); + return; + } + } + + // hash check (user/pw auth only) + if(eee->conf.shared_secret) { + speck_128_encrypt(hash_buf, (speck_context_t*)eee->conf.shared_secret_ctx); + if(memcmp(hash_buf, udp_buf + udp_size - N2N_REG_SUP_HASH_CHECK_LEN /* length is has already been checked */, N2N_REG_SUP_HASH_CHECK_LEN)) { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong hash"); + return; + } + } + + if(ra.cookie != eee->curr_sn->last_cookie) { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie"); + return; + } + + if(handle_remote_auth(eee, sn, &(ra.auth))) { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old response to challenge"); + if(eee->conf.shared_secret) { + traceEvent(TRACE_NORMAL, "Rx REGISTER_SUPER_ACK with wrong or old response to challenge, maybe indicating wrong federation public key (-P)"); + } + return; + } + + if(is_valid_peer_sock(&ra.sock)) + orig_sender = &(ra.sock); + + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK from %s [%s] (external %s) with %u attempts left", + macaddr_str(mac_buf1, ra.srcMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender), + (unsigned int)eee->sup_attempts); + + if(is_null_mac(eee->curr_sn->mac_addr)) { + HASH_DEL(eee->conf.supernodes, eee->curr_sn); + memcpy(&eee->curr_sn->mac_addr, ra.srcMac, N2N_MAC_SIZE); + HASH_ADD_PEER(eee->conf.supernodes, eee->curr_sn); + } + + payload = (n2n_REGISTER_SUPER_ACK_payload_t*)tmpbuf; + + // from here on, 'sn' gets used differently + for(i = 0; i < ra.num_sn; i++) { + skip_add = SN_ADD; + sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &(payload->sock), payload->mac, &skip_add); + + if(skip_add == SN_ADD_ADDED) { + sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE); + if(sn->ip_addr != NULL) { + inet_ntop(payload->sock.family, + (payload->sock.family == AF_INET) ? (void*)&(payload->sock.addr.v4) : (void*)&(payload->sock.addr.v6), + sn->ip_addr, N2N_EDGE_SN_HOST_SIZE - 1); + sprintf(ip_tmp, "%s:%u", (char*)sn->ip_addr, (uint16_t)(payload->sock.port)); + memcpy(sn->ip_addr, ip_tmp, sizeof(ip_tmp)); + } + sn_selection_criterion_default(&(sn->selection_criterion)); + sn->last_seen = 0; /* as opposed to payload handling in supernode */ + traceEvent(TRACE_NORMAL, "supernode '%s' added to the list of supernodes.", sn->ip_addr); + } + // shift to next payload entry + payload++; + } + + if(eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_SN_ASSIGN) { + if((ra.dev_addr.net_addr != 0) && (ra.dev_addr.net_bitlen != 0)) { + net = htonl(ra.dev_addr.net_addr); + if((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) { + strncpy(eee->tuntap_priv_conf.ip_addr, ip_str, N2N_NETMASK_STR_SIZE); + eee->tuntap_priv_conf.ip_addr[N2N_NETMASK_STR_SIZE - 1] = '\0'; + } + net = htonl(bitlen2mask(ra.dev_addr.net_bitlen)); + if((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) { + strncpy(eee->tuntap_priv_conf.netmask, ip_str, N2N_NETMASK_STR_SIZE); + eee->tuntap_priv_conf.netmask[N2N_NETMASK_STR_SIZE - 1] = '\0'; + } + } + } + + eee->sn_wait = 0; + reset_sup_attempts(eee); /* refresh because we got a response */ + + // update last_sup only on 'real' REGISTER_SUPER_ACKs, not on bootstrap ones (own MAC address + // still null_mac) this allows reliable in/out PACKET drop if not really registered with a supernode yet + if(!is_null_mac(eee->device.mac_addr)) { + if(!eee->last_sup) { + // indicates first successful connection between the edge and a supernode + traceEvent(TRACE_NORMAL, "[OK] edge <<< ================ >>> supernode"); + // send gratuitous ARP only upon first registration with supernode + send_grat_arps(eee); + } + eee->last_sup = now; + } + + // NOTE: the register_interval should be chosen by the edge node based on its NAT configuration. + // eee->conf.register_interval = ra.lifetime; + + if(eee->cb.sn_registration_updated && !is_null_mac(eee->device.mac_addr)) + eee->cb.sn_registration_updated(eee, now, &sender); + + break; + } + + case MSG_TYPE_REGISTER_SUPER_NAK: { + + n2n_REGISTER_SUPER_NAK_t nak; + + if(!(eee->sn_wait)) { + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER_NAK with no outstanding REGISTER_SUPER"); + return; + } + + memset(&nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t)); + decode_REGISTER_SUPER_NAK(&nak, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, nak.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER_NAK due to time stamp error"); + return; + } + } + + if(nak.cookie != eee->curr_sn->last_cookie) { + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER_NAK with wrong or old cookie"); + return; + } + + // REVISIT: authenticate the NAK packet really originating from the supernode along the auth token. + // this must follow a different scheme because it needs to prove authenticity although the + // edge-provided credentials are wrong + + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_NAK"); + + if((memcmp(nak.srcMac, eee->device.mac_addr, sizeof(n2n_mac_t))) == 0) { + if(eee->conf.shared_secret) { + traceEvent(TRACE_ERROR, "authentication error, username or password not recognized by supernode"); + } else { + traceEvent(TRACE_ERROR, "authentication error, MAC or IP address already in use or not released yet by supernode"); + } + // REVISIT: the following portion is too harsh, repeated error warning should be sufficient until it eventually is resolved, + // preventing de-auth attacks + /* exit(1); this is too harsh, repeated error warning should be sufficient until it eventually is resolved, preventing de-auth attacks + } else { + HASH_FIND_PEER(eee->known_peers, nak.srcMac, peer); + if(peer != NULL) { + HASH_DEL(eee->known_peers, peer); + } + HASH_FIND_PEER(eee->pending_peers, nak.srcMac, scan); + if(scan != NULL) { + HASH_DEL(eee->pending_peers, scan); + } */ + } + break; + } + + case MSG_TYPE_PEER_INFO: { + + n2n_PEER_INFO_t pi; + struct peer_info * scan; + int skip_add; + + decode_PEER_INFO(&pi, &cmn, udp_buf, &rem, &idx); + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, null_mac, stamp, TIME_STAMP_ALLOW_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped PEER_INFO due to time stamp error"); + return; + } + } + + if((cmn.flags & N2N_FLAGS_SOCKET) && !is_valid_peer_sock(&pi.sock)) { + traceEvent(TRACE_DEBUG, "skip invalid PEER_INFO from %s [%s]", + macaddr_str(mac_buf1, pi.mac), + sock_to_cstr(sockbuf1, &pi.sock)); + break; + } + + if(is_null_mac(pi.mac)) { + // PONG - answer to PING (QUERY_PEER_INFO with null mac) + skip_add = SN_ADD_SKIP; + scan = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &sender, pi.srcMac, &skip_add); + if(scan != NULL) { + eee->sn_pong = 1; + scan->last_seen = now; + scan->uptime = pi.uptime; + memcpy(scan->version, pi.version, sizeof(n2n_version_t)); + /* The data type depends on the actual selection strategy that has been chosen. */ + SN_SELECTION_CRITERION_DATA_TYPE sn_sel_tmp = pi.load; + sn_selection_criterion_calculate(eee, scan, &sn_sel_tmp); + + traceEvent(TRACE_INFO, "Rx PONG from supernode %s", + macaddr_str(mac_buf1, pi.srcMac)); + + break; + } + } else { + // regular PEER_INFO + HASH_FIND_PEER(eee->pending_peers, pi.mac, scan); + if(!scan) + // just in case the remote edge has been upgraded by the REG/ACK mechanism in the meantime + HASH_FIND_PEER(eee->known_peers, pi.mac, scan); + + if(scan) { + scan->sock = pi.sock; + + traceEvent(TRACE_INFO, "Rx PEER_INFO %s can be found at [%s]", + macaddr_str(mac_buf1, pi.mac), + sock_to_cstr(sockbuf1, &pi.sock)); + + if(cmn.flags & N2N_FLAGS_SOCKET) { + scan->preferred_sock = pi.preferred_sock; + send_register(eee, &scan->preferred_sock, scan->mac_addr, N2N_LOCAL_REG_COOKIE); + + traceEvent(TRACE_INFO, "%s has preferred local socket at [%s]", + macaddr_str(mac_buf1, pi.mac), + sock_to_cstr(sockbuf1, &pi.preferred_sock)); + } + + send_register(eee, &scan->sock, scan->mac_addr, N2N_REGULAR_REG_COOKIE); + + } else { + traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s", + macaddr_str(mac_buf1, pi.mac)); + } + } + break; + } + + case MSG_TYPE_RE_REGISTER_SUPER: { + + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_peer_time_stamp_and_verify(eee, sn, null_mac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped RE_REGISTER due to time stamp error"); + return; + } + } + + // only accept in user/pw mode for immediate re-registration because the new + // key is required for continous traffic flow, in other modes edge will realize + // changes with regular recurring REGISTER_SUPER + if(!eee->conf.shared_secret) { + traceEvent(TRACE_DEBUG, "dropped RE_REGISTER_SUPER as not in user/pw auth mode"); + return; + } + + traceEvent(TRACE_INFO, "Rx RE_REGISTER_SUPER"); + + eee->sn_wait = 2; /* immediately */ + + break; + } + + default: + /* Not a known message type */ + traceEvent(TRACE_INFO, "unable to handle packet type %d: ignored", (signed int)msg_type); + return; + } /* switch(msg_type) */ + } else if(from_supernode) /* if(community match) */ + traceEvent(TRACE_INFO, "received packet with unknown community"); + else + traceEvent(TRACE_INFO, "ignoring packet with unknown community"); +} + + +/* ************************************** */ + + +int fetch_and_eventually_process_data (n2n_edge_t *eee, SOCKET sock, + uint8_t *pktbuf, uint16_t *expected, uint16_t *position, + time_t now) { + + ssize_t bread = 0; + + if((!eee->conf.connect_tcp) +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + || (sock == eee->udp_multicast_sock) +#endif + ) { + // udp + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sock, pktbuf, N2N_PKT_BUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if((bread < 0) +#ifdef WIN32 + && (WSAGetLastError() != WSAECONNRESET) +#endif + ) { + /* For UDP bread of zero just means no data (unlike TCP). */ + /* The fd is no good now. Maybe we lost our interface. */ + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + return -1; + } + + // we have a datagram to process... + if(bread > 0) { + // ...and the datagram has data (not just a header) + process_udp(eee, &sender_sock, sock, pktbuf, bread, now); + } + + } else { + // tcp + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sock, + pktbuf + *position, *expected - *position, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + if((bread <= 0) && (errno)) { + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + supernode_disconnect(eee); + eee->sn_wait = 1; + traceEvent(TRACE_DEBUG, "disconnected supernode due to connection error"); + goto tcp_done; + } + *position = *position + bread; + + if(*position == *expected) { + if(*position == sizeof(uint16_t)) { + // the prepended length has been read, preparing for the packet + *expected = *expected + be16toh(*(uint16_t*)(pktbuf)); + if(*expected > N2N_PKT_BUF_SIZE) { + supernode_disconnect(eee); + eee->sn_wait = 1; + traceEvent(TRACE_DEBUG, "disconnected supernode due to too many bytes expected"); + goto tcp_done; + } + } else { + // full packet read, handle it + process_udp(eee, (struct sockaddr_in*)&sender_sock, sock, + pktbuf + sizeof(uint16_t), *position - sizeof(uint16_t), now); + // reset, await new prepended length + *expected = sizeof(uint16_t); + *position = 0; + } + } + } + tcp_done: + ; + + return 0; +} + + +void print_edge_stats (const n2n_edge_t *eee) { + + const struct n2n_edge_stats *s = &eee->stats; + + traceEvent(TRACE_NORMAL, "**********************************"); + traceEvent(TRACE_NORMAL, "Packet stats:"); + traceEvent(TRACE_NORMAL, " TX P2P: %u pkts", s->tx_p2p); + traceEvent(TRACE_NORMAL, " RX P2P: %u pkts", s->rx_p2p); + traceEvent(TRACE_NORMAL, " TX Supernode: %u pkts (%u broadcast)", s->tx_sup, s->tx_sup_broadcast); + traceEvent(TRACE_NORMAL, " RX Supernode: %u pkts (%u broadcast)", s->rx_sup, s->rx_sup_broadcast); + traceEvent(TRACE_NORMAL, "**********************************"); +} + + +/* ************************************** */ + + +int run_edge_loop (n2n_edge_t *eee) { + + size_t numPurged; + time_t lastIfaceCheck = 0; + time_t lastTransop = 0; + time_t last_purge_known = 0; + time_t last_purge_pending = 0; + + uint16_t expected = sizeof(uint16_t); + uint16_t position = 0; + uint8_t pktbuf[N2N_PKT_BUF_SIZE + sizeof(uint16_t)]; /* buffer + prepended buffer length in case of tcp */ + +#ifdef WIN32 + struct tunread_arg arg; + arg.eee = eee; + HANDLE tun_read_thread = startTunReadThread(&arg); +#endif + + *eee->keep_running = 1; + update_supernode_reg(eee, time(NULL)); + + /* Main loop + * + * select() is used to wait for input on either the TAP fd or the UDP/TCP + * socket. When input is present the data is read and processed by either + * readFromIPSocket() or edge_read_from_tap() + */ + + while(*eee->keep_running) { + + int rc, max_sock = 0; + fd_set socket_mask; + struct timeval wait_time; + time_t now; + + FD_ZERO(&socket_mask); + + FD_SET(eee->udp_mgmt_sock, &socket_mask); + max_sock = eee->udp_mgmt_sock; + + if(eee->sock >= 0) { + FD_SET(eee->sock, &socket_mask); + max_sock = max(eee->sock, eee->udp_mgmt_sock); + } +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if((eee->conf.allow_p2p) + && (eee->conf.preferred_sock.family == (uint8_t)AF_INVALID)) { + FD_SET(eee->udp_multicast_sock, &socket_mask); + max_sock = max(eee->sock, eee->udp_multicast_sock); + } +#endif + +#ifndef WIN32 + FD_SET(eee->device.fd, &socket_mask); + max_sock = max(max_sock, eee->device.fd); +#endif + + wait_time.tv_sec = (eee->sn_wait) ? (SOCKET_TIMEOUT_INTERVAL_SECS / 10 + 1) : (SOCKET_TIMEOUT_INTERVAL_SECS); + wait_time.tv_usec = 0; + rc = select(max_sock + 1, &socket_mask, NULL, NULL, &wait_time); + now = time(NULL); + + // make sure ciphers are updated before the packet is treated + if((now - lastTransop) > TRANSOP_TICK_INTERVAL) { + lastTransop = now; + + eee->transop.tick(&eee->transop, now); + } + + if(rc > 0) { + // any or all of the FDs could have input; check them all + + // external + if(FD_ISSET(eee->sock, &socket_mask)) { + if(0 != fetch_and_eventually_process_data(eee, eee->sock, + pktbuf, &expected, &position, + now)) { + *eee->keep_running = 0; + break; + } + if(eee->conf.connect_tcp) { + if((expected >= N2N_PKT_BUF_SIZE) || (position >= N2N_PKT_BUF_SIZE)) { + // something went wrong, possibly even before + // e.g. connection failure/closure in the middle of transmission (between len & data) + supernode_disconnect(eee); + eee->sn_wait = 1; + + expected = sizeof(uint16_t); + position = 0; + } + } + } + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(FD_ISSET(eee->udp_multicast_sock, &socket_mask)) { + if(0 != fetch_and_eventually_process_data(eee, eee->udp_multicast_sock, + pktbuf, &expected, &position, + now)) { + *eee->keep_running = 0; + break; + } + } +#endif + + if(FD_ISSET(eee->udp_mgmt_sock, &socket_mask)) { + // read from the management port socket + readFromMgmtSocket(eee); + + if(!(*eee->keep_running)) + break; + } + +#ifndef WIN32 + if(FD_ISSET(eee->device.fd, &socket_mask)) { + // read an ethernet frame from the TAP socket; write on the IP socket + edge_read_from_tap(eee); + } +#endif + } + + // finished processing select data + update_supernode_reg(eee, now); + + numPurged = 0; + // keep, i.e. do not purge, the known peers while no supernode supernode connection + if(!eee->sn_wait) + numPurged = purge_expired_nodes(&eee->known_peers, + eee->sock, NULL, + &last_purge_known, + PURGE_REGISTRATION_FREQUENCY, REGISTRATION_TIMEOUT); + numPurged += purge_expired_nodes(&eee->pending_peers, + eee->sock, NULL, + &last_purge_pending, + PURGE_REGISTRATION_FREQUENCY, REGISTRATION_TIMEOUT); + + if(numPurged > 0) { + traceEvent(TRACE_INFO, "%u peers removed. now: pending=%u, operational=%u", + numPurged, + HASH_COUNT(eee->pending_peers), + HASH_COUNT(eee->known_peers)); + } + + if((eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_DHCP) && + ((now - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) { + uint32_t old_ip = eee->device.ip_addr; + + traceEvent(TRACE_NORMAL, "re-checking dynamic IP address"); + tuntap_get_address(&(eee->device)); + lastIfaceCheck = now; + + if((old_ip != eee->device.ip_addr) && eee->cb.ip_address_changed) + eee->cb.ip_address_changed(eee, old_ip, eee->device.ip_addr); + } + + sort_supernodes(eee, now); + + eee->resolution_request = resolve_check(eee->resolve_parameter, eee->resolution_request, now); + + if(eee->cb.main_loop_period) + eee->cb.main_loop_period(eee, now); + + } /* while */ + + send_unregister_super(eee); + +#ifdef WIN32 + WaitForSingleObject(tun_read_thread, INFINITE); +#endif + + closesocket(eee->sock); + + return(0); +} + +/* ************************************** */ + +/** Deinitialise the edge and deallocate any owned memory. */ +void edge_term (n2n_edge_t * eee) { + + resolve_cancel_thread(eee->resolve_parameter); + + if(eee->sock >= 0) + closesocket(eee->sock); + + if(eee->udp_mgmt_sock >= 0) + closesocket(eee->udp_mgmt_sock); + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(eee->udp_multicast_sock >= 0) + closesocket(eee->udp_multicast_sock); +#endif + + clear_peer_list(&eee->pending_peers); + clear_peer_list(&eee->known_peers); + + eee->transop.deinit(&eee->transop); + + edge_cleanup_routes(eee); + + destroy_network_traffic_filter(eee->network_traffic_filter); + + closeTraceFile(); + + free(eee); +} + +/* ************************************** */ + + +static int edge_init_sockets (n2n_edge_t *eee) { + + if(eee->udp_mgmt_sock >= 0) + closesocket(eee->udp_mgmt_sock); + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + if(eee->udp_multicast_sock >= 0) + closesocket(eee->udp_multicast_sock); +#endif + + eee->udp_mgmt_sock = open_socket(eee->conf.mgmt_port, INADDR_LOOPBACK, 0 /* UDP */); + if(eee->udp_mgmt_sock < 0) { + traceEvent(TRACE_ERROR, "failed to bind management UDP port %u", eee->conf.mgmt_port); + return(-2); + } + +#ifndef SKIP_MULTICAST_PEERS_DISCOVERY + /* Populate the multicast group for local edge */ + eee->multicast_peer.family = AF_INET; + eee->multicast_peer.port = N2N_MULTICAST_PORT; + eee->multicast_peer.addr.v4[0] = 224; /* N2N_MULTICAST_GROUP */ + eee->multicast_peer.addr.v4[1] = 0; + eee->multicast_peer.addr.v4[2] = 0; + eee->multicast_peer.addr.v4[3] = 68; + + eee->udp_multicast_sock = open_socket(N2N_MULTICAST_PORT, INADDR_ANY, 0 /* UDP */); + if(eee->udp_multicast_sock < 0) + return(-3); + else { + u_int enable_reuse = 1; + + /* allow multiple sockets to use the same PORT number */ + setsockopt(eee->udp_multicast_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable_reuse, sizeof(enable_reuse)); +#ifdef SO_REUSEPORT /* no SO_REUSEPORT in Windows / old linux versions */ + setsockopt(eee->udp_multicast_sock, SOL_SOCKET, SO_REUSEPORT, &enable_reuse, sizeof(enable_reuse)); +#endif + } +#endif + + return(0); +} + +/* ************************************** */ + +#ifdef __linux__ + +static uint32_t get_gateway_ip () { + + FILE *fd; + char *token = NULL; + char *gateway_ip_str = NULL; + char buf[256]; + uint32_t gateway = 0; + + if(!(fd = fopen("/proc/net/route", "r"))) + return(0); + + while(fgets(buf, sizeof(buf), fd)) { + if(strtok(buf, "\t") && (token = strtok(NULL, "\t")) && (!strcmp(token, "00000000"))) { + token = strtok(NULL, "\t"); + + if(token) { + struct in_addr addr; + + addr.s_addr = strtoul(token, NULL, 16); + gateway_ip_str = inet_ntoa(addr); + + if(gateway_ip_str) { + gateway = addr.s_addr; + break; + } + } + } + } + + fclose(fd); + + return(gateway); +} + +static char* route_cmd_to_str (int cmd, const n2n_route_t *route, char *buf, size_t bufsize) { + + const char *cmd_str; + struct in_addr addr; + char netbuf[64], gwbuf[64]; + + switch(cmd) { + case RTM_NEWROUTE: + cmd_str = "Add"; + break; + + case RTM_DELROUTE: + cmd_str = "Delete"; + break; + + default: + cmd_str = "?"; + } + + addr.s_addr = route->net_addr; + inet_ntop(AF_INET, &addr, netbuf, sizeof(netbuf)); + addr.s_addr = route->gateway; + inet_ntop(AF_INET, &addr, gwbuf, sizeof(gwbuf)); + + snprintf(buf, bufsize, "%s %s/%d via %s", cmd_str, netbuf, route->net_bitlen, gwbuf); + + return(buf); +} + +/* Adapted from https://olegkutkov.me/2019/08/29/modifying-linux-network-routes-using-netlink/ */ +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +/* Add new data to rtattr */ +static int rtattr_add (struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) { + + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + if(NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { + traceEvent(TRACE_ERROR, "rtattr_add error: message exceeded bound of %d\n", maxlen); + return -1; + } + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = len; + + if(alen) + memcpy(RTA_DATA(rta), data, alen); + + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); + + return 0; +} + +static int routectl (int cmd, int flags, n2n_route_t *route, int if_idx) { + + int rv = -1; + int rv2; + char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ + char route_buf[256]; + struct iovec iov; + struct msghdr msg; + struct sockaddr_nl sa; + uint8_t read_reply = 1; + int nl_sock; + + struct { + struct nlmsghdr n; + struct rtmsg r; + char buf[4096]; + } nl_request; + + if((nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); + return(-1); + } + + /* Subscribe to route change events */ + iov.iov_base = nl_buf; + iov.iov_len = sizeof(nl_buf); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_NOTIFY; + sa.nl_pid = getpid(); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + /* Subscribe to route events */ + if(bind(nl_sock, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); + goto out; + } + + /* Initialize request structure */ + memset(&nl_request, 0, sizeof(nl_request)); + nl_request.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + nl_request.n.nlmsg_flags = NLM_F_REQUEST | flags; + nl_request.n.nlmsg_type = cmd; + nl_request.r.rtm_family = AF_INET; + nl_request.r.rtm_table = RT_TABLE_MAIN; + nl_request.r.rtm_scope = RT_SCOPE_NOWHERE; + + /* Set additional flags if NOT deleting route */ + if(cmd != RTM_DELROUTE) { + nl_request.r.rtm_protocol = RTPROT_BOOT; + nl_request.r.rtm_type = RTN_UNICAST; + } + + nl_request.r.rtm_family = AF_INET; + nl_request.r.rtm_dst_len = route->net_bitlen; + + /* Select scope, for simplicity we supports here only IPv6 and IPv4 */ + if(nl_request.r.rtm_family == AF_INET6) + nl_request.r.rtm_scope = RT_SCOPE_UNIVERSE; + else + nl_request.r.rtm_scope = RT_SCOPE_LINK; + + /* Set gateway */ + if(route->net_bitlen) { + if(rtattr_add(&nl_request.n, sizeof(nl_request), RTA_GATEWAY, &route->gateway, 4) < 0) + goto out; + + nl_request.r.rtm_scope = 0; + nl_request.r.rtm_family = AF_INET; + } + + /* Don't set destination and interface in case of default gateways */ + if(route->net_bitlen) { + /* Set destination network */ + if(rtattr_add(&nl_request.n, sizeof(nl_request), /*RTA_NEWDST*/ RTA_DST, &route->net_addr, 4) < 0) + goto out; + + /* Set interface */ + if(if_idx > 0) { + if(rtattr_add(&nl_request.n, sizeof(nl_request), RTA_OIF, &if_idx, sizeof(int)) < 0) + goto out; + } + } + + /* Send message to the netlink */ + if((rv2 = send(nl_sock, &nl_request, sizeof(nl_request), 0)) != sizeof(nl_request)) { + traceEvent(TRACE_ERROR, "netlink send failed [%d]: %s", errno, strerror(errno)); + goto out; + } + + /* Wait for the route notification. Assume that the first reply we get is the correct one. */ + traceEvent(TRACE_DEBUG, "waiting for netlink response..."); + + while(read_reply) { + ssize_t len = recvmsg(nl_sock, &msg, 0); + struct nlmsghdr *nh; + + for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { + /* Stop after the first reply */ + read_reply = 0; + + if(nh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = NLMSG_DATA(nh); + int errcode = err->error; + + if(errcode < 0) + errcode = -errcode; + + /* Ignore EEXIST as existing rules are ok */ + if(errcode != EEXIST) { + traceEvent(TRACE_ERROR, "[err=%d] route: %s", errcode, route_cmd_to_str(cmd, route, route_buf, sizeof(route_buf))); + goto out; + } + } + + if(nh->nlmsg_type == NLMSG_DONE) + break; + + if(nh->nlmsg_type == cmd) { + traceEvent(TRACE_DEBUG, "Found netlink reply"); + break; + } + } + } + + traceEvent(TRACE_DEBUG, route_cmd_to_str(cmd, route, route_buf, sizeof(route_buf))); + rv = 0; + +out: + close(nl_sock); + + return(rv); +} +#endif + +/* ************************************** */ + +#ifdef __linux__ + +static int edge_init_routes_linux (n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) { + int i; + for(i = 0; inet_addr == 0) && (route->net_bitlen == 0)) { + /* This is a default gateway rule. We need to: + * + * 1. Add a route to the supernode via the host internet gateway + * 2. Add the new default gateway route + * + * Instead of modifying the system default gateway, we use the trick + * of adding a route to the networks 0.0.0.0/1 and 128.0.0.0/1, thus + * covering the whole IPv4 range. Such routes in linux take precedence + * over the default gateway (0.0.0.0/0) since are more specific. + * This leaves the default gateway unchanged so that after n2n is + * stopped the cleanup is easier. + * See https://github.com/zerotier/ZeroTierOne/issues/178#issuecomment-204599227 + */ + n2n_sock_t sn; + n2n_route_t custom_route; + uint32_t *a; + + if(eee->sn_route_to_clean) { + traceEvent(TRACE_ERROR, "only one default gateway route allowed"); + return(-1); + } + + if(eee->conf.sn_num != 1) { + traceEvent(TRACE_ERROR, "only one supernode supported with routes"); + return(-1); + } + + if(supernode2sock(&sn, eee->conf.supernodes->ip_addr) < 0) + return(-1); + + if(sn.family != AF_INET) { + traceEvent(TRACE_ERROR, "only IPv4 routes supported"); + return(-1); + } + + a = (u_int32_t*)sn.addr.v4; + custom_route.net_addr = *a; + custom_route.net_bitlen = 32; + custom_route.gateway = get_gateway_ip(); + + if(!custom_route.gateway) { + traceEvent(TRACE_ERROR, "could not determine the gateway IP address"); + return(-1); + } + + /* ip route add supernode via internet_gateway */ + if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, -1) < 0) + return(-1); + + /* Save the route to delete it when n2n is stopped */ + eee->sn_route_to_clean = calloc(1, sizeof(n2n_route_t)); + + /* Store a copy of the rules into the runtime to delete it during shutdown */ + if(eee->sn_route_to_clean) + *eee->sn_route_to_clean = custom_route; + + /* ip route add 0.0.0.0/1 via n2n_gateway */ + custom_route.net_addr = 0; + custom_route.net_bitlen = 1; + custom_route.gateway = route->gateway; + + if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0) + return(-1); + + /* ip route add 128.0.0.0/1 via n2n_gateway */ + custom_route.net_addr = 128; + custom_route.net_bitlen = 1; + custom_route.gateway = route->gateway; + + if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0) + return(-1); + } else { + /* ip route add net via n2n_gateway */ + if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, route, eee->device.if_idx) < 0) + return(-1); + } + } + + return(0); +} +#endif + +/* ************************************** */ + +#ifdef WIN32 +static int edge_init_routes_win (n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes, uint8_t verb /* 0 = add, 1 = delete */) { + int i; + struct in_addr net_addr, gateway; + char c_net_addr[32]; + char c_gateway[32]; + char c_interface[32]; + char c_verb[32]; + char cmd[256]; + + for(i = 0; i < num_routes; i++) { + n2n_route_t *route = &routes[i]; + if((route->net_addr == 0) && (route->net_bitlen == 0)) { + // REVISIT: there might be a chance to get it working on Windows following the hints at + // https://docs.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row + // + // " The DisableDefaultRoutes member of the MIB_IPINTERFACE_ROW structure can be used to disable + // using the default route on an interface. This member can be used as a security measure by + // VPN clients to restrict split tunneling when split tunneling is not required by the VPN client. + // A VPN client can call the SetIpInterfaceEntry function to set the DisableDefaultRoutes member + // to TRUE when required. A VPN client can query the current state of the DisableDefaultRoutes + // member by calling the GetIpInterfaceEntry function. " + traceEvent(TRACE_WARNING, "the 0.0.0.0/0 route settings are not supported on Windows"); + return(-1); + } else { + /* ip route add net via n2n_gateway */ + memcpy(&net_addr, &(route->net_addr), sizeof(net_addr)); + memcpy(&gateway, &(route->gateway), sizeof(gateway)); + _snprintf(c_net_addr, sizeof(c_net_addr), inet_ntoa(net_addr)); + _snprintf(c_gateway, sizeof(c_gateway), inet_ntoa(gateway)); + _snprintf(c_interface, sizeof(c_interface), "if %u", eee->device.if_idx); + _snprintf(c_verb, sizeof(c_verb), verb ? "delete" : "add"); + _snprintf(cmd, sizeof(cmd), "route %s %s/%d %s %s > nul", c_verb, c_net_addr, route->net_bitlen, c_gateway, c_interface); + traceEvent(TRACE_NORMAL, "ROUTE CMD = '%s'\n", cmd); + system(cmd); + } + } + + return (0); +} +#endif // WIN32 + +/* ************************************** */ + +/* Add the user-provided routes to the linux routing table. Network routes + * are bound to the n2n TAP device, so they are automatically removed when + * the TAP device is destroyed. */ +int edge_init_routes (n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) { +#ifdef __linux__ + return edge_init_routes_linux(eee, routes, num_routes); +#endif + +#ifdef WIN32 + return edge_init_routes_win(eee, routes, num_routes, 0 /* add */); +#endif + return 0; +} + +/* ************************************** */ + +static void edge_cleanup_routes (n2n_edge_t *eee) { +#ifdef __linux__ + if(eee->sn_route_to_clean) { + /* ip route del supernode via internet_gateway */ + routectl(RTM_DELROUTE, 0, eee->sn_route_to_clean, -1); + free(eee->sn_route_to_clean); + } +#endif + +#ifdef WIN32 + edge_init_routes_win(eee, eee->conf.routes, eee->conf.num_routes, 1 /* del */); +#endif + +} + +/* ************************************** */ + +void edge_init_conf_defaults (n2n_edge_conf_t *conf) { + + char *tmp_string; + + memset(conf, 0, sizeof(*conf)); + + conf->bind_address = INADDR_ANY; /* any address */ + conf->local_port = 0 /* any port */; + conf->preferred_sock.family = AF_INVALID; + conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */ + conf->transop_id = N2N_TRANSFORM_ID_NULL; + conf->header_encryption = HEADER_ENCRYPTION_NONE; + conf->compression = N2N_COMPRESSION_ID_NONE; + conf->drop_multicast = 1; + conf->allow_p2p = 1; + conf->disable_pmtu_discovery = 1; + conf->register_interval = REGISTER_SUPER_INTERVAL_DFL; + conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; + /* reserve possible last char as null terminator. */ + gethostname((char*)conf->dev_desc, N2N_DESC_SIZE-1); + + if(getenv("N2N_KEY")) { + conf->encrypt_key = strdup(getenv("N2N_KEY")); + conf->transop_id = N2N_TRANSFORM_ID_AES; + } + if(getenv("N2N_COMMUNITY")) { + strncpy((char*)conf->community_name, getenv("N2N_COMMUNITY"), N2N_COMMUNITY_SIZE); + conf->community_name[N2N_COMMUNITY_SIZE - 1] = '\0'; + } + if(getenv("N2N_PASSWORD")) { + conf->shared_secret = calloc(1, sizeof(n2n_private_public_key_t)); + if(conf->shared_secret) + generate_private_key(*(conf->shared_secret), getenv("N2N_PASSWORD")); + } + + tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1); + if(tmp_string) { + strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1); + conf->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen(N2N_MGMT_PASSWORD)); + free(tmp_string); + } + + conf->sn_selection_strategy = SN_SELECTION_STRATEGY_LOAD; + conf->metric = 0; +} + +/* ************************************** */ + +void edge_term_conf (n2n_edge_conf_t *conf) { + + if(conf->routes) free(conf->routes); + if(conf->encrypt_key) free(conf->encrypt_key); + + if(conf->network_traffic_filter_rules) { + filter_rule_t *el = 0, *tmp = 0; + HASH_ITER(hh, conf->network_traffic_filter_rules, el, tmp) { + HASH_DEL(conf->network_traffic_filter_rules, el); + free(el); + } + } +} + +/* ************************************** */ + +const n2n_edge_conf_t* edge_get_conf (const n2n_edge_t *eee) { + + return(&eee->conf); +} + +/* ************************************** */ + +int edge_conf_add_supernode (n2n_edge_conf_t *conf, const char *ip_and_port) { + + struct peer_info *sn; + n2n_sock_t *sock; + int skip_add; + int rv = -1; + + sock = (n2n_sock_t*)calloc(1,sizeof(n2n_sock_t)); + rv = supernode2sock(sock, ip_and_port); + + if(rv < -2) { /* we accept resolver failure as it might resolve later */ + traceEvent(TRACE_WARNING, "invalid supernode parameter."); + free(sock); + return 1; + } + + skip_add = SN_ADD; + sn = add_sn_to_list_by_mac_or_sock(&(conf->supernodes), sock, null_mac, &skip_add); + + if(sn != NULL) { + sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE); + + if(sn->ip_addr != NULL) { + strncpy(sn->ip_addr, ip_and_port, N2N_EDGE_SN_HOST_SIZE - 1); + memcpy(&(sn->sock), sock, sizeof(n2n_sock_t)); + memcpy(sn->mac_addr, null_mac, sizeof(n2n_mac_t)); + sn->purgeable = SN_UNPURGEABLE; + } + } + + free(sock); + + traceEvent(TRACE_NORMAL, "adding supernode = %s", sn->ip_addr); + conf->sn_num++; + + return 0; +} + +/* ************************************** */ + +int quick_edge_init (char *device_name, char *community_name, + char *encrypt_key, char *device_mac, + char *local_ip_address, + char *supernode_ip_address_port, + int *keep_on_running) { + + tuntap_dev tuntap; + n2n_edge_t *eee; + n2n_edge_conf_t conf; + int rv; + + /* Setup the configuration */ + edge_init_conf_defaults(&conf); + conf.encrypt_key = encrypt_key; + conf.transop_id = N2N_TRANSFORM_ID_AES; + conf.compression = N2N_COMPRESSION_ID_NONE; + snprintf((char*)conf.community_name, sizeof(conf.community_name), "%s", community_name); + edge_conf_add_supernode(&conf, supernode_ip_address_port); + + /* Validate configuration */ + if(edge_verify_conf(&conf) != 0) + return(-1); + + /* Open the tuntap device */ + if(tuntap_open(&tuntap, device_name, "static", + local_ip_address, "255.255.255.0", + device_mac, DEFAULT_MTU +#ifdef WIN32 + , 0 +#endif + ) < 0) + return(-2); + + /* Init edge */ + if((eee = edge_init(&conf, &rv)) == NULL) + goto quick_edge_init_end; + + eee->keep_running = keep_on_running; + rv = run_edge_loop(eee); + edge_term(eee); + edge_term_conf(&conf); + +quick_edge_init_end: + tuntap_close(&tuntap); + return(rv); +} + +/* ************************************** */ diff --git a/bundles/n2n_ntop_v3/src/edge_utils_win32.c b/bundles/n2n_ntop_v3/src/edge_utils_win32.c new file mode 100644 index 00000000..73ccb0b0 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/edge_utils_win32.c @@ -0,0 +1,111 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#ifdef WIN32 + +#include "edge_utils_win32.h" + +/* ************************************** */ + +static DWORD* tunReadThread (LPVOID lpArg) { + + struct tunread_arg *arg = (struct tunread_arg*)lpArg; + + while(*arg->eee->keep_running) { + edge_read_from_tap(arg->eee); + } + + return((DWORD*)NULL); +} + +/* ************************************** */ + +/** Start a second thread in Windows because TUNTAP interfaces do not expose + * file descriptors. */ +HANDLE startTunReadThread (struct tunread_arg *arg) { + + DWORD dwThreadId; + + return(CreateThread(NULL, /* security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)tunReadThread, /* thread function */ + (void*)arg, /* argument to thread function */ + 0, /* thread creation flags */ + &dwThreadId)); /* thread id out */ +} + + + +int get_best_interface_ip (n2n_edge_t * eee, dec_ip_str_t ip_addr){ + DWORD interface_index = -1; + DWORD dwRetVal = 0; + PIP_ADAPTER_INFO pAdapterInfo = NULL, pAdapter = NULL; + macstr_t mac_buf; + ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); + + dwRetVal = GetBestInterface(*(IPAddr*)(&eee->curr_sn->sock.addr.v4), &interface_index); + if(dwRetVal != NO_ERROR) return -1; + + pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen); + if(pAdapterInfo == NULL) { + traceEvent(TRACE_INFO, "Error allocating memory needed to call GetAdaptersInfo\n"); + return -1; + } + + dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); + if(dwRetVal == ERROR_BUFFER_OVERFLOW) { + pAdapterInfo = (PIP_ADAPTER_INFO)realloc(pAdapterInfo, ulOutBufLen); + if(pAdapterInfo == NULL) { + traceEvent(TRACE_INFO, "Error allocating memory needed to call GetAdaptersInfo\n"); + return -1; + } + } + + dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); +// hexdump((uint8_t*)pAdapterInfo, ulOutBufLen); + if(dwRetVal == NO_ERROR) { + for(pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next) { + if(pAdapter->Index != interface_index) continue; + + traceEvent(TRACE_DEBUG, "Adapter Index: %ld\n", pAdapter->Index); + traceEvent(TRACE_DEBUG, "Combo Index: %ld\n", pAdapter->ComboIndex); + traceEvent(TRACE_DEBUG, "Adapter Name: %s\n", pAdapter->AdapterName); + traceEvent(TRACE_DEBUG, "Adapter Desc: %s\n", pAdapter->Description); + traceEvent(TRACE_DEBUG, "Adapter Type: %u\n", pAdapter->Type); + macaddr_str(mac_buf, pAdapter->Address); + traceEvent(TRACE_DEBUG, "Adapter Addr: %s\n", mac_buf); + traceEvent(TRACE_DEBUG, "DHCP Enabled: %u\n", pAdapter->DhcpEnabled); + traceEvent(TRACE_DEBUG, "DHCP Server: %s\n", pAdapter->DhcpServer.IpAddress.String); + traceEvent(TRACE_DEBUG, "IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String); + traceEvent(TRACE_DEBUG, "IP Mask: %s\n", pAdapter->IpAddressList.IpMask.String); + traceEvent(TRACE_DEBUG, "Gateway: %s\n", pAdapter->GatewayList.IpAddress.String); + strncpy(ip_addr, pAdapter->IpAddressList.IpAddress.String, sizeof(dec_ip_str_t)-1); + } + } else { + traceEvent(TRACE_WARNING, "GetAdaptersInfo failed with error: %d\n", dwRetVal); + } + if(pAdapterInfo != NULL) { + free(pAdapterInfo); + pAdapterInfo = NULL; + } + return 0; +} + + +#endif + diff --git a/bundles/n2n_ntop_v3/src/example_edge_embed.c b/bundles/n2n_ntop_v3/src/example_edge_embed.c new file mode 100644 index 00000000..3c926ce9 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/example_edge_embed.c @@ -0,0 +1,78 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +static int keep_running; + +int main() { + + n2n_edge_conf_t conf; + tuntap_dev tuntap; + n2n_edge_t *eee; + int rc; + + edge_init_conf_defaults(&conf); + conf.allow_p2p = 1; // Whether to allow peer-to-peer communication + conf.allow_routing = 1; // Whether to allow the edge to route packets to other edges + snprintf((char *)conf.community_name, sizeof(conf.community_name), "%s", "mycommunity"); // Community to connect to + conf.disable_pmtu_discovery = 1; // Whether to disable the path MTU discovery + conf.drop_multicast = 0; // Whether to disable multicast + conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; // How to set the IP address + conf.encrypt_key = "mysecret"; // Secret to decrypt & encrypt with + conf.local_port = 0; // What port to use (0 = any port) + conf.mgmt_port = N2N_EDGE_MGMT_PORT; // Edge management port (5644 by default) + conf.register_interval = 1; // Interval for both UDP NAT hole punching and supernode registration + conf.register_ttl = 1; // Interval for UDP NAT hole punching through supernode + edge_conf_add_supernode(&conf, "localhost:1234"); // Supernode to connect to + conf.tos = 16; // Type of service for sent packets + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; // Use the twofish encryption + + if(edge_verify_conf(&conf) != 0) { + return -1; + } + + if(tuntap_open(&tuntap, + "edge0", // Name of the device to create + "static", // IP mode; static|dhcp + "10.0.0.1", // Set ip address + "255.255.255.0", // Netmask to use + "DE:AD:BE:EF:01:10", // Set mac address + DEFAULT_MTU // MTU to use +#ifdef WIN32 + , 0 +#endif + ) < 0) + { + return -1; + } + + eee = edge_init(&conf, &rc); + if(eee == NULL) { + exit(1); + } + + keep_running = 1; + eee->keep_running = &keep_running; + rc = run_edge_loop(eee); + + edge_term(eee); + tuntap_close(&tuntap); + + return rc; +} diff --git a/bundles/n2n_ntop_v3/src/example_edge_embed_quick_edge_init.c b/bundles/n2n_ntop_v3/src/example_edge_embed_quick_edge_init.c new file mode 100644 index 00000000..148655a5 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/example_edge_embed_quick_edge_init.c @@ -0,0 +1,55 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +/* + This tool demonstrates how to easily embed + n2n on an existing application + */ + +int main (int argc, char* argv[]) { + + char *device_name = (char*)"n2n0"; + char *network_name = (char*)"mynetwork"; + char *secret_key = (char*)"mysecret"; + char *my_mac_address = (char*)"DE:AD:BE:EF:01:10"; + char *my_ipv4_addr = (char*)"1.2.3.4"; + char *supernode = (char*)"7.8.9.10:1234"; + int keep_on_running = 1; + + /* Increase tracelevel to see what's happening */ + setTraceLevel(10); + + /* Random seed */ + n2n_srand(n2n_seed()); + + /* + NOTE + + As the function below won't end, you should + call it inside a separate thread + */ + return(quick_edge_init(device_name, + network_name, + secret_key, + my_mac_address, + my_ipv4_addr, + supernode, + &keep_on_running)); +} diff --git a/bundles/n2n_ntop_v3/src/example_sn_embed.c b/bundles/n2n_ntop_v3/src/example_sn_embed.c new file mode 100644 index 00000000..0f5b679a --- /dev/null +++ b/bundles/n2n_ntop_v3/src/example_sn_embed.c @@ -0,0 +1,51 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +static int keep_running; + +int main () { + + n2n_sn_t sss_node; + int rc; + + sn_init_defaults(&sss_node); + sss_node.daemon = 0; // Whether to daemonize + sss_node.lport = 1234; // Main UDP listen port + + sss_node.sock = open_socket(sss_node.lport, INADDR_ANY, 0 /* UDP */); + if(-1 == sss_node.sock) { + exit(-2); + } + + sss_node.mgmt_sock = open_socket(5645, INADDR_LOOPBACK, 0 /* UDP */); // Main UDP management port + if(-1 == sss_node.mgmt_sock) { + exit(-2); + } + + sn_init(&sss_node); + + keep_running = 1; + sss_node.keep_running = &keep_running; + rc = run_sn_loop(&sss_node); + + sn_term(&sss_node); + + return rc; +} diff --git a/bundles/n2n_ntop_v3/src/header_encryption.c b/bundles/n2n_ntop_v3/src/header_encryption.c new file mode 100644 index 00000000..462982af --- /dev/null +++ b/bundles/n2n_ntop_v3/src/header_encryption.c @@ -0,0 +1,170 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) + + +int packet_header_decrypt (uint8_t packet[], uint16_t packet_len, + char *community_name, + he_context_t *ctx, he_context_t *ctx_iv, + uint64_t *stamp) { + + // try community name as possible key and check for magic bytes "n2__" + uint32_t magic = 0x6E320000; + uint32_t test_magic; + uint32_t checksum_high = 0; + + // check for magic + // so, as a first step, decrypt last 4 bytes from where originally the community name would be + speck_ctr((uint8_t*)&test_magic, &packet[16], 4, packet, (speck_context_t*)ctx); + test_magic = be32toh(test_magic); + + //extract header length (lower 2 bytes) + uint32_t header_len = test_magic - magic; + + if(header_len <= packet_len) { + // decrypt the complete header + speck_ctr(&packet[16], &packet[16], header_len - 16, packet, (speck_context_t*)ctx); + + // extract time stamp and un-xor actual checksum (calculated here) from it + // if payload was altered (different checksum than original), time stamp verification will fail + // use speck block cipher step (1 block == 128 bit == 16 bytes) + speck_128_decrypt(packet, (speck_context_t*)ctx_iv); + + // extract the required data + *stamp = be64toh(*(uint64_t*)&packet[4]); + checksum_high = be32toh(*(uint32_t*)packet); + + // restore original packet order before calculating checksum + memcpy(&packet[0], &packet[20], 4); + memcpy(&packet[4], community_name, N2N_COMMUNITY_SIZE); + uint64_t checksum = pearson_hash_64(packet, packet_len); + + if((checksum >> 32) != checksum_high) { + traceEvent(TRACE_DEBUG, "packet_header_decrypt dropped a packet with invalid checksum."); + + // unsuccessful + return 0; + } + + *stamp = *stamp ^ (checksum << 32); + + // successful + return 1; + } else { + + // unsuccessful + return 0; + } +} + + +int packet_header_encrypt (uint8_t packet[], uint16_t header_len, uint16_t packet_len, + he_context_t *ctx, he_context_t *ctx_iv, + uint64_t stamp) { + + uint32_t *p32 = (uint32_t*)packet; + uint64_t *p64 = (uint64_t*)packet; + uint64_t checksum = 0; + uint32_t magic = 0x6E320000; /* == ASCII "n2__" */ + magic += header_len; + + if(packet_len < 24) { + traceEvent(TRACE_DEBUG, "packet_header_encrypt dropped a packet too short to be valid."); + return -1; + } + // we trust in the caller assuring header_len <= packet_len + + checksum = pearson_hash_64(packet, packet_len); + + // re-order packet + p32[5] = p32[0]; + + // add time stamp, checksum, and random to form the pre-IV + p64[0] = htobe64(checksum); + + p32[1] = p32[1] ^ htobe32((uint32_t)(stamp >> 32)); + p32[2] = htobe32((uint32_t)stamp); + + p32[3] = n2n_rand(); + + // encrypt this pre-IV to IV + speck_128_encrypt(packet, (speck_context_t*)ctx_iv); + + // place IV plus magic in packet + p32[4] = htobe32(magic); + + // encrypt, starting from magic + speck_ctr(&packet[16], &packet[16], header_len - 16, packet, (speck_context_t*)ctx); + + return 0; +} + + +void packet_header_setup_key (const char *community_name, + he_context_t **ctx_static, he_context_t **ctx_dynamic, + he_context_t **ctx_iv_static, he_context_t **ctx_iv_dynamic) { + + uint8_t key[16]; + + // for REGISTER_SUPER, REGISTER_SUPER_ACK, REGISTER_SUPER_NAK only; + // for all other packets, same as static by default (changed by user/pw auth scheme + // calling packet_header_change_dynamic_key later) + + pearson_hash_128(key, (uint8_t*)community_name, N2N_COMMUNITY_SIZE); + + if(!*ctx_static) + *ctx_static = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)ctx_static, key, 128); + + if(!*ctx_dynamic) + *ctx_dynamic = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)ctx_dynamic, key, 128); + + // hash again and use as key for IV encryption + pearson_hash_128(key, key, sizeof(key)); + + if(!*ctx_iv_static) + *ctx_iv_static = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)ctx_iv_static, key, 128); + + if(!*ctx_iv_dynamic) + *ctx_iv_dynamic = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)ctx_iv_dynamic, key, 128); +} + + +void packet_header_change_dynamic_key (uint8_t *key_dynamic, + he_context_t **ctx_dynamic, he_context_t **ctx_iv_dynamic) { + + uint8_t key[16]; + pearson_hash_128(key, key_dynamic, N2N_AUTH_CHALLENGE_SIZE); + + // for REGISTER_SUPER, REGISTER_SUPER_ACK, REGISTER_SUPER_NAK only + // for all other packets, same as static by default (changed by user/pw auth scheme) + speck_init((speck_context_t**)ctx_dynamic, key, 128); + + // hash again and use as key for IV encryption + // REMOVE as soon as checksum and replay protection get their own fields + pearson_hash_128(key, key, sizeof(key)); + speck_init((speck_context_t**)ctx_iv_dynamic, key, 128); +} diff --git a/bundles/n2n_ntop_v3/src/hexdump.c b/bundles/n2n_ntop_v3/src/hexdump.c new file mode 100644 index 00000000..75093b75 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/hexdump.c @@ -0,0 +1,45 @@ + +#include + +#include "n2n.h" +#include "hexdump.h" + +void fhexdump(unsigned int display_addr, void *in, int size, FILE *stream) { + uint8_t *p = in; + + while(size>0) { + int i; + + fprintf(stream, "%03x: ", display_addr); + + for (i = 0; i < 16; i++) { + if (i < size) { + fprintf(stream, "%02x", p[i]); + } else { + fprintf(stream, " "); + } + if (i==7) { + fprintf(stream, " "); + } else { + fprintf(stream, " "); + } + } + fprintf(stream, " |"); + + for (i = 0; i < 16; i++) { + if (i < size) { + char ch = p[i]; + if (ch>=0x20 && ch<=0x7e) { + fprintf(stream, "%c", ch); + } else { + fprintf(stream, " "); + } + } + } + fprintf(stream, "|\n"); + + size -= 16; + display_addr += 16; + p += 16; + } +} diff --git a/bundles/n2n_ntop_v3/src/minilzo.c b/bundles/n2n_ntop_v3/src/minilzo.c new file mode 100644 index 00000000..8fd86645 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/minilzo.c @@ -0,0 +1,6365 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO 1 + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if 0 +#elif !defined(__LZO_LANG_OVERRIDE) +#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) +# if (__ASSEMBLER__+0) <= 0 +# error "__ASSEMBLER__" +# else +# define LZO_LANG_ASSEMBLER 1 +# endif +#elif defined(__cplusplus) +# if (__cplusplus+0) <= 0 +# error "__cplusplus" +# elif (__cplusplus < 199711L) +# define LZO_LANG_CXX 1 +# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 +# define LZO_LANG_CXX _MSVC_LANG +# else +# define LZO_LANG_CXX __cplusplus +# endif +# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) +# define LZO_LANG_C __STDC_VERSION__ +# else +# define LZO_LANG_C 1 +# endif +#endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(_MSC_VER) && defined(M_I86HM) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# define LZO_CC_CLANG_C2 _MSC_VER +# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 +# define LZO_INFO_CC "clang/c2" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# if defined(__APPLE_CC__) +# define LZO_CC_CLANG_VENDOR_APPLE 1 +# define LZO_INFO_CC "clang/apple" +# else +# define LZO_CC_CLANG_VENDOR_LLVM 1 +# define LZO_INFO_CC "clang" +# endif +# if defined(__clang_version__) +# define LZO_INFO_CCVER __clang_version__ +# else +# define LZO_INFO_CCVER __VERSION__ +# endif +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) || defined(_M_ARM64) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__riscv) +# define LZO_ARCH_RISCV 1 +# define LZO_INFO_ARCH "riscv" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if !defined(LZO_ARCH_ARM_THUMB2) +#if (LZO_ARCH_ARM) +# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) +# if defined(__thumb2__) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) +# define LZO_ARCH_ARM_THUMB2 1 +# endif +# endif +#endif +#endif +#if (LZO_ARCH_ARM_THUMB2) +# undef LZO_INFO_ARCH +# define LZO_INFO_ARCH "arm_thumb2" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON) && ((__ARM_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(__cplusplus) +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#if defined(__cplusplus) +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin +#endif +#endif +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 +#endif +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute +#endif +#endif +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 +#endif +#if !defined(lzo_has_declspec_attribute) +#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) +# define lzo_has_declspec_attribute __has_declspec_attribute +#endif +#endif +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 +#endif +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature +#endif +#endif +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 +#endif +#if !defined(lzo_has_extension) +#if (LZO_CC_CLANG) && defined(__has_extension) +# define lzo_has_extension __has_extension +#elif (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_extension __has_feature +#endif +#endif +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_RESULT) +# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_very_likely) +# ifndef __lzo_HAVE_very_likely +# define __lzo_HAVE_very_likely 1 +# endif +#else +# define __lzo_very_likely(e) __lzo_likely(e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if defined(__lzo_very_unlikely) +# ifndef __lzo_HAVE_very_unlikely +# define __lzo_HAVE_very_unlikely 1 +# endif +#else +# define __lzo_very_unlikely(e) __lzo_unlikely(e) +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#if !defined(lzo_unused_funcs_impl) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f +# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) +# define lzo_unused_funcs_impl(r,f) static r f +# else +# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +#if (LZO_LANG_ASSEMBLER) +# undef LZO_COMPILE_TIME_ASSERT_HEADER +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ +#else +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#define LZO_SIZEOF_CHAR 1 +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_ARM64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# else +# define LZO_SIZEOF_VOID_P 4 +# endif +# else + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) +# define LZO_ABI_IP32W64 1 +# ifndef LZO_INFO_ABI_PM +# define LZO_INFO_ABI_PM "ip32w64" +# endif +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# if ((__ARM_FEATURE_UNALIGNED)+0) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +# elif 1 && (LZO_ARCH_ARM_THUMB2) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_RISCV) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#define LZO_TYPEOF_CHAR 1u +#define LZO_TYPEOF_SHORT 2u +#define LZO_TYPEOF_INT 3u +#define LZO_TYPEOF_LONG 4u +#define LZO_TYPEOF_LONG_LONG 5u +#define LZO_TYPEOF___INT8 17u +#define LZO_TYPEOF___INT16 18u +#define LZO_TYPEOF___INT32 19u +#define LZO_TYPEOF___INT64 20u +#define LZO_TYPEOF___INT128 21u +#define LZO_TYPEOF___INT256 22u +#define LZO_TYPEOF___MODE_QI 33u +#define LZO_TYPEOF___MODE_HI 34u +#define LZO_TYPEOF___MODE_SI 35u +#define LZO_TYPEOF___MODE_DI 36u +#define LZO_TYPEOF___MODE_TI 37u +#define LZO_TYPEOF_CHAR_P 129u +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +# if !(LZO_LANG_ASSEMBLER) + __lzo_gnuc_extension__ typedef long long lzo_llong_t__; + __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# endif +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T +#endif +#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# endif +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T +#endif +#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) +# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 +# endif +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +#else +#endif +#endif +#if defined(lzo_int64e_t) +# define LZO_SIZEOF_LZO_INT64E_T 8 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 +# if !(LZO_LANG_ASSEMBLER) + typedef char * lzo_intptr_t; + typedef char * lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) +# if !(LZO_LANG_ASSEMBLER) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 +# if !(LZO_LANG_ASSEMBLER) + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# endif +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x20a0) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H 1 +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H 1 + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#if defined(LZO_CFG_BUILD_DLL) && (LZO_CFG_BUILD_DLL+0) && !defined(__LZO_EXPORT1) && !defined(__LZO_EXPORT2) && 0 +#ifndef __LZODEFS_H_INCLUDED +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#endif +#endif +#include +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) +# include LZO_CFG_EXTRA_CONFIG_HEADER2 +#endif +#endif + +#if !defined(__LZOCONF_H_INCLUDED) || (LZO_VERSION+0 != 0x20a0) +# error "version mismatch" +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100)) +# pragma warning(disable: 4702) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +# pragma warning(disable: 4514 4710 4711) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1800)) +# pragma warning(disable: 4746) +#endif +#if (LZO_CC_INTELC && (__INTEL_COMPILER >= 900)) +# pragma warning(disable: 1684) +#endif + +#if (LZO_CC_SUNPROC) +#if !defined(__cplusplus) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +# pragma error_messages(off,E_STATEMENT_NOT_REACHED) +#endif +#endif + +#if !defined(__LZO_NOEXPORT1) +# define __LZO_NOEXPORT1 /*empty*/ +#endif +#if !defined(__LZO_NOEXPORT2) +# define __LZO_NOEXPORT2 /*empty*/ +#endif + +#if 1 +# define LZO_PUBLIC_DECL(r) LZO_EXTERN(r) +#endif +#if 1 +# define LZO_PUBLIC_IMPL(r) LZO_PUBLIC(r) +#endif +#if !defined(LZO_LOCAL_DECL) +# define LZO_LOCAL_DECL(r) __LZO_EXTERN_C LZO_LOCAL_IMPL(r) +#endif +#if !defined(LZO_LOCAL_IMPL) +# define LZO_LOCAL_IMPL(r) __LZO_NOEXPORT1 r __LZO_NOEXPORT2 __LZO_CDECL +#endif +#if 1 +# define LZO_STATIC_DECL(r) LZO_PRIVATE(r) +#endif +#if 1 +# define LZO_STATIC_IMPL(r) LZO_PRIVATE(r) +#endif + +#if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING) +#elif 1 +# include +#else +# define LZO_WANT_ACC_INCD_H 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define LZO_CFG_NO_CONFIG_HEADER 1 +#endif + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1) +#endif +#if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2) +#endif +#if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4) +#endif +#if defined(lzo_int64_t) || defined(lzo_uint64_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8) +#endif + +#if (LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#else +# undef lzo_memcmp +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#else +# undef lzo_memcpy +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#else +# undef lzo_memmove +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#else +# undef lzo_memset +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if (LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if (LZO_CFG_PGO) +# undef __lzo_likely +# undef __lzo_unlikely +# define __lzo_likely(e) (e) +# define __lzo_unlikely(e) (e) +#endif + +#undef _ +#undef __ +#undef ___ +#undef ____ +#undef _p0 +#undef _p1 +#undef _p2 +#undef _p3 +#undef _p4 +#undef _s0 +#undef _s1 +#undef _s2 +#undef _s3 +#undef _s4 +#undef _ww + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#ifndef __LZO_FUNC_H +#define __LZO_FUNC_H 1 + +#if !defined(LZO_BITOPS_USE_ASM_BITSCAN) && !defined(LZO_BITOPS_USE_GNUC_BITSCAN) && !defined(LZO_BITOPS_USE_MSC_BITSCAN) +#if 1 && (LZO_ARCH_AMD64) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_ASM_SYNTAX_GNUC) +#define LZO_BITOPS_USE_ASM_BITSCAN 1 +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul)))) +#define LZO_BITOPS_USE_GNUC_BITSCAN 1 +#elif (LZO_OS_WIN32 || LZO_OS_WIN64) && ((LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 1010)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#define LZO_BITOPS_USE_MSC_BITSCAN 1 +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#include +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64) +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif +#endif +#endif + +__lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanReverse(&r, v); return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT == 4) + unsigned r; r = (unsigned) __builtin_clz(v); return r; +#define lzo_bitops_ctlz32(v) ((unsigned) __builtin_clz(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzl(v); return r ^ 32; +#define lzo_bitops_ctlz32(v) (((unsigned) __builtin_clzl(v)) ^ 32) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanReverse64(&r, v); return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzl(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzll(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +__lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanForward(&r, v); return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT >= 4) + unsigned r; r = (unsigned) __builtin_ctz(v); return r; +#define lzo_bitops_cttz32(v) ((unsigned) __builtin_ctz(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanForward64(&r, v); return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzl(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzll(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +lzo_unused_funcs_impl(void, lzo_bitops_unused_funcs)(void) +{ + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); + LZO_UNUSED_FUNC(lzo_bitops_ctlz32_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz32_func); +#if defined(lzo_uint64_t) + LZO_UNUSED_FUNC(lzo_bitops_ctlz64_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz64_func); +#endif +} + +#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED) +#if !defined(lzo_memops_tcheck__) && 0 +#define lzo_memops_tcheck__(t,a,b) ((void)0, sizeof(t) == (a) && __lzo_alignof(t) == (b)) +#endif +#endif +#ifndef lzo_memops_TU0p +#define lzo_memops_TU0p void __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU1p +#define lzo_memops_TU1p unsigned char __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU2p +#if (LZO_OPT_UNALIGNED16) +typedef lzo_uint16_t __lzo_may_alias lzo_memops_TU2; +#define lzo_memops_TU2p volatile lzo_memops_TU2 * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU2_struct,2) +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#else +struct lzo_memops_TU2_struct { unsigned char a[2]; } __lzo_may_alias; +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#endif +#ifndef lzo_memops_TU2p +#define lzo_memops_TU2p lzo_memops_TU2 * +#endif +#endif +#ifndef lzo_memops_TU4p +#if (LZO_OPT_UNALIGNED32) +typedef lzo_uint32_t __lzo_may_alias lzo_memops_TU4; +#define lzo_memops_TU4p volatile lzo_memops_TU4 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU4_struct,4) +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#else +struct lzo_memops_TU4_struct { unsigned char a[4]; } __lzo_may_alias; +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#endif +#ifndef lzo_memops_TU4p +#define lzo_memops_TU4p lzo_memops_TU4 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_TU8p +#if (LZO_OPT_UNALIGNED64) +typedef lzo_uint64_t __lzo_may_alias lzo_memops_TU8; +#define lzo_memops_TU8p volatile lzo_memops_TU8 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU8_struct,8) +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#else +struct lzo_memops_TU8_struct { unsigned char a[8]; } __lzo_may_alias; +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#endif +#ifndef lzo_memops_TU8p +#define lzo_memops_TU8p lzo_memops_TU8 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_set_TU1p +#define lzo_memops_set_TU1p volatile lzo_memops_TU1p +#endif +#ifndef lzo_memops_move_TU1p +#define lzo_memops_move_TU1p lzo_memops_TU1p +#endif +#define LZO_MEMOPS_SET1(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__1 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__1[0] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET2(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__2 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__2[0] = LZO_BYTE(cc); d__2[1] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET3(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__3 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__3[0] = LZO_BYTE(cc); d__3[1] = LZO_BYTE(cc); d__3[2] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET4(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__4 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__4[0] = LZO_BYTE(cc); d__4[1] = LZO_BYTE(cc); d__4[2] = LZO_BYTE(cc); d__4[3] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE1(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__1 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__1 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__1[0] = s__1[0]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE2(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__2 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__2 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__2[0] = s__2[0]; d__2[1] = s__2[1]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE3(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__3 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__3 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__3[0] = s__3[0]; d__3[1] = s__3[1]; d__3[2] = s__3[2]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE4(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__4 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__4 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__4[0] = s__4[0]; d__4[1] = s__4[1]; d__4[2] = s__4[2]; d__4[3] = s__4[3]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE8(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__8 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__8 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__8[0] = s__8[0]; d__8[1] = s__8[1]; d__8[2] = s__8[2]; d__8[3] = s__8[3]; \ + d__8[4] = s__8[4]; d__8[5] = s__8[5]; d__8[6] = s__8[6]; d__8[7] = s__8[7]; \ + LZO_BLOCK_END +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU1p)0)==1) +#define LZO_MEMOPS_COPY1(dd,ss) LZO_MEMOPS_MOVE1(dd,ss) +#if (LZO_OPT_UNALIGNED16) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) +#define LZO_MEMOPS_COPY2(dd,ss) \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY2(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU2,2,1)) { \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE2(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY2(dd,ss) LZO_MEMOPS_MOVE2(dd,ss) +#endif +#if (LZO_OPT_UNALIGNED32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) +#define LZO_MEMOPS_COPY4(dd,ss) \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY4(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU4,4,1)) { \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE4(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY4(dd,ss) LZO_MEMOPS_MOVE4(dd,ss) +#endif +#if (LZO_WORDSIZE != 8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#else +#if (LZO_OPT_UNALIGNED64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) +#elif (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU8,8,1)) { \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE8(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY8(dd,ss) LZO_MEMOPS_MOVE8(dd,ss) +#endif +#endif +#define LZO_MEMOPS_COPYN(dd,ss,nn) \ + LZO_BLOCK_BEGIN \ + lzo_memops_TU1p d__n = (lzo_memops_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_TU1p s__n = (const lzo_memops_TU1p) (const lzo_memops_TU0p) (ss); \ + lzo_uint n__n = (nn); \ + while ((void)0, n__n >= 8) { LZO_MEMOPS_COPY8(d__n, s__n); d__n += 8; s__n += 8; n__n -= 8; } \ + if ((void)0, n__n >= 4) { LZO_MEMOPS_COPY4(d__n, s__n); d__n += 4; s__n += 4; n__n -= 4; } \ + if ((void)0, n__n > 0) do { *d__n++ = *s__n++; } while (--n__n > 0); \ + LZO_BLOCK_END + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_voidp ss) +{ + lzo_uint16_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(&v, ss); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU2p s = (const lzo_memops_TU2p) ss; + unsigned long vv; + __asm__("lhbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint16_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint16_t) (((lzo_uint16_t)s[0]) | ((lzo_uint16_t)s[1] << 8)); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_LE16(ss) lzo_memops_get_le16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_voidp ss) +{ + lzo_uint32_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(&v, ss); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU4p s = (const lzo_memops_TU4p) ss; + unsigned long vv; + __asm__("lwbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint32_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint32_t) (((lzo_uint32_t)s[0]) | ((lzo_uint32_t)s[1] << 8) | ((lzo_uint32_t)s[2] << 16) | ((lzo_uint32_t)s[3] << 24)); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_LE32(ss) lzo_memops_get_le32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) +#endif + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_voidp ss) +{ + lzo_uint16_t v; + LZO_MEMOPS_COPY2(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED16) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) +#define LZO_MEMOPS_GET_NE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_NE16(ss) lzo_memops_get_ne16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_voidp ss) +{ + lzo_uint32_t v; + LZO_MEMOPS_COPY4(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) +#define LZO_MEMOPS_GET_NE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_NE32(ss) lzo_memops_get_ne32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) +#define LZO_MEMOPS_GET_NE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) +#endif + +__lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint16_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(dd, &vv); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU2p d = (lzo_memops_TU2p) dd; + unsigned long v = vv; + __asm__("sthbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE16(dd,vv) lzo_memops_put_le16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint32_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(dd, &vv); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU4p d = (lzo_memops_TU4p) dd; + unsigned long v = vv; + __asm__("stwbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); + d[2] = LZO_BYTE((vv >> 16) & 0xff); + d[3] = LZO_BYTE((vv >> 24) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE32(dd,vv) lzo_memops_put_le32(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint16_t vv) +{ + LZO_MEMOPS_COPY2(dd, &vv); +} +#if (LZO_OPT_UNALIGNED16) +#define LZO_MEMOPS_PUT_NE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE16(dd,vv) lzo_memops_put_ne16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint32_t vv) +{ + LZO_MEMOPS_COPY4(dd, &vv); +} +#if (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_PUT_NE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE32(dd,vv) lzo_memops_put_ne32(dd,vv) +#endif + +lzo_unused_funcs_impl(void, lzo_memops_unused_funcs)(void) +{ + LZO_UNUSED_FUNC(lzo_memops_unused_funcs); + LZO_UNUSED_FUNC(lzo_memops_get_le16); + LZO_UNUSED_FUNC(lzo_memops_get_le32); + LZO_UNUSED_FUNC(lzo_memops_get_ne16); + LZO_UNUSED_FUNC(lzo_memops_get_ne32); + LZO_UNUSED_FUNC(lzo_memops_put_le16); + LZO_UNUSED_FUNC(lzo_memops_put_le32); + LZO_UNUSED_FUNC(lzo_memops_put_ne16); + LZO_UNUSED_FUNC(lzo_memops_put_ne32); +} + +#endif + +#ifndef UA_SET1 +#define UA_SET1 LZO_MEMOPS_SET1 +#endif +#ifndef UA_SET2 +#define UA_SET2 LZO_MEMOPS_SET2 +#endif +#ifndef UA_SET3 +#define UA_SET3 LZO_MEMOPS_SET3 +#endif +#ifndef UA_SET4 +#define UA_SET4 LZO_MEMOPS_SET4 +#endif +#ifndef UA_MOVE1 +#define UA_MOVE1 LZO_MEMOPS_MOVE1 +#endif +#ifndef UA_MOVE2 +#define UA_MOVE2 LZO_MEMOPS_MOVE2 +#endif +#ifndef UA_MOVE3 +#define UA_MOVE3 LZO_MEMOPS_MOVE3 +#endif +#ifndef UA_MOVE4 +#define UA_MOVE4 LZO_MEMOPS_MOVE4 +#endif +#ifndef UA_MOVE8 +#define UA_MOVE8 LZO_MEMOPS_MOVE8 +#endif +#ifndef UA_COPY1 +#define UA_COPY1 LZO_MEMOPS_COPY1 +#endif +#ifndef UA_COPY2 +#define UA_COPY2 LZO_MEMOPS_COPY2 +#endif +#ifndef UA_COPY3 +#define UA_COPY3 LZO_MEMOPS_COPY3 +#endif +#ifndef UA_COPY4 +#define UA_COPY4 LZO_MEMOPS_COPY4 +#endif +#ifndef UA_COPY8 +#define UA_COPY8 LZO_MEMOPS_COPY8 +#endif +#ifndef UA_COPYN +#define UA_COPYN LZO_MEMOPS_COPYN +#endif +#ifndef UA_COPYN_X +#define UA_COPYN_X LZO_MEMOPS_COPYN +#endif +#ifndef UA_GET_LE16 +#define UA_GET_LE16 LZO_MEMOPS_GET_LE16 +#endif +#ifndef UA_GET_LE32 +#define UA_GET_LE32 LZO_MEMOPS_GET_LE32 +#endif +#ifdef LZO_MEMOPS_GET_LE64 +#ifndef UA_GET_LE64 +#define UA_GET_LE64 LZO_MEMOPS_GET_LE64 +#endif +#endif +#ifndef UA_GET_NE16 +#define UA_GET_NE16 LZO_MEMOPS_GET_NE16 +#endif +#ifndef UA_GET_NE32 +#define UA_GET_NE32 LZO_MEMOPS_GET_NE32 +#endif +#ifdef LZO_MEMOPS_GET_NE64 +#ifndef UA_GET_NE64 +#define UA_GET_NE64 LZO_MEMOPS_GET_NE64 +#endif +#endif +#ifndef UA_PUT_LE16 +#define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16 +#endif +#ifndef UA_PUT_LE32 +#define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32 +#endif +#ifndef UA_PUT_NE16 +#define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16 +#endif +#ifndef UA_PUT_NE32 +#define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32 +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_xint a_lzo_xint; + lzo_int16_t a_lzo_int16_t; + lzo_uint16_t a_lzo_uint16_t; + lzo_int32_t a_lzo_int32_t; + lzo_uint32_t a_lzo_uint32_t; +#if defined(lzo_uint64_t) + lzo_int64_t a_lzo_int64_t; + lzo_uint64_t a_lzo_uint64_t; +#endif + size_t a_size_t; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + void * a_void_p; + char * a_char_p; + unsigned char * a_uchar_p; + const void * a_c_void_p; + const char * a_c_char_p; + const unsigned char * a_c_uchar_p; + lzo_voidp a_lzo_voidp; + lzo_bytep a_lzo_bytep; + const lzo_voidp a_c_lzo_voidp; + const lzo_bytep a_c_lzo_bytep; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef LZO_DETERMINISTIC +#define LZO_DETERMINISTIC 1 +#endif + +#ifndef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 1 +#endif + +#if (LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#else + lzo_uintptr_t p, n; + if (size < 2) return 0; + p = __lzo_ptr_linear(ptr); +#if 0 + n = (((p + size - 1) / size) * size) - p; +#else + if ((size & (size - 1)) != 0) + return 0; + n = size; n = ((p + n - 1) & ~(n - 1)) - p; +#endif +#endif + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +static const char lzo_copyright_[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif +static const char lzo_version_string_[] = LZO_VERSION_STRING; +static const char lzo_version_date_[] = LZO_VERSION_DATE; + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ + return (const lzo_bytep) lzo_copyright_; +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return lzo_version_string_; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return lzo_version_date_; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return lzo_version_string_; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return lzo_version_date_; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1) +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2) +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4) +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8) + +LZO_PUBLIC(lzo_uint32_t) +lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32_t s1 = adler & 0xffff; + lzo_uint32_t s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) + const lzo_hbyte_p p1 = LZO_STATIC_CAST(const lzo_hbyte_p, s1); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, s2); + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int cc, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) + lzo_hbyte_p p = LZO_STATIC_CAST(lzo_hbyte_p, s); + unsigned char c = LZO_ITRUNC(unsigned char, cc); + if __lzo_likely(len > 0) do + *p++ = c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, cc, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_INIT) + +#if !defined(__LZO_IN_MINILZO) + +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT + + LZOCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + LZOCHK_ASSERT_IS_SIGNED_T(lzo_int) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) +#if !(__LZO_UINTPTR_T_IS_POINTER) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + +#endif +#undef LZOCHK_ASSERT + +union lzo_config_check_union { + lzo_uint a[2]; + unsigned char b[2*LZO_MAX(8,sizeof(lzo_uint))]; +#if defined(lzo_uint64_t) + lzo_uint64_t c[2]; +#endif +}; + +#if 0 +#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) +#else +static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) +{ + return (lzo_voidp) ((lzo_bytep) ptr + off); +} +#endif + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul)) +# if 0 + volatile +# endif +#endif + union lzo_config_check_union u; + lzo_voidp p; + unsigned r = 1; + + u.a[0] = u.a[1] = 0; + p = u2p(&u, 0); + r &= ((* (lzo_bytep) p) == 0); +#if !(LZO_CFG_NO_CONFIG_CHECK) +#if (LZO_ABI_BIG_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[0] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif + u.a[0] = u.a[1] = 0; + u.b[0] = 1; u.b[3] = 2; + p = u2p(&u, 1); + r &= UA_GET_NE16(p) == 0; + r &= UA_GET_LE16(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE16(p) == 128; + u.b[2] = 129; + r &= UA_GET_LE16(p) == LZO_UINT16_C(0x8180); +#if (LZO_ABI_BIG_ENDIAN) + r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8081); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8180); +#endif + u.a[0] = u.a[1] = 0; + u.b[0] = 3; u.b[5] = 4; + p = u2p(&u, 1); + r &= UA_GET_NE32(p) == 0; + r &= UA_GET_LE32(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE32(p) == 128; + u.b[2] = 129; u.b[3] = 130; u.b[4] = 131; + r &= UA_GET_LE32(p) == LZO_UINT32_C(0x83828180); +#if (LZO_ABI_BIG_ENDIAN) + r &= UA_GET_NE32(p) == LZO_UINT32_C(0x80818283); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + r &= UA_GET_NE32(p) == LZO_UINT32_C(0x83828180); +#endif +#if defined(UA_GET_NE64) + u.c[0] = u.c[1] = 0; + u.b[0] = 5; u.b[9] = 6; + p = u2p(&u, 1); + u.c[0] = u.c[1] = 0; + r &= UA_GET_NE64(p) == 0; +#if defined(UA_GET_LE64) + r &= UA_GET_LE64(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE64(p) == 128; +#endif +#endif +#if defined(lzo_bitops_ctlz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz32(v) == 31 - i; + r &= lzo_bitops_ctlz32_func(v) == 31 - i; + }} +#endif +#if defined(lzo_bitops_ctlz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz64(v) == 63 - i; + r &= lzo_bitops_ctlz64_func(v) == 63 - i; + }} +#endif +#if defined(lzo_bitops_cttz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz32(v) == i; + r &= lzo_bitops_cttz32_func(v) == i; + }} +#endif +#if defined(lzo_bitops_cttz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz64(v) == i; + r &= lzo_bitops_cttz64_func(v) == i; + }} +#endif +#endif + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT +#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef LZOCHK_ASSERT + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32_t)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#endif + +#define LZO1X 1 +#define LZO_EOF_CODE 1 +#define M2_MAX_OFFSET 0x0800 + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#if 1 && defined(UA_GET_LE32) +#undef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 0 +#undef lzo_dict_t +#define lzo_dict_t lzo_uint16_t +#endif + +#define LZO_NEED_DICT_H 1 +#ifndef D_BITS +#define D_BITS 14 +#endif +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#if 1 +#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) +#else +#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) +#endif + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H 1 + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X 1 +#endif + +#if !defined(__LZO_IN_MINILZO) +#include +#endif + +#ifndef LZO_EOF_CODE +#define LZO_EOF_CODE 1 +#endif +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 6 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 6 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +static void __attribute__((__unused__)) +#else +static void +#endif +DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if (LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if (LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) + +#ifndef DO_COMPRESS +#define DO_COMPRESS lzo1x_1_compress +#endif + +#if 1 && defined(DO_COMPRESS) && !defined(do_compress) +# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core) +#endif + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_uint ti, lzo_voidp wrkmem) +{ + const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - 20; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += ti < 4 ? 4 - ti : 0; + for (;;) + { + const lzo_bytep m_pos; +#if !(LZO_DETERMINISTIC) + LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); + lzo_uint m_len; + lzo_uint dindex; +next: + if __lzo_unlikely(ip >= ip_end) + break; + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if (LZO_OPT_UNALIGNED32) + if (UA_GET_NE32(m_pos) != UA_GET_NE32(ip)) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) +#endif + { +literal: + UPDATE_I(dict,0,dindex,ip,in); + ip += 1 + ((ip - ii) >> 5); + continue; + } + UPDATE_I(dict,0,dindex,ip,in); +#else + lzo_uint m_off; + lzo_uint m_len; + { + lzo_uint32_t dv; + lzo_uint dindex; +literal: + ip += 1 + ((ip - ii) >> 5); +next: + if __lzo_unlikely(ip >= ip_end) + break; + dv = UA_GET_LE32(ip); + dindex = DINDEX(dv,ip); + GINDEX(m_off,m_pos,in+dict,dindex,in); + UPDATE_I(dict,0,dindex,ip,in); + if __lzo_unlikely(dv != UA_GET_LE32(m_pos)) + goto literal; + } +#endif + + ii -= ti; ti = 0; + { + lzo_uint t = pd(ip,ii); + if (t != 0) + { + if (t <= 3) + { + op[-2] = LZO_BYTE(op[-2] | t); +#if (LZO_OPT_UNALIGNED32) + UA_COPY4(op, ii); + op += t; +#else + { do *op++ = *ii++; while (--t > 0); } +#endif + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + else if (t <= 16) + { + *op++ = LZO_BYTE(t - 3); + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += t; + } +#endif + else + { + if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + *op++ = 0; + while __lzo_unlikely(tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + do { + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += 16; ii += 16; t -= 16; + } while (t >= 16); if (t > 0) +#endif + { do *op++ = *ii++; while (--t > 0); } + } + } + } + m_len = 4; + { +#if (LZO_OPT_UNALIGNED64) + lzo_uint64_t v; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 8; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz64) + m_len += lzo_bitops_ctlz64(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (64 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (64 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz64) + m_len += lzo_bitops_cttz64(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#elif (LZO_OPT_UNALIGNED32) + lzo_uint32_t v; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if (v != 0) + break; + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz32) + m_len += lzo_bitops_ctlz32(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (32 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (32 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz32) + m_len += lzo_bitops_cttz32(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#else + if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { + do { + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (ip[m_len] == m_pos[m_len]); + } +#endif + } +m_len_done: + m_off = pd(ip,m_pos); + ip += m_len; + ii = ip; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + else + { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + goto next; + } + + *out_len = pd(op, out); + return pd(in_end,ii-ti); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_bytep ip = in; + lzo_bytep op = out; + lzo_uint l = in_len; + lzo_uint t = 0; + + while (l > 20) + { + lzo_uint ll = l; + lzo_uintptr_t ll_end; +#if 0 || (LZO_DETERMINISTIC) + ll = LZO_MIN(ll, 49152); +#endif + ll_end = (lzo_uintptr_t)ip + ll; + if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) + break; +#if (LZO_DETERMINISTIC) + lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); +#endif + t = do_compress(ip,ll,op,out_len,t,wrkmem); + ip += ll; + op += *out_len; + l -= ll; + } + t += l; + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] = LZO_BYTE(op[-2] | t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + UA_COPYN(op, ii, t); + op += t; + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN 1 +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ diff --git a/bundles/n2n_ntop_v3/src/n2n.c b/bundles/n2n_ntop_v3/src/n2n.c new file mode 100644 index 00000000..a3fa9597 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/n2n.c @@ -0,0 +1,951 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#include "sn_selection.h" + +#include "minilzo.h" + +#include + + + +/* ************************************** */ + +SOCKET open_socket (int local_port, in_addr_t address, int type /* 0 = UDP, TCP otherwise */) { + + SOCKET sock_fd; + struct sockaddr_in local_address; + int sockopt; + + if((int)(sock_fd = socket(PF_INET, ((type == 0) ? SOCK_DGRAM : SOCK_STREAM) , 0)) < 0) { + traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", + strerror(errno), sock_fd); + return(-1); + } + +#ifndef WIN32 + /* fcntl(sock_fd, F_SETFL, O_NONBLOCK); */ +#endif + + sockopt = 1; + setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); + + memset(&local_address, 0, sizeof(local_address)); + local_address.sin_family = AF_INET; + local_address.sin_port = htons(local_port); + local_address.sin_addr.s_addr = htonl(address); + + if(bind(sock_fd,(struct sockaddr*) &local_address, sizeof(local_address)) == -1) { + traceEvent(TRACE_ERROR, "Bind error on local port %u [%s]\n", local_port, strerror(errno)); + return(-1); + } + + return(sock_fd); +} + + +static int traceLevel = 2 /* NORMAL */; +static int useSyslog = 0, syslog_opened = 0; +static FILE *traceFile = NULL; + +int getTraceLevel () { + + return(traceLevel); +} + +void setTraceLevel (int level) { + + traceLevel = level; +} + +void setUseSyslog (int use_syslog) { + + useSyslog = use_syslog; +} + +void setTraceFile (FILE *f) { + + traceFile = f; +} + +void closeTraceFile () { + + if((traceFile != NULL) && (traceFile != stdout)) { + fclose(traceFile); + } +#ifndef WIN32 + if(useSyslog && syslog_opened) { + closelog(); + syslog_opened = 0; + } +#endif +} + +#define N2N_TRACE_DATESIZE 32 +void traceEvent (int eventTraceLevel, char* file, int line, char * format, ...) { + + va_list va_ap; + + if(traceFile == NULL) { + traceFile = stdout; + } + + if(eventTraceLevel <= traceLevel) { + char buf[1024]; + char out_buf[1280]; + char theDate[N2N_TRACE_DATESIZE]; + char *extra_msg = ""; + time_t theTime = time(NULL); + int i; + + /* We have two paths - one if we're logging, one if we aren't + * Note that the no-log case is those systems which don't support it(WIN32), + * those without the headers !defined(USE_SYSLOG) + * those where it's parametrically off... + */ + + memset(buf, 0, sizeof(buf)); + strftime(theDate, N2N_TRACE_DATESIZE, "%d/%b/%Y %H:%M:%S", localtime(&theTime)); + + va_start(va_ap, format); + vsnprintf(buf, sizeof(buf) - 1, format, va_ap); + va_end(va_ap); + + if(eventTraceLevel == 0 /* TRACE_ERROR */) { + extra_msg = "ERROR: "; + } else if(eventTraceLevel == 1 /* TRACE_WARNING */) { + extra_msg = "WARNING: "; + } + + while(buf[strlen(buf) - 1] == '\n') { + buf[strlen(buf) - 1] = '\0'; + } + +#ifndef WIN32 + if(useSyslog) { + if(!syslog_opened) { + openlog("n2n", LOG_PID, LOG_DAEMON); + syslog_opened = 1; + } + + snprintf(out_buf, sizeof(out_buf), "%s%s", extra_msg, buf); + syslog(LOG_INFO, "%s", out_buf); + } else { + for(i = strlen(file) - 1; i > 0; i--) { + if(file[i] == '/') { + i++; + break; + } + } + snprintf(out_buf, sizeof(out_buf), "%s [%s:%d] %s%s", theDate, &file[i], line, extra_msg, buf); + fprintf(traceFile, "%s\n", out_buf); + fflush(traceFile); + } +#else + /* this is the WIN32 code */ + for(i = strlen(file) - 1; i > 0; i--) { + if(file[i] == '\\') { + i++; + break; + } + } + snprintf(out_buf, sizeof(out_buf), "%s [%s:%d] %s%s", theDate, &file[i], line, extra_msg, buf); + fprintf(traceFile, "%s\n", out_buf); + fflush(traceFile); +#endif + } + +} + +/* *********************************************** */ + +/* addr should be in network order. Things are so much simpler that way. */ +char* intoa (uint32_t /* host order */ addr, char* buf, uint16_t buf_len) { + + char *cp, *retStr; + uint8_t byteval; + int n; + + cp = &buf[buf_len]; + *--cp = '\0'; + + n = 4; + do { + byteval = addr & 0xff; + *--cp = byteval % 10 + '0'; + byteval /= 10; + if(byteval > 0) { + *--cp = byteval % 10 + '0'; + byteval /= 10; + if(byteval > 0) { + *--cp = byteval + '0'; + } + } + *--cp = '.'; + addr >>= 8; + } while(--n > 0); + + /* Convert the string to lowercase */ + retStr = (char*)(cp + 1); + + return(retStr); +} + + +/** Convert subnet prefix bit length to host order subnet mask. */ +uint32_t bitlen2mask (uint8_t bitlen) { + + uint8_t i; + uint32_t mask = 0; + + for (i = 1; i <= bitlen; ++i) { + mask |= 1 << (32 - i); + } + + return mask; +} + + +/** Convert host order subnet mask to subnet prefix bit length. */ +uint8_t mask2bitlen (uint32_t mask) { + + uint8_t i, bitlen = 0; + + for (i = 0; i < 32; ++i) { + if((mask << i) & 0x80000000) { + ++bitlen; + } else { + break; + } + } + + return bitlen; +} + + +/* *********************************************** */ + +char * macaddr_str (macstr_t buf, + const n2n_mac_t mac) { + + snprintf(buf, N2N_MACSTR_SIZE, "%02X:%02X:%02X:%02X:%02X:%02X", + mac[0] & 0xFF, mac[1] & 0xFF, mac[2] & 0xFF, + mac[3] & 0xFF, mac[4] & 0xFF, mac[5] & 0xFF); + + return(buf); +} + +/* *********************************************** */ + +/** Resolve the supernode IP address. + * + */ +int supernode2sock (n2n_sock_t *sn, const n2n_sn_name_t addrIn) { + + n2n_sn_name_t addr; + char *supernode_host; + char *supernode_port; + int rv = 0; + int nameerr; + const struct addrinfo aihints = {0, PF_INET, 0, 0, 0, NULL, NULL, NULL}; + struct addrinfo * ainfo = NULL; + struct sockaddr_in * saddr; + + sn->family = AF_INVALID; + + memcpy(addr, addrIn, N2N_EDGE_SN_HOST_SIZE); + supernode_host = strtok(addr, ":"); + + if(supernode_host) { + supernode_port = strtok(NULL, ":"); + if(supernode_port) { + sn->port = atoi(supernode_port); + nameerr = getaddrinfo(supernode_host, NULL, &aihints, &ainfo); + if(0 == nameerr) { + /* ainfo s the head of a linked list if non-NULL. */ + if(ainfo && (PF_INET == ainfo->ai_family)) { + /* It is definitely and IPv4 address -> sockaddr_in */ + saddr = (struct sockaddr_in *)ainfo->ai_addr; + memcpy(sn->addr.v4, &(saddr->sin_addr.s_addr), IPV4_SIZE); + sn->family = AF_INET; + traceEvent(TRACE_INFO, "supernode2sock successfully resolves supernode IPv4 address for %s", supernode_host); + rv = 0; + } else { + /* Should only return IPv4 addresses due to aihints. */ + traceEvent(TRACE_WARNING, "supernode2sock fails to resolve supernode IPv4 address for %s", supernode_host); + rv = -1; + } + freeaddrinfo(ainfo); /* free everything allocated by getaddrinfo(). */ + } else { + traceEvent(TRACE_WARNING, "supernode2sock fails to resolve supernode host %s, %d: %s", supernode_host, nameerr, gai_strerror(nameerr)); + rv = -2; + } + } else { + traceEvent(TRACE_WARNING, "supernode2sock sees malformed supernode parameter (-l ) %s", addrIn); + rv = -3; + } + } else { + traceEvent(TRACE_WARNING, "supernode2sock sees malformed supernode parameter (-l ) %s", + addrIn); + rv = -4; + } + + ainfo = NULL; + + return rv; +} + + +N2N_THREAD_RETURN_DATATYPE resolve_thread(N2N_THREAD_PARAMETER_DATATYPE p) { + +#ifdef HAVE_PTHREAD + n2n_resolve_parameter_t *param = (n2n_resolve_parameter_t*)p; + n2n_resolve_ip_sock_t *entry, *tmp_entry; + time_t rep_time = N2N_RESOLVE_INTERVAL / 10; + time_t now; + + while(1) { + sleep(N2N_RESOLVE_INTERVAL / 60); /* wake up in-between to check for signaled requests */ + + // what's the time? + now = time(NULL); + + // lock access + pthread_mutex_lock(¶m->access); + + // is it time to resolve yet? + if(((param->request)) || ((now - param->last_resolved) > rep_time)) { + HASH_ITER(hh, param->list, entry, tmp_entry) { + // resolve + entry->error_code = supernode2sock(&entry->sock, entry->org_ip); + // if socket changed and no error + if(!sock_equal(&entry->sock, entry->org_sock) + && (!entry->error_code)) { + // flag the change + param->changed = 1; + } + } + param->last_resolved = now; + + // any request fulfilled + param->request = 0; + + // determine next resolver repetition (shorter time if resolver errors occured) + rep_time = N2N_RESOLVE_INTERVAL; + HASH_ITER(hh, param->list, entry, tmp_entry) { + if(entry->error_code) { + rep_time = N2N_RESOLVE_INTERVAL / 10; + break; + } + } + } + + // unlock access + pthread_mutex_unlock(¶m->access); + } +#endif +} + + +int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list) { + +#ifdef HAVE_PTHREAD + struct peer_info *sn, *tmp_sn; + n2n_resolve_ip_sock_t *entry; + int ret; + + // create parameter structure + *param = (n2n_resolve_parameter_t*)calloc(1, sizeof(n2n_resolve_parameter_t)); + if(*param) { + HASH_ITER(hh, sn_list, sn, tmp_sn) { + // create entries for those peers that come with ip_addr string (from command-line) + if(sn->ip_addr) { + entry = (n2n_resolve_ip_sock_t*)calloc(1, sizeof(n2n_resolve_ip_sock_t)); + if(entry) { + entry->org_ip = sn->ip_addr; + entry->org_sock = &(sn->sock); + memcpy(&(entry->sock), &(sn->sock), sizeof(n2n_sock_t)); + HASH_ADD(hh, (*param)->list, org_ip, sizeof(char*), entry); + } else + traceEvent(TRACE_WARNING, "resolve_create_thread was unable to add list entry for supernode '%s'", sn->ip_addr); + } + } + (*param)->check_interval = N2N_RESOLVE_CHECK_INTERVAL; + } else { + traceEvent(TRACE_WARNING, "resolve_create_thread was unable to create list of supernodes"); + return -1; + } + + // create thread + ret = pthread_create(&((*param)->id), NULL, resolve_thread, (void *)*param); + if(ret) { + traceEvent(TRACE_WARNING, "resolve_create_thread failed to create resolver thread with error number %d", ret); + return -1; + } + + pthread_mutex_init(&((*param)->access), NULL); + + return 0; +#endif +} + + +void resolve_cancel_thread (n2n_resolve_parameter_t *param) { + +#ifdef HAVE_PTHREAD + pthread_cancel(param->id); + free(param); +#endif +} + + +uint8_t resolve_check (n2n_resolve_parameter_t *param, uint8_t requires_resolution, time_t now) { + + uint8_t ret = requires_resolution; /* if trylock fails, it still requires resolution */ + +#ifdef HAVE_PTHREAD + n2n_resolve_ip_sock_t *entry, *tmp_entry; + n2n_sock_str_t sock_buf; + + if(NULL == param) + return ret; + + // check_interval and last_check do not need to be guarded by the mutex because + // their values get changed and evaluated only here + + if((now - param->last_checked > param->check_interval) || (requires_resolution)) { + // try to lock access + if(pthread_mutex_trylock(¶m->access) == 0) { + // any changes? + if(param->changed) { + // reset flag + param->changed = 0; + // unselectively copy all socks (even those with error code, that would be the old one because + // sockets do not get overwritten in case of error in resolve_thread) from list to supernode list + HASH_ITER(hh, param->list, entry, tmp_entry) { + memcpy(entry->org_sock, &entry->sock, sizeof(n2n_sock_t)); + traceEvent(TRACE_INFO, "resolve_check renews ip address of supernode '%s' to %s", + entry->org_ip, sock_to_cstr(sock_buf, &(entry->sock))); + } + } + + // let the resolver thread know eventual difficulties in reaching the supernode + if(requires_resolution) { + param->request = 1; + ret = 0; + } + + param->last_checked = now; + + // next appointment + if(param->request) + // earlier if resolver still working on fulfilling a request + param->check_interval = N2N_RESOLVE_CHECK_INTERVAL / 10; + else + param->check_interval = N2N_RESOLVE_CHECK_INTERVAL; + + // unlock access + pthread_mutex_unlock(¶m->access); + } + } +#endif + + return ret; +} + + +/* ************************************** */ + + +struct peer_info* add_sn_to_list_by_mac_or_sock (struct peer_info **sn_list, n2n_sock_t *sock, const n2n_mac_t mac, int *skip_add) { + + struct peer_info *scan, *tmp, *peer = NULL; + + if(!is_null_mac(mac)) { /* not zero MAC */ + HASH_FIND_PEER(*sn_list, mac, peer); + } + + if(peer == NULL) { /* zero MAC, search by socket */ + HASH_ITER(hh, *sn_list, scan, tmp) { + if(memcmp(&(scan->sock), sock, sizeof(n2n_sock_t)) == 0) { + // update mac if appropriate, needs to be deleted first because it is key to the hash list + if(!is_null_mac(mac)) { + HASH_DEL(*sn_list, scan); + memcpy(scan->mac_addr, mac, sizeof(n2n_mac_t)); + HASH_ADD_PEER(*sn_list, scan); + } + peer = scan; + break; + } + } + + if((peer == NULL) && (*skip_add == SN_ADD)) { + peer = (struct peer_info*)calloc(1, sizeof(struct peer_info)); + if(peer) { + sn_selection_criterion_default(&(peer->selection_criterion)); + peer->last_valid_time_stamp = initial_time_stamp(); + memcpy(&(peer->sock), sock, sizeof(n2n_sock_t)); + memcpy(peer->mac_addr, mac, sizeof(n2n_mac_t)); + HASH_ADD_PEER(*sn_list, peer); + *skip_add = SN_ADD_ADDED; + } + } + } + + return peer; +} + +/* ************************************************ */ + + +/* http://www.faqs.org/rfcs/rfc908.html */ +uint8_t is_multi_broadcast (const n2n_mac_t dest_mac) { + + int is_broadcast = (memcmp(broadcast_mac, dest_mac, N2N_MAC_SIZE) == 0); + int is_multicast = (memcmp(multicast_mac, dest_mac, 3) == 0) && !(dest_mac[3] >> 7); + int is_ipv6_multicast = (memcmp(ipv6_multicast_mac, dest_mac, 2) == 0); + + return is_broadcast || is_multicast || is_ipv6_multicast; +} + + +uint8_t is_broadcast (const n2n_mac_t dest_mac) { + + int is_broadcast = (memcmp(broadcast_mac, dest_mac, N2N_MAC_SIZE) == 0); + + return is_broadcast; +} + + +uint8_t is_null_mac (const n2n_mac_t dest_mac) { + + int is_null_mac = (memcmp(null_mac, dest_mac, N2N_MAC_SIZE) == 0); + + return is_null_mac; +} + + +/* *********************************************** */ + +char* msg_type2str (uint16_t msg_type) { + + switch(msg_type) { + case MSG_TYPE_REGISTER: return("MSG_TYPE_REGISTER"); + case MSG_TYPE_DEREGISTER: return("MSG_TYPE_DEREGISTER"); + case MSG_TYPE_PACKET: return("MSG_TYPE_PACKET"); + case MSG_TYPE_REGISTER_ACK: return("MSG_TYPE_REGISTER_ACK"); + case MSG_TYPE_REGISTER_SUPER: return("MSG_TYPE_REGISTER_SUPER"); + case MSG_TYPE_REGISTER_SUPER_ACK: return("MSG_TYPE_REGISTER_SUPER_ACK"); + case MSG_TYPE_REGISTER_SUPER_NAK: return("MSG_TYPE_REGISTER_SUPER_NAK"); + case MSG_TYPE_FEDERATION: return("MSG_TYPE_FEDERATION"); + default: return("???"); + } + + return("???"); +} + +/* *********************************************** */ + +void hexdump (const uint8_t *buf, size_t len) { + + size_t i; + + if(0 == len) { + return; + } + + printf("-----------------------------------------------\n"); + for(i = 0; i < len; i++) { + if((i > 0) && ((i % 16) == 0)) { + printf("\n"); + } + printf("%02X ", buf[i] & 0xFF); + } + printf("\n"); + printf("-----------------------------------------------\n"); +} + + +/* *********************************************** */ + +void print_n2n_version () { + + printf("Welcome to n2n v.%s for %s\n" + "Built on %s\n" + "Copyright 2007-2021 - ntop.org and contributors\n\n", + GIT_RELEASE, PACKAGE_OSNAME, PACKAGE_BUILDDATE); +} + +/* *********************************************** */ + +size_t purge_expired_nodes (struct peer_info **peer_list, + SOCKET socket_not_to_close, + n2n_tcp_connection_t **tcp_connections, + time_t *p_last_purge, + int frequency, int timeout) { + + time_t now = time(NULL); + size_t num_reg = 0; + + if((now - (*p_last_purge)) < frequency) { + return 0; + } + + traceEvent(TRACE_DEBUG, "Purging old registrations"); + + num_reg = purge_peer_list(peer_list, socket_not_to_close, tcp_connections, now - timeout); + + (*p_last_purge) = now; + traceEvent(TRACE_DEBUG, "Remove %ld registrations", num_reg); + + return num_reg; +} + +/** Purge old items from the peer_list, eventually close the related socket, and + * return the number of items that were removed. */ +size_t purge_peer_list (struct peer_info **peer_list, + SOCKET socket_not_to_close, + n2n_tcp_connection_t **tcp_connections, + time_t purge_before) { + + struct peer_info *scan, *tmp; + n2n_tcp_connection_t *conn; + size_t retval = 0; + + HASH_ITER(hh, *peer_list, scan, tmp) { + if((scan->purgeable == SN_PURGEABLE) && (scan->last_seen < purge_before)) { + if((scan->socket_fd >=0) && (scan->socket_fd != socket_not_to_close)) { + if(tcp_connections) { + HASH_FIND_INT(*tcp_connections, &scan->socket_fd, conn); + if(conn) { + HASH_DEL(*tcp_connections, conn); + free(conn); + } + shutdown(scan->socket_fd, SHUT_RDWR); + closesocket(scan->socket_fd); + } + } + HASH_DEL(*peer_list, scan); + retval++; + free(scan); + } + } + + return retval; +} + +/** Purge all items from the peer_list and return the number of items that were removed. */ +size_t clear_peer_list (struct peer_info ** peer_list) { + + struct peer_info *scan, *tmp; + size_t retval = 0; + + HASH_ITER(hh, *peer_list, scan, tmp) { + HASH_DEL(*peer_list, scan); + retval++; + free(scan); + } + + return retval; +} + +static uint8_t hex2byte (const char * s) { + + char tmp[3]; + tmp[0] = s[0]; + tmp[1] = s[1]; + tmp[2] = 0; /* NULL term */ + + return((uint8_t)strtol(tmp, NULL, 16)); +} + +extern int str2mac (uint8_t * outmac /* 6 bytes */, const char * s) { + + size_t i; + + /* break it down as one case for the first "HH", the 5 x through loop for + * each ":HH" where HH is a two hex nibbles in ASCII. */ + + *outmac = hex2byte(s); + ++outmac; + s += 2; /* don't skip colon yet - helps generalise loop. */ + + for(i = 1; i < 6; ++i) { + s += 1; + *outmac = hex2byte(s); + ++outmac; + s += 2; + } + + return 0; /* ok */ +} + +extern char * sock_to_cstr (n2n_sock_str_t out, + const n2n_sock_t * sock) { + + if(NULL == out) { + return NULL; + } + memset(out, 0, N2N_SOCKBUF_SIZE); + + if(AF_INET6 == sock->family) { + /* INET6 not written yet */ + snprintf(out, N2N_SOCKBUF_SIZE, "XXXX:%hu", sock->port); + return out; + } else { + const uint8_t * a = sock->addr.v4; + + snprintf(out, N2N_SOCKBUF_SIZE, "%hu.%hu.%hu.%hu:%hu", + (unsigned short)(a[0] & 0xff), + (unsigned short)(a[1] & 0xff), + (unsigned short)(a[2] & 0xff), + (unsigned short)(a[3] & 0xff), + (unsigned short)sock->port); + return out; + } +} + +char *ip_subnet_to_str (dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr) { + + snprintf(buf, sizeof(dec_ip_bit_str_t), "%hhu.%hhu.%hhu.%hhu/%hhu", + (uint8_t) ((ipaddr->net_addr >> 24) & 0xFF), + (uint8_t) ((ipaddr->net_addr >> 16) & 0xFF), + (uint8_t) ((ipaddr->net_addr >> 8) & 0xFF), + (uint8_t) (ipaddr->net_addr & 0xFF), + ipaddr->net_bitlen); + + return buf; +} + + +/* @return 1 if the two sockets are equivalent. */ +int sock_equal (const n2n_sock_t * a, + const n2n_sock_t * b) { + + if(a->port != b->port) { + return(0); + } + + if(a->family != b->family) { + return(0); + } + + switch(a->family) { + case AF_INET: + if(memcmp(a->addr.v4, b->addr.v4, IPV4_SIZE)) { + return(0); + } + break; + + default: + if(memcmp(a->addr.v6, b->addr.v6, IPV6_SIZE)) { + return(0); + } + break; + } + + /* equal */ + return(1); +} + + +/* *********************************************** */ + +// fills a specified memory area with random numbers +int memrnd (uint8_t *address, size_t len) { + + for(; len >= 4; len -= 4) { + *(uint32_t*)address = n2n_rand(); + address += 4; + } + + for(; len > 0; len--) { + *address = n2n_rand(); + address++; + } + + return 0; +} + + +// exclusive-ors a specified memory area with another +int memxor (uint8_t *destination, const uint8_t *source, size_t len) { + + for(; len >= 4; len -= 4) { + *(uint32_t*)destination ^= *(uint32_t*)source; + source += 4; + destination += 4; + } + + for(; len > 0; len--) { + *destination ^= *source; + source++; + destination++; + } + + return 0; +} + +/* *********************************************** */ + +#if defined(WIN32) +int gettimeofday (struct timeval *tp, void *tzp) { + + time_t clock; + struct tm tm; + SYSTEMTIME wtm; + + GetLocalTime(&wtm); + tm.tm_year = wtm.wYear - 1900; + tm.tm_mon = wtm.wMonth - 1; + tm.tm_mday = wtm.wDay; + tm.tm_hour = wtm.wHour; + tm.tm_min = wtm.wMinute; + tm.tm_sec = wtm.wSecond; + tm.tm_isdst = -1; + clock = mktime(&tm); + tp->tv_sec = clock; + tp->tv_usec = wtm.wMilliseconds * 1000; + + return 0; +} +#endif + + +// stores the previously issued time stamp +static uint64_t previously_issued_time_stamp = 0; + + +// returns a time stamp for use with replay protection (branchless code) +// +// depending on the self-detected accuracy, it has the following format +// +// MMMMMMMMCCCCCCCF or +// +// MMMMMMMMSSSSSCCF +// +// with M being the 32-bit second time stamp +// S the 20-bit sub-second (microsecond) time stamp part, if applicable +// C a counter (8 bit or 24 bit) reset to 0 with every MMMMMMMM(SSSSS) turn-over +// F a 4-bit flag field with +// ...c being the accuracy indicator (if set, only counter and no sub-second accuracy) +// +uint64_t time_stamp (void) { + + struct timeval tod; + uint64_t micro_seconds; + uint64_t co, mask_lo, mask_hi, hi_unchanged, counter, new_co; + + gettimeofday(&tod, NULL); + + // (roughly) calculate the microseconds since 1970, leftbound + micro_seconds = ((uint64_t)(tod.tv_sec) << 32) + ((uint64_t)tod.tv_usec << 12); + // more exact but more costly due to the multiplication: + // micro_seconds = ((uint64_t)(tod.tv_sec) * 1000000ULL + tod.tv_usec) << 12; + + // extract "counter only" flag (lowest bit) + co = (previously_issued_time_stamp << 63) >> 63; + // set mask accordingly + mask_lo = -co; + mask_lo >>= 32; + // either 0x00000000FFFFFFFF (if co flag set) or 0x0000000000000000 (if co flag not set) + + mask_lo |= (~mask_lo) >> 52; + // either 0x00000000FFFFFFFF (unchanged) or 0x0000000000000FFF (lowest 12 bit set) + + mask_hi = ~mask_lo; + + hi_unchanged = ((previously_issued_time_stamp & mask_hi) == (micro_seconds & mask_hi)); + // 0 if upper bits unchanged (compared to previous stamp), 1 otherwise + + // read counter and shift right for flags + counter = (previously_issued_time_stamp & mask_lo) >> 4; + + counter += hi_unchanged; + counter &= -hi_unchanged; + // either counter++ if upper part of timestamp unchanged, 0 otherwise + + // back to time stamp format + counter <<= 4; + + // set new co flag if counter overflows while upper bits unchanged or if it was set before + new_co = (((counter & mask_lo) == 0) & hi_unchanged) | co; + + // in case co flag changed, masks need to be recalculated + mask_lo = -new_co; + mask_lo >>= 32; + mask_lo |= (~mask_lo) >> 52; + mask_hi = ~mask_lo; + + // assemble new timestamp + micro_seconds &= mask_hi; + micro_seconds |= counter; + micro_seconds |= new_co; + + previously_issued_time_stamp = micro_seconds; + + return micro_seconds; +} + + +// returns an initial time stamp for use with replay protection +uint64_t initial_time_stamp (void) { + + return time_stamp() - TIME_STAMP_FRAME; +} + + +// checks if a provided time stamp is consistent with current time and previously valid time stamps +// and, in case of validity, updates the "last valid time stamp" +int time_stamp_verify_and_update (uint64_t stamp, uint64_t *previous_stamp, int allow_jitter) { + + int64_t diff; /* do not change to unsigned */ + uint64_t co; /* counter only mode (for sub-seconds) */ + + co = (stamp << 63) >> 63; + + // is it around current time (+/- allowed deviation TIME_STAMP_FRAME)? + diff = stamp - time_stamp(); + // abs() + diff = (diff < 0 ? -diff : diff); + if(diff >= TIME_STAMP_FRAME) { + traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp out of allowed frame."); + return 0; // failure + } + + // if applicable: is it higher than previous time stamp (including allowed deviation of TIME_STAMP_JITTER)? + if(NULL != previous_stamp) { + diff = stamp - *previous_stamp; + if(allow_jitter) { + // 8 times higher jitter allowed for counter-only flagged timestamps ( ~ 1.25 sec with 160 ms default jitter) + diff += TIME_STAMP_JITTER << (co << 3); + } + + if(diff <= 0) { + traceEvent(TRACE_DEBUG, "time_stamp_verify_and_update found a timestamp too old compared to previous."); + return 0; // failure + } + // for not allowing to exploit the allowed TIME_STAMP_JITTER to "turn the clock backwards", + // set the higher of the values + *previous_stamp = (stamp > *previous_stamp ? stamp : *previous_stamp); + } + + return 1; // success +} diff --git a/bundles/n2n_ntop_v3/src/n2n_regex.c b/bundles/n2n_ntop_v3/src/n2n_regex.c new file mode 100644 index 00000000..56e47da7 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/n2n_regex.c @@ -0,0 +1,486 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +// taken from https://github.com/kokke/tiny-regex-c +// under Unlicense as of August 4, 2020 + +/* + * + * Mini regex-module inspired by Rob Pike's regex code described in: + * + * http://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html + * + * + * + * Supports: + * --------- + * '.' Dot, matches any character + * '^' Start anchor, matches beginning of string -- NOTE: currently disabled (checking for full matches anyway) + * '$' End anchor, matches end of string -- NOTE: currently disabled (checking for full matches anyway) + * '*' Asterisk, match zero or more (greedy) + * '+' Plus, match one or more (greedy) + * '?' Question, match zero or one (non-greedy) + * '[abc]' Character class, match if one of {'a', 'b', 'c'} + * '[^abc]' Inverted class, match if NOT one of {'a', 'b', 'c'} -- NOTE: feature is currently broken! + * '[a-zA-Z]' Character ranges, the character set of the ranges { a-z | A-Z } + * '\s' Whitespace, \t \f \r \n \v and spaces + * '\S' Non-whitespace + * '\w' Alphanumeric, [a-zA-Z0-9_] + * '\W' Non-alphanumeric + * '\d' Digits, [0-9] + * '\D' Non-digits + * + * + */ + + +#include "n2n.h" +#include "n2n_regex.h" + +/* Definitions: */ + +#define MAX_REGEXP_OBJECTS 30 /* Max number of regex symbols in expression. */ +#define MAX_CHAR_CLASS_LEN 40 /* Max length of character-class buffer in. */ + + +enum { UNUSED, DOT, BEGIN, END, QUESTIONMARK, STAR, PLUS, CHAR_TYPE, CHAR_CLASS, INV_CHAR_CLASS, DIGIT, NOT_DIGIT, ALPHA, NOT_ALPHA, WHITESPACE, NOT_WHITESPACE, /* BRANCH */ }; + +typedef struct regex_t { + unsigned char type; /* CHAR_TYPE, STAR, etc. */ + union { + unsigned char ch; /* the character itself */ + unsigned char* ccl; /* OR a pointer to characters in class */ + }; +} regex_t; + + + +/* Private function declarations: */ +static int matchpattern (regex_t* pattern, const char* text, int* matchlength); +static int matchcharclass (char c, const char* str); +static int matchstar (regex_t p, regex_t* pattern, const char* text, int* matchlength); +static int matchplus (regex_t p, regex_t* pattern, const char* text, int* matchlength); +static int matchone (regex_t p, char c); +static int matchdigit (char c); +static int matchalpha (char c); +static int matchwhitespace (char c); +static int matchmetachar (char c, const char* str); +static int matchrange (char c, const char* str); +static int matchdot (char c); +static int ismetachar (char c); + + + +/* Public functions: */ +int re_match (const char* pattern, const char* text, int* matchlength) { + + re_t re_p; /* pointer to (to be created) copy of compiled regex */ + int ret = -1; + + re_p = re_compile (pattern); + ret = re_matchp(re_p, text, matchlength); + free(re_p); + + return(ret); +} + +int re_matchp (re_t pattern, const char* text, int* matchlength) { + + *matchlength = 0; + + if(pattern != 0) { + if(pattern[0].type == BEGIN) { + return ((matchpattern(&pattern[1], text, matchlength)) ? 0 : -1); + } else { + int idx = -1; + + do { + idx += 1; + + if(matchpattern(pattern, text, matchlength)) { + if(text[0] == '\0') { + return -1; + } + return idx; + } + } while(*text++ != '\0'); + } + } + + return -1; +} + +re_t re_compile (const char* pattern) { + + /* The sizes of the two static arrays below substantiates the static RAM usage of this module. + MAX_REGEXP_OBJECTS is the max number of symbols in the expression. + MAX_CHAR_CLASS_LEN determines the size of buffer for chars in all char-classes in the expression. */ + static regex_t re_compiled[MAX_REGEXP_OBJECTS]; + re_t re_p; /* pointer to (to be created) copy of compiled regex in re_compiled */ + + static unsigned char ccl_buf[MAX_CHAR_CLASS_LEN]; + int ccl_bufidx = 1; + + char c; /* current char in pattern */ + int i = 0; /* index into pattern */ + int j = 0; /* index into re_compiled */ + + while(pattern[i] != '\0' && (j + 1 < MAX_REGEXP_OBJECTS)) { + c = pattern[i]; + + switch(c) { + /* Meta-characters: */ + // case '^': { re_compiled[j].type = BEGIN; } break; <-- disabled (always full matches) + // case '$': { re_compiled[j].type = END; } break; <-- disabled (always full matches) + case '.': { re_compiled[j].type = DOT; } break; + case '*': { re_compiled[j].type = STAR; } break; + case '+': { re_compiled[j].type = PLUS; } break; + case '?': { re_compiled[j].type = QUESTIONMARK; } break; + /* case '|': { re_compiled[j].type = BRANCH; } break; <-- not working properly */ + + /* Escaped character-classes (\s \w ...): */ + case '\\': { + if(pattern[i + 1] != '\0') { + /* Skip the escape-char '\\' */ + i += 1; + /* ... and check the next */ + switch(pattern[i]) { + /* Meta-character: */ + case 'd': { re_compiled[j].type = DIGIT; } break; + case 'D': { re_compiled[j].type = NOT_DIGIT; } break; + case 'w': { re_compiled[j].type = ALPHA; } break; + case 'W': { re_compiled[j].type = NOT_ALPHA; } break; + case 's': { re_compiled[j].type = WHITESPACE; } break; + case 'S': { re_compiled[j].type = NOT_WHITESPACE; } break; + + /* Escaped character, e.g. '.' */ + default: { + re_compiled[j].type = CHAR_TYPE; + re_compiled[j].ch = pattern[i]; + } break; + } + } + /* '\\' as last char in pattern -> invalid regular expression. */ + /* + else + { + re_compiled[j].type = CHAR_TYPE; + re_compiled[j].ch = pattern[i]; + } + */ + } break; + + /* Character class: */ + case '[': { + /* Remember where the char-buffer starts. */ + int buf_begin = ccl_bufidx; + + /* Look-ahead to determine if negated */ + if(pattern[i+1] == '^') { + re_compiled[j].type = INV_CHAR_CLASS; + i += 1; /* Increment i to avoid including '^' in the char-buffer */ + } else { + re_compiled[j].type = CHAR_CLASS; + } + + /* Copy characters inside [..] to buffer */ + while((pattern[++i] != ']') + && (pattern[i] != '\0')) /* Missing ] */ + { + if(pattern[i] == '\\') { + if(ccl_bufidx >= MAX_CHAR_CLASS_LEN - 1) { + //fputs("exceeded internal buffer!\n", stderr); + return 0; + } + ccl_buf[ccl_bufidx++] = pattern[i++]; + } else if(ccl_bufidx >= MAX_CHAR_CLASS_LEN) { + //fputs("exceeded internal buffer!\n", stderr); + return 0; + } + ccl_buf[ccl_bufidx++] = pattern[i]; + } + if(ccl_bufidx >= MAX_CHAR_CLASS_LEN) { + /* Catches cases such as [00000000000000000000000000000000000000][ */ + //fputs("exceeded internal buffer!\n", stderr); + return 0; + } + /* Null-terminate string end */ + ccl_buf[ccl_bufidx++] = 0; + re_compiled[j].ccl = &ccl_buf[buf_begin]; + } break; + + /* Other characters: */ + default: { + re_compiled[j].type = CHAR_TYPE; + re_compiled[j].ch = c; + } break; + } + i += 1; + j += 1; + } + /* 'UNUSED' is a sentinel used to indicate end-of-pattern */ + re_compiled[j].type = UNUSED; + + re_p = (re_t)calloc(1, sizeof(re_compiled)); + memcpy (re_p, re_compiled, sizeof(re_compiled)); + + return (re_t) re_p; +} + +void re_print (regex_t* pattern) { + + const char* types[] = { "UNUSED", "DOT", "BEGIN", "END", "QUESTIONMARK", "STAR", "PLUS", "CHAR_TYPE", "CHAR_CLASS", "INV_CHAR_CLASS", "DIGIT", "NOT_DIGIT", "ALPHA", "NOT_ALPHA", "WHITESPACE" , "NOT_WHITESPACE", /* "BRANCH" */ }; + int i; + int j; + char c; + + for(i = 0; i < MAX_REGEXP_OBJECTS; ++i) { + if(pattern[i].type == UNUSED) { + break; + } + + printf("type: %s", types[pattern[i].type]); + if((pattern[i].type == CHAR_CLASS) || (pattern[i].type == INV_CHAR_CLASS)) { + printf(" ["); + for(j = 0; j < MAX_CHAR_CLASS_LEN; ++j) { + c = pattern[i].ccl[j]; + if((c == '\0') || (c == ']')) { + break; + } + printf("%c", c); + } + printf("]"); + } else if(pattern[i].type == CHAR_TYPE) { + printf(" '%c'", pattern[i].ch); + } + printf("\n"); + } +} + + + +/* Private functions: */ +static int matchdigit (char c) { + + return ((c >= '0') && (c <= '9')); +} + +static int matchalpha (char c) { + + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); +} + +static int matchwhitespace (char c) { + + return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\f') || (c == '\v')); +} + +static int matchalphanum (char c) { + + return ((c == '_') || matchalpha(c) || matchdigit(c)); +} + +static int matchrange (char c, const char* str) { + + return ((c != '-') && (str[0] != '\0') && (str[0] != '-') && + (str[1] == '-') && (str[1] != '\0') && + (str[2] != '\0') && ((c >= str[0]) && (c <= str[2]))); +} + +static int matchdot (char c) { + + return ((c != '\n') && (c != '\r')); +} + +static int ismetachar (char c) { + + return ((c == 's') || (c == 'S') || (c == 'w') || (c == 'W') || (c == 'd') || (c == 'D')); +} + +static int matchmetachar (char c, const char* str) { + + switch(str[0]) { + case 'd': return matchdigit(c); + case 'D': return !matchdigit(c); + case 'w': return matchalphanum(c); + case 'W': return !matchalphanum(c); + case 's': return matchwhitespace(c); + case 'S': return !matchwhitespace(c); + default: return (c == str[0]); + } +} + +static int matchcharclass (char c, const char* str) { + + do { + if(matchrange(c, str)) { + return 1; + } else if(str[0] == '\\') { + /* Escape-char: increment str-ptr and match on next char */ + str += 1; + if(matchmetachar(c, str)) { + return 1; + } else if((c == str[0]) && !ismetachar(c)) { + return 1; + } + } else if(c == str[0]) { + if(c == '-') { + return ((str[-1] == '\0') || (str[1] == '\0')); + } else { + return 1; + } + } + } while(*str++ != '\0'); + + return 0; +} + +static int matchone (regex_t p, char c) { + + switch(p.type) { + case DOT: return matchdot(c); + case CHAR_CLASS: return matchcharclass(c, (const char*)p.ccl); + case INV_CHAR_CLASS: return !matchcharclass(c, (const char*)p.ccl); + case DIGIT: return matchdigit(c); + case NOT_DIGIT: return !matchdigit(c); + case ALPHA: return matchalphanum(c); + case NOT_ALPHA: return !matchalphanum(c); + case WHITESPACE: return matchwhitespace(c); + case NOT_WHITESPACE: return !matchwhitespace(c); + default: return (p.ch == c); + } +} + +static int matchstar (regex_t p, regex_t* pattern, const char* text, int* matchlength) { + + int prelen = *matchlength; + const char* prepoint = text; + + while((text[0] != '\0') && matchone(p, *text)) { + text++; + (*matchlength)++; + } + + while(text >= prepoint) { + if(matchpattern(pattern, text--, matchlength)) { + return 1; + } + (*matchlength)--; + } + + *matchlength = prelen; + + return 0; +} + +static int matchplus (regex_t p, regex_t* pattern, const char* text, int* matchlength) { + + const char* prepoint = text; + + while((text[0] != '\0') && matchone(p, *text)) { + text++; + (*matchlength)++; + } + + while(text > prepoint) { + if(matchpattern(pattern, text--, matchlength)) { + return 1; + } + (*matchlength)--; + } + + return 0; +} + +static int matchquestion (regex_t p, regex_t* pattern, const char* text, int* matchlength) { + + if(p.type == UNUSED) { + return 1; + } + + if(matchpattern(pattern, text, matchlength)) { + return 1; + } + + if(*text && matchone(p, *text++)) { + if(matchpattern(pattern, text, matchlength)) { + (*matchlength)++; + return 1; + } + } + + return 0; +} + + +#if 0 + +/* Recursive matching */ +static int matchpattern (regex_t* pattern, const char* text, int *matchlength) { + + int pre = *matchlength; + + if((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK)) { + return matchquestion(pattern[1], &pattern[2], text, matchlength); + } else if(pattern[1].type == STAR) { + return matchstar(pattern[0], &pattern[2], text, matchlength); + } else if(pattern[1].type == PLUS) { + return matchplus(pattern[0], &pattern[2], text, matchlength); + } else if((pattern[0].type == END) && pattern[1].type == UNUSED) { + return text[0] == '\0'; + } else if((text[0] != '\0') && matchone(pattern[0], text[0])) { + (*matchlength)++; + return matchpattern(&pattern[1], text+1); + } else { + *matchlength = pre; + return 0; + } +} + +#else + +/* Iterative matching */ +static int matchpattern (regex_t* pattern, const char* text, int* matchlength) { + + int pre = *matchlength; + + do { + if((pattern[0].type == UNUSED) || (pattern[1].type == QUESTIONMARK)) { + return matchquestion(pattern[0], &pattern[2], text, matchlength); + } else if(pattern[1].type == STAR) { + return matchstar(pattern[0], &pattern[2], text, matchlength); + } else if(pattern[1].type == PLUS) { + return matchplus(pattern[0], &pattern[2], text, matchlength); + } else if((pattern[0].type == END) && pattern[1].type == UNUSED) { + return (text[0] == '\0'); + } +/* Branching is not working properly + else if (pattern[1].type == BRANCH) + { + return (matchpattern(pattern, text) || matchpattern(&pattern[2], text)); + } +*/ + (*matchlength)++; + } while((text[0] != '\0') && matchone(*pattern++, *text++)); + + *matchlength = pre; + + return 0; +} + +#endif diff --git a/bundles/n2n_ntop_v3/src/network_traffic_filter.c b/bundles/n2n_ntop_v3/src/network_traffic_filter.c new file mode 100644 index 00000000..9ec76a2c --- /dev/null +++ b/bundles/n2n_ntop_v3/src/network_traffic_filter.c @@ -0,0 +1,783 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" +#include "network_traffic_filter.h" +#include "uthash.h" + +// cache that hit less than 10 while 10000 package processed will be delete; +#define CLEAR_CACHE_EVERY_X_COUNT 10000 +#define CLAER_CACHE_ACTIVE_COUNT 10 + +/* for [-Wmissing-declarations] */ +const char* get_filter_packet_proto_name (filter_packet_proto proto); + +const char* get_filter_packet_proto_name (filter_packet_proto proto) { + + switch(proto) { + case FPP_ARP: + return "ARP"; + case FPP_TCP: + return "TCP"; + case FPP_UDP: + return "UDP"; + case FPP_ICMP: + return "ICMP"; + case FPP_IGMP: + return "IGMP"; + default: + return "UNKNOWN_PROTO"; + } +} + + +/* for [-Wmissing-declarations] */ +const char* get_filter_packet_info_log_string (packet_address_proto_info_t* info); + +const char* get_filter_packet_info_log_string (packet_address_proto_info_t* info) { + + static char buf[1024] = {0}; + + switch(info->proto) { + case FPP_ARP: + case FPP_ICMP: + case FPP_IGMP: + return get_filter_packet_proto_name(info->proto); + case FPP_TCP: + case FPP_UDP: { + struct in_addr src, dst; + + src.s_addr = info->src_ip; + dst.s_addr = info->dst_ip; + const char* proto = get_filter_packet_proto_name(info->proto); + char src_ip[64] = {0}; + char dst_ip[64] = {0}; + strcpy(src_ip, inet_ntoa(src)); + strcpy(dst_ip, inet_ntoa(dst)); + sprintf(buf, "%s\t%s:%d->%s:%d", proto, src_ip, info->src_port, dst_ip, info->dst_port); + return buf; + } + default: + return "UNKNOWN_PROTO"; + } +} + +/* for [-Wmissing-declarations] */ +void collect_packet_info (packet_address_proto_info_t* out_info, unsigned char *buffer, int size); + +void collect_packet_info (packet_address_proto_info_t* out_info, unsigned char *buffer, int size) { + + ether_hdr_t *hdr_ether = (ether_hdr_t*)buffer; + uint16_t ether_type = ntohs(hdr_ether->type); + struct n2n_iphdr *hdr_ip = NULL; + struct n2n_tcphdr *hdr_tcp = NULL; + struct n2n_udphdr *udp_hdr = NULL; + + memset(out_info, 0, sizeof(packet_address_proto_info_t)); + + switch(ether_type) { + case 0x0800: { + buffer += sizeof(ether_hdr_t); + size -= sizeof(ether_hdr_t); + if(size <= 0) { + return; + } + hdr_ip = (struct n2n_iphdr*)buffer; + + switch(hdr_ip->version) { + case 4: { + out_info->src_ip = hdr_ip->saddr; + out_info->dst_ip = hdr_ip->daddr; + switch(hdr_ip->protocol) { + case 0x01: + out_info->proto = FPP_ICMP; + break; + case 0x02: + out_info->proto = FPP_IGMP; + break; + case 0x06: { + out_info->proto = FPP_TCP; + buffer += hdr_ip->ihl * 4; + size -= hdr_ip->ihl * 4; + if(size <= 0) { + return; + } + hdr_tcp = (struct n2n_tcphdr*)buffer; + out_info->src_port = ntohs(hdr_tcp->source); + out_info->dst_port = ntohs(hdr_tcp->dest); + break; + } + case 0x11: { + out_info->proto = FPP_UDP; + buffer += hdr_ip->ihl * 4; + size -= hdr_ip->ihl * 4; + if(size <= 0) { + return; + } + udp_hdr = (struct n2n_udphdr*)buffer; + out_info->src_port = ntohs(udp_hdr->source); + out_info->dst_port = ntohs(udp_hdr->dest); + break; + } + default: + out_info->proto = FPP_UNKNOWN; + }; + break; + } + case 6: { + // TODO: IPV6 Not Support + out_info->proto = FPP_UNKNOWN; + break; + } + default: + out_info->proto = FPP_UNKNOWN; + } + break; + } + case 0x0806: + out_info->proto = FPP_ARP; + break; + case 0x86DD: + out_info->proto = FPP_UNKNOWN; + break; + default: + traceEvent(TRACE_DEBUG, "collect_packet_info stumbled across the unknown ether type 0x%04X", ether_type); + }; +} + +/* for [-Wmissing-declarations] */ +const char* get_filter_rule_info_log_string (filter_rule_t* rule); + +const char* get_filter_rule_info_log_string (filter_rule_t* rule) { + + static char buf[1024] = {0}; + char* print_start = buf; + char src_net[64] = {0}; + char dst_net[64] = {0}; + struct in_addr src, dst; + + src.s_addr = rule->key.src_net_cidr; + dst.s_addr = rule->key.dst_net_cidr; + strcpy(src_net, inet_ntoa(src)); + strcpy(dst_net, inet_ntoa(dst)); + print_start += sprintf(print_start, "%s/%d:[%d,%d],%s/%d:[%d,%d]", + src_net, rule->key.src_net_bit_len, + rule->key.src_port_range.start_port, rule->key.src_port_range.end_port, + dst_net, rule->key.dst_net_bit_len, + rule->key.dst_port_range.start_port, rule->key.dst_port_range.end_port +#if 0 + , + rule->bool_accept_tcp ? '+' : '-', rule->bool_accept_udp ? '+' : '-', rule->bool_accept_icmp ? '+' : '-' +#endif + ); + if(rule->key.bool_tcp_configured) { + print_start += sprintf(print_start, ",TCP%c", rule->bool_accept_tcp ? '+' : '-'); + } + + if(rule->key.bool_udp_configured) { + print_start += sprintf(print_start, ",UDP%c", rule->bool_accept_udp ? '+' : '-'); + } + + if(rule->key.bool_icmp_configured) { + print_start += sprintf(print_start, ",ICMP%c", rule->bool_accept_icmp ? '+' : '-'); + } + + return buf; +} + + + +/* for [-Wmissing-declarations] */ +uint8_t march_cidr_and_address (in_addr_t network, uint8_t net_bitlen, in_addr_t ip_addr); + +uint8_t march_cidr_and_address (in_addr_t network, uint8_t net_bitlen, in_addr_t ip_addr) { + + in_addr_t mask = 0, ip_addr_network = 0; + + network = ntohl(network); + ip_addr = ntohl(ip_addr); + uint32_t mask1 = net_bitlen != 0 ? ((~mask) << (32u-net_bitlen)) : 0; + ip_addr_network = ip_addr & mask1; + if(network == ip_addr_network) { + return net_bitlen + 1; // march 0.0.0.0/0 still march success, that case return 1 + } else { + return 0; + } +} + +/* for [-Wmissing-declarations] */ +uint8_t march_rule_and_cache_key (filter_rule_key_t *rule_key, packet_address_proto_info_t *pkt_addr_info); + +// if ports march, compare cidr. if cidr ok, return sum of src&dst cidr net_bitlen. means always select larger net_bitlen record when multi record is marched. +uint8_t march_rule_and_cache_key (filter_rule_key_t *rule_key, packet_address_proto_info_t *pkt_addr_info) { + + // march failed if proto is not configured at the rule. + switch(pkt_addr_info->proto) { + case FPP_ICMP: + if(!rule_key->bool_icmp_configured) { + return 0; + } + break; + case FPP_UDP: + if(!rule_key->bool_udp_configured) { + return 0; + } + break; + case FPP_TCP: + if(!rule_key->bool_tcp_configured) { + return 0; + } + break; + default: + return 0; + } + + // ignore ports for ICMP proto. + if(pkt_addr_info->proto == FPP_ICMP || (rule_key->src_port_range.start_port <= pkt_addr_info->src_port + && pkt_addr_info->src_port <= rule_key->src_port_range.end_port + && rule_key->dst_port_range.start_port <= pkt_addr_info->dst_port + && pkt_addr_info->dst_port <= rule_key->dst_port_range.end_port)) { + uint8_t march_src_score = march_cidr_and_address(rule_key->src_net_cidr, rule_key->src_net_bit_len, pkt_addr_info->src_ip); + uint8_t march_dst_score = march_cidr_and_address(rule_key->dst_net_cidr, rule_key->dst_net_bit_len, pkt_addr_info->dst_ip); + if((march_src_score > 0) && (march_dst_score > 0)) { + return march_src_score + march_dst_score; + } + } + + return(0); +} + +/* for [-Wmissing-declarations] */ +filter_rule_t* get_filter_rule (filter_rule_t **rules, packet_address_proto_info_t *pkt_addr_info); + +filter_rule_t* get_filter_rule (filter_rule_t **rules, packet_address_proto_info_t *pkt_addr_info) { + + filter_rule_t *item = 0, *tmp = 0, *marched_rule = 0; + int march_score = 0; + + HASH_ITER(hh, *rules, item, tmp) { + /* ... it is safe to delete and free s here */ + uint8_t cur_march_score = march_rule_and_cache_key(&(item->key), pkt_addr_info); + if(cur_march_score > march_score) { + marched_rule = item; + march_score = cur_march_score; + } + } + + return marched_rule; +} + + +/* for [-Wmissing-declarations] */ +void update_and_clear_cache_if_need (network_traffic_filter_t *filter); + +void update_and_clear_cache_if_need (network_traffic_filter_t *filter) { + + if(++(filter->work_count_scene_last_clear) > CLEAR_CACHE_EVERY_X_COUNT) { + filter_rule_pair_cache_t *item = NULL, *tmp = NULL; + HASH_ITER(hh, filter->connections_rule_cache, item, tmp) { + /* ... it is safe to delete and free s here */ + if(item->active_count < CLAER_CACHE_ACTIVE_COUNT) { + traceEvent(TRACE_DEBUG, "### DELETE filter cache %s", get_filter_packet_info_log_string(&item->key)); + HASH_DEL(filter->connections_rule_cache, item); + free(item); + } else { + item->active_count = 0; + } + } + filter->work_count_scene_last_clear = 0; + } +} + +/* for [-Wmissing-declarations] */ +filter_rule_pair_cache_t* get_or_create_filter_rule_cache (network_traffic_filter_t *filter, packet_address_proto_info_t *pkt_addr_info); + +filter_rule_pair_cache_t* get_or_create_filter_rule_cache (network_traffic_filter_t *filter, packet_address_proto_info_t *pkt_addr_info) { + + filter_rule_pair_cache_t* rule_cache_find_result = 0; + HASH_FIND(hh, filter->connections_rule_cache, pkt_addr_info, sizeof(packet_address_proto_info_t), rule_cache_find_result); + if(!rule_cache_find_result) { + filter_rule_t* rule = get_filter_rule(&filter->rules, pkt_addr_info); + if(!rule) { + return NULL; + } + + rule_cache_find_result = malloc(sizeof(filter_rule_pair_cache_t)); + memset(rule_cache_find_result, 0, sizeof(filter_rule_pair_cache_t)); + rule_cache_find_result->key = *pkt_addr_info; + switch(rule_cache_find_result->key.proto) { + case FPP_ICMP: + rule_cache_find_result->bool_allow_traffic = rule->bool_accept_icmp; + break; + case FPP_UDP: + rule_cache_find_result->bool_allow_traffic = rule->bool_accept_udp; + break; + case FPP_TCP: + rule_cache_find_result->bool_allow_traffic = rule->bool_accept_tcp; + break; + default: + traceEvent(TRACE_WARNING, "### Generate filter rule cache failed!"); + return NULL; + } + traceEvent(TRACE_DEBUG, "### ADD filter cache %s", get_filter_packet_info_log_string(&rule_cache_find_result->key)); + HASH_ADD(hh, filter->connections_rule_cache, key, sizeof(packet_address_proto_info_t), rule_cache_find_result); + } + ++(rule_cache_find_result->active_count); + update_and_clear_cache_if_need(filter); + + return rule_cache_find_result; +} + +/* for [-Wmissing-declarations] */ +n2n_verdict filter_packet_from_peer (network_traffic_filter_t *filter, n2n_edge_t *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t payload_size); + +n2n_verdict filter_packet_from_peer (network_traffic_filter_t *filter, n2n_edge_t *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t payload_size) { + + filter_rule_pair_cache_t *cur_pkt_rule = 0; + packet_address_proto_info_t pkt_info; + + collect_packet_info(&pkt_info, payload, payload_size); + cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info); + if(cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic) { + traceEvent(TRACE_DEBUG, "### DROP %s", get_filter_packet_info_log_string(&pkt_info)); + return N2N_DROP; + } + + return N2N_ACCEPT; +} + +/* for [-Wmissing-declarations] */ +n2n_verdict filter_packet_from_tap (network_traffic_filter_t *filter, n2n_edge_t *eee, uint8_t *payload, uint16_t payload_size); + +n2n_verdict filter_packet_from_tap (network_traffic_filter_t *filter, n2n_edge_t *eee, uint8_t *payload, uint16_t payload_size) { + + filter_rule_pair_cache_t *cur_pkt_rule = 0; + packet_address_proto_info_t pkt_info; + + collect_packet_info(&pkt_info, payload, payload_size); + cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info); + if(cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic) { + traceEvent(TRACE_DEBUG, "### DROP %s", get_filter_packet_info_log_string(&pkt_info)); + return N2N_DROP; + } + + return N2N_ACCEPT; +} + +/* for [-Wmissing-declarations] */ +network_traffic_filter_t *create_network_traffic_filter (); + +network_traffic_filter_t *create_network_traffic_filter () { + + network_traffic_filter_t *filter = malloc(sizeof(network_traffic_filter_t)); + + memset(filter, 0, sizeof(network_traffic_filter_t)); + filter->filter_packet_from_peer = filter_packet_from_peer; + filter->filter_packet_from_tap = filter_packet_from_tap; + + return filter; +} + +/* for [-Wmissing-declarations] */ +void destroy_network_traffic_filter (network_traffic_filter_t *filter); + +void destroy_network_traffic_filter (network_traffic_filter_t *filter) { + + filter_rule_t *el = 0, *tmp = 0; + filter_rule_pair_cache_t* el1 = 0, * tmp1 = 0; + + HASH_ITER(hh, filter->rules, el, tmp) { + HASH_DEL(filter->rules, el); + free(el); + } + + HASH_ITER(hh, filter->connections_rule_cache, el1, tmp1) { + HASH_DEL(filter->connections_rule_cache, el1); + free(el); + } + + free(filter); +} + +/* for [-Wmissing-declarations] */ +void network_traffic_filter_add_rule (network_traffic_filter_t* filter, filter_rule_t* rules); + +void network_traffic_filter_add_rule (network_traffic_filter_t* filter, filter_rule_t* rules) { + + filter_rule_t *item = NULL, *tmp = NULL; + + HASH_ITER(hh, rules, item, tmp) { + filter_rule_t *new_rule = malloc(sizeof(filter_rule_t)); + memcpy(new_rule, item, sizeof(filter_rule_t)); + HASH_ADD(hh, filter->rules, key, sizeof(filter_rule_key_t), new_rule); + traceEvent(TRACE_NORMAL, "### ADD network traffic filter %s", get_filter_rule_info_log_string(new_rule)); + } +} + +/* for [-Wmissing-declarations] */ +in_addr_t get_int32_addr_from_ip_string (const char* begin, const char* next_pos_of_last_char); + +in_addr_t get_int32_addr_from_ip_string (const char* begin, const char* next_pos_of_last_char) { + + char buf[16] = {0}; + + if((next_pos_of_last_char - begin) > 15) { + traceEvent(TRACE_WARNING, "Internal Error"); + return -1; + } + memcpy(buf, begin, (next_pos_of_last_char - begin)); + + return inet_addr(buf); +} + +/* for [-Wmissing-declarations] */ +int get_int32_from_number_string (const char* begin, const char* next_pos_of_last_char); + +int get_int32_from_number_string (const char* begin, const char* next_pos_of_last_char) { + + char buf[6] = {0}; + + if((next_pos_of_last_char - begin) > 5 ) { // max is 65535, 5 char + traceEvent(TRACE_WARNING, "Internal Error"); + return 0; + } + memcpy(buf, begin, (next_pos_of_last_char - begin)); + + return atoi(buf); +} + +/* for [-Wmissing-declarations] */ +void process_traffic_filter_proto (const char* begin, const char* next_pos_of_last_char, filter_rule_t *rule_struct); + +void process_traffic_filter_proto (const char* begin, const char* next_pos_of_last_char, filter_rule_t *rule_struct) { + + char buf[6] = {0}; + + if((next_pos_of_last_char - begin) > 5 ) { // max length str is "ICMP+", 5 char + traceEvent(TRACE_WARNING, "Internal Error"); + } + memcpy(buf, begin, (next_pos_of_last_char - begin)); + + if(strstr(buf, "TCP")) { + rule_struct->key.bool_tcp_configured = 1; + rule_struct->bool_accept_tcp = buf[3] == '+'; + } else if(strstr(buf, "UDP")) { + rule_struct->key.bool_udp_configured = 1; + rule_struct->bool_accept_udp = buf[3] == '+'; + } else if(strstr(buf, "ICMP")) { + rule_struct->key.bool_icmp_configured = 1; + rule_struct->bool_accept_icmp = buf[4] == '+'; + } else { + traceEvent(TRACE_WARNING, "Invalid Proto : %s", buf); + } +} + +typedef enum { + FPS_SRC_NET = 1, + FPS_SRC_NET_BIT_LEN, + FPS_SRC_PORT_SINGLE, + FPS_SRC_PORT_RANGE, + FPS_SRC_PORT_START, + FPS_SRC_PORT_END, + FPS_DST_NET, + FPS_DST_NET_BIT_LEN, + FPS_DST_PORT_SINGLE, + FPS_DST_PORT_RANGE, + FPS_DST_PORT_START, + FPS_DST_PORT_END, + FPS_PROTO +} filter_process_stage; + +/* for [-Wmissing-declarations] */ +uint8_t process_traffic_filter_rule_str (const char *rule_str, filter_rule_t *rule_struct); + +uint8_t process_traffic_filter_rule_str (const char *rule_str, filter_rule_t *rule_struct) { + + const char *cur_pos = rule_str, *stage_begin_pos = rule_str; + filter_process_stage stage = FPS_SRC_NET; + + while(1) { + switch(stage) { + case FPS_SRC_NET: { + if((*cur_pos >= '0' && *cur_pos <= '9') || *cur_pos == '.') { + ; // Normal FPS_SRC_NET, next char + } else if(*cur_pos == '/') { + // FPS_SRC_NET finish, next is FPS_SRC_NET_BIT_LEN + rule_struct->key.src_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + stage = FPS_SRC_NET_BIT_LEN; + } else if(*cur_pos == ':') { + // FPS_SRC_NET finish, ignore FPS_SRC_NET_BIT_LEN(default 32), next is one of FPS_SRC_PORT_RANGE/FPS_SRC_PORT_SINGLE + rule_struct->key.src_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + rule_struct->key.src_net_bit_len = 32; + stage_begin_pos = cur_pos + 1; + if(*(cur_pos + 1) == '[') { + stage = FPS_SRC_PORT_RANGE; + } else { + stage = FPS_SRC_PORT_SINGLE; + } + } else if(*cur_pos == ',') { + // FPS_SRC_NET finish, ignore FPS_SRC_NET_BIT_LEN(default 32), ignore FPS_SRC_PORT(default all), + // next is FPS_DST_NET + rule_struct->key.src_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + rule_struct->key.src_net_bit_len = 32; + rule_struct->key.src_port_range.start_port = 0; + rule_struct->key.src_port_range.end_port = 65535; + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_NET; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_SRC_NET_BIT_LEN: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_SRC_NET_BIT_LEN, next char + } else if(*cur_pos == ':') { + // FPS_SRC_NET_BIT_LEN finish, next is one of FPS_SRC_PORT_RANGE/FPS_SRC_PORT_SINGLE + rule_struct->key.src_net_bit_len = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + if(*(cur_pos + 1) == '[') { + stage = FPS_SRC_PORT_RANGE; + } else { + stage = FPS_SRC_PORT_SINGLE; + } + } else if(*cur_pos == ',') { + // FPS_SRC_NET_BIT_LEN finish, ignore FPS_SRC_PORT(default all), next is FPS_DST_NET + rule_struct->key.src_net_bit_len = get_int32_from_number_string(stage_begin_pos, cur_pos);; + rule_struct->key.src_port_range.start_port = 0; + rule_struct->key.src_port_range.end_port = 65535; + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_NET; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_SRC_PORT_SINGLE: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_SRC_PORT_SINGLE, next char + } else if(*cur_pos == ',') { + // FPS_SRC_PORT_SINGLE finish, next is FPS_DST_NET + rule_struct->key.src_port_range.start_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + rule_struct->key.src_port_range.end_port = rule_struct->key.src_port_range.start_port; + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_NET; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_SRC_PORT_RANGE: { + if(*cur_pos == '[') { + stage_begin_pos = cur_pos + 1; + stage = FPS_SRC_PORT_START; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_SRC_PORT_START: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_SRC_PORT_START, next char + } else if(*cur_pos == ',') { + // FPS_SRC_PORT_START finish, next is FPS_SRC_PORT_END + rule_struct->key.src_port_range.start_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + stage = FPS_SRC_PORT_END; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_SRC_PORT_END: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_SRC_PORT_END, next char + } else if((*cur_pos == ']') && (*(cur_pos + 1) == ',')) { + // FPS_SRC_PORT_END finish, next is FPS_DST_NET + rule_struct->key.src_port_range.end_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 2; + stage = FPS_DST_NET; + ++cur_pos; //skip next char ',' + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_NET: { + if((*cur_pos >= '0' && *cur_pos <= '9') || *cur_pos == '.') { + ; // Normal FPS_DST_NET, next char + } else if(*cur_pos == '/') { + // FPS_DST_NET finish, next is FPS_DST_NET_BIT_LEN + rule_struct->key.dst_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_NET_BIT_LEN; + } else if(*cur_pos == ':') { + // FPS_DST_NET finish, ignore FPS_DST_NET_BIT_LEN(default 32), next is one of FPS_DST_PORT_RANGE/FPS_DST_PORT_SINGLE + rule_struct->key.dst_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + rule_struct->key.dst_net_bit_len = 32; + stage_begin_pos = cur_pos + 1; + if(*(cur_pos + 1) == '[') { + stage = FPS_DST_PORT_RANGE; + } else { + stage = FPS_DST_PORT_SINGLE; + } + } else if((*cur_pos == ',') || (*cur_pos == 0)) { + // FPS_DST_NET finish, ignore FPS_DST_NET_BIT_LEN(default 32), ignore FPS_DST_PORT(default all), + // next is FPS_PROTO + rule_struct->key.dst_net_cidr = get_int32_addr_from_ip_string(stage_begin_pos, cur_pos); + rule_struct->key.dst_net_bit_len = 32; + rule_struct->key.dst_port_range.start_port = 0; + rule_struct->key.dst_port_range.end_port = 65535; + stage_begin_pos = cur_pos + 1; + stage = FPS_PROTO; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_NET_BIT_LEN: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_DST_NET_BIT_LEN, next char + } else if(*cur_pos == ':') { + // FPS_DST_NET_BIT_LEN finish, next is one of FPS_DST_PORT_RANGE/FPS_DST_PORT_SINGLE + rule_struct->key.dst_net_bit_len = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + if(*(cur_pos + 1) == '[') { + stage = FPS_DST_PORT_RANGE; + } else { + stage = FPS_DST_PORT_SINGLE; + } + } else if((*cur_pos == ',') || (*cur_pos == 0)) { + // FPS_DST_NET_BIT_LEN finish, ignore FPS_DST_PORT(default all), next is FPS_PROTO + rule_struct->key.dst_net_bit_len = get_int32_from_number_string(stage_begin_pos, cur_pos);; + rule_struct->key.dst_port_range.start_port = 0; + rule_struct->key.dst_port_range.end_port = 65535; + stage_begin_pos = cur_pos + 1; + stage = FPS_PROTO; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_PORT_SINGLE: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_DST_PORT_SINGLE, next char + } else if((*cur_pos == ',') || (*cur_pos == 0)) { + // FPS_DST_PORT_SINGLE finish, next is FPS_PROTO + rule_struct->key.dst_port_range.start_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + rule_struct->key.dst_port_range.end_port = rule_struct->key.dst_port_range.start_port; + stage_begin_pos = cur_pos + 1; + stage = FPS_PROTO; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_PORT_RANGE: { + if(*cur_pos == '[') { + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_PORT_START; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_PORT_START: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_DST_PORT_START, next char + } else if(*cur_pos == ',') { + // FPS_DST_PORT_START finish, next is FPS_DST_PORT_END + rule_struct->key.dst_port_range.start_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage_begin_pos = cur_pos + 1; + stage = FPS_DST_PORT_END; + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_DST_PORT_END: { + if((*cur_pos >= '0') && (*cur_pos <= '9')) { + ; // Normal FPS_DST_PORT_END, next char + } else if(*cur_pos == ']') { + // FPS_DST_PORT_END finish, next is FPS_PROTO + rule_struct->key.dst_port_range.end_port = get_int32_from_number_string(stage_begin_pos, cur_pos); + stage = FPS_PROTO; + if(*(cur_pos + 1) == ',') { + stage_begin_pos = cur_pos + 2; + ++cur_pos; //skip next char ',' + } else if(*(cur_pos + 1) != 0) { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + } else { + traceEvent(TRACE_WARNING, "process filter rule with error char %c at pos %d", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + + case FPS_PROTO: { + if((*cur_pos != '-') && (*cur_pos != '+') && (*cur_pos != ',')) { + ; // Normal FPS_PROTO. next char + } else if(*cur_pos != ',') { + process_traffic_filter_proto(stage_begin_pos, cur_pos + 1, rule_struct); + if(*(cur_pos+1) == 0) { // end of whole rule string + break; + } else { // new proto info, and skip next char ',' + stage_begin_pos = cur_pos + 2; + ++cur_pos; + } + } else { + traceEvent(TRACE_WARNING, "Internal Error: ',' should skiped", *cur_pos, cur_pos - rule_str); + return 0; + } + break; + } + } + + if(0 == *cur_pos) { + break; + } + ++cur_pos; + } + + return 1; +} diff --git a/bundles/n2n_ntop_v3/src/pearson.c b/bundles/n2n_ntop_v3/src/pearson.c new file mode 100644 index 00000000..68f9e38a --- /dev/null +++ b/bundles/n2n_ntop_v3/src/pearson.c @@ -0,0 +1,224 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +// taken from https://github.com/Logan007/pearsonB +// this is free and unencumbered software released into the public domain + + +#include "pearson.h" + + +// Christopher Wellons' triple32 from https://github.com/skeeto/hash-prospector +// published under The Unlicense +#define permute32(in) \ + in ^= in >> 17; \ + in *= 0xed5ad4bb; \ + in ^= in >> 11; \ + in *= 0xac4c1b51; \ + in ^= in >> 15; \ + in *= 0x31848bab; \ + in ^= in >> 14 + +// David Stafford's Mix13 from http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html +// the author clarified via eMail that this of his work is released to the public domain +#define permute64(in) \ + in ^= (in >> 30); \ + in *= 0xbf58476d1ce4e5b9; \ + in ^= (in >> 27); \ + in *= 0x94d049bb133111eb; \ + in ^= (in >> 31) + +#define dec1(in) \ + in-- + +#define dec2(in) \ + dec1(in); \ + dec1(in) + +#define dec3(in) \ + dec2(in); \ + dec1(in) + +#define dec4(in) \ + dec3(in); \ + dec1(in) + +#define hash_round(hash, in, part) \ + hash##part ^= in; \ + dec##part(hash##part); \ + permute64(hash##part) + + +void pearson_hash_256 (uint8_t *out, const uint8_t *in, size_t len) { + + uint64_t *current; + current = (uint64_t*)in; + uint64_t org_len = len; + uint64_t hash1 = 0; + uint64_t hash2 = 0; + uint64_t hash3 = 0; + uint64_t hash4 = 0; + + while (len > 7) { + // digest words little endian first + hash_round(hash, le64toh(*current), 1); + hash_round(hash, le64toh(*current), 2); + hash_round(hash, le64toh(*current), 3); + hash_round(hash, le64toh(*current), 4); + + current++; + len-=8; + } + + // handle the rest + hash1 = ~hash1; + hash2 = ~hash2; + hash3 = ~hash3; + hash4 = ~hash4; + + while(len) { + // byte-wise, no endianess + hash_round(hash, *(uint8_t*)current, 1); + hash_round(hash, *(uint8_t*)current, 2); + hash_round(hash, *(uint8_t*)current, 3); + hash_round(hash, *(uint8_t*)current, 4); + + current = (uint64_t*)((uint8_t*)current + 1); + len--; + } + + // digest length + hash1 = ~hash1; + hash2 = ~hash2; + hash3 = ~hash3; + hash4 = ~hash4; + + hash_round(hash, org_len, 1); + hash_round(hash, org_len, 2); + hash_round(hash, org_len, 3); + hash_round(hash, org_len, 4); + + // hash string is stored big endian, the natural way to read + uint64_t *o; + o = (uint64_t*)out; + *o = htobe64(hash4); + o++; + *o = htobe64(hash3); + o++; + *o = htobe64(hash2); + o++; + *o = htobe64(hash1); +} + + +void pearson_hash_128 (uint8_t *out, const uint8_t *in, size_t len) { + + uint64_t *current; + current = (uint64_t*)in; + uint64_t org_len = len; + uint64_t hash1 = 0; + uint64_t hash2 = 0; + + while (len > 7) { + // digest words little endian first + hash_round(hash, le64toh(*current), 1); + hash_round(hash, le64toh(*current), 2); + + current++; + len-=8; + } + + // handle the rest + hash1 = ~hash1; + hash2 = ~hash2; + + while(len) { + // byte-wise, no endianess + hash_round(hash, *(uint8_t*)current, 1); + hash_round(hash, *(uint8_t*)current, 2); + + current = (uint64_t*)((uint8_t*)current + 1); + len--; + } + + // digest length + hash1 = ~hash1; + hash2 = ~hash2; + + hash_round(hash, org_len, 1); + hash_round(hash, org_len, 2); + + // hash string is stored big endian, the natural way to read + uint64_t *o; + o = (uint64_t*)out; + *o = htobe64(hash2); + o++; + *o = htobe64(hash1); +} + + +uint64_t pearson_hash_64 (const uint8_t *in, size_t len) { + + uint64_t *current; + current = (uint64_t*)in; + uint64_t org_len = len; + uint64_t hash1 = 0; + + while(len > 7) { + // digest words little endian first + hash_round(hash, le64toh(*current), 1); + + current++; + len-=8; + } + + // handle the rest + hash1 = ~hash1; + while(len) { + // byte-wise, no endianess + hash_round(hash, *(uint8_t*)current, 1); + + current = (uint64_t*)((uint8_t*)current + 1); + len--; + } + + // digest length + hash1 = ~hash1; + hash_round(hash, org_len, 1); + + // caller is responsible for storing it big endian to memory (if ever) + return hash1; +} + + +uint32_t pearson_hash_32 (const uint8_t *in, size_t len) { + + return pearson_hash_64(in, len); +} + + +uint16_t pearson_hash_16 (const uint8_t *in, size_t len) { + + return pearson_hash_64(in, len); +} + + +void pearson_hash_init(void) { + +} diff --git a/bundles/n2n_ntop_v3/src/random_numbers.c b/bundles/n2n_ntop_v3/src/random_numbers.c new file mode 100644 index 00000000..0adb8c6f --- /dev/null +++ b/bundles/n2n_ntop_v3/src/random_numbers.c @@ -0,0 +1,244 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "random_numbers.h" + + +// the following code offers an alterate pseudo random number generator +// namely XORSHIFT128+ to use instead of C's rand() +// its performance is on par with C's rand() + + +// the state must be seeded in a way that it is not all zero, choose some +// arbitrary defaults (in this case: taken from splitmix64) +static rn_generator_state_t rn_current_state = { + .a = 0x9E3779B97F4A7C15, + .b = 0xBF58476D1CE4E5B9 +}; + + +// used for mixing the initializing seed +static uint64_t splitmix64 (splitmix64_state_t *state) { + + uint64_t result = state->s; + + state->s = result + 0x9E3779B97F4A7C15; + + result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9; + result = (result ^ (result >> 27)) * 0x94D049BB133111EB; + + return result ^ (result >> 31); +} + + +int n2n_srand (uint64_t seed) { + + uint8_t i; + splitmix64_state_t smstate = { seed }; + + rn_current_state.a = 0; + rn_current_state.b = 0; + + rn_current_state.a = splitmix64 (&smstate); + rn_current_state.b = splitmix64 (&smstate); + + // the following lines could be deleted as soon as it is formally prooved that + // there is no seed leading to (a == b == 0). until then, just to be safe: + if((rn_current_state.a == 0) && (rn_current_state.b == 0)) { + rn_current_state.a = 0x9E3779B97F4A7C15; + rn_current_state.b = 0xBF58476D1CE4E5B9; + } + + // stabilize in unlikely case of weak state with only a few bits set + for(i = 0; i < 32; i++) + n2n_rand(); + + return 0; +} + + +// the following code of xorshift128p was taken from +// https://en.wikipedia.org/wiki/Xorshift as of July, 2019 +// and thus is considered public domain +uint64_t n2n_rand (void) { + + uint64_t t = rn_current_state.a; + uint64_t const s = rn_current_state.b; + + rn_current_state.a = s; + t ^= t << 23; + t ^= t >> 17; + t ^= s ^ (s >> 26); + rn_current_state.b = t; + + return t + s; +} + + +// the following code tries to gather some entropy from several sources +// for use as seed. Note, that this code does not set the random generator +// state yet, a call to n2n_srand (n2n_seed()) would do +uint64_t n2n_seed (void) { + + uint64_t seed = 0; /* this could even go uninitialized */ + uint64_t ret = 0; /* this could even go uninitialized */ + size_t i = 0; + +#ifdef SYS_getrandom + int rc = -1; + for(i = 0; (i < RND_RETRIES) && (rc != sizeof(seed)); i++) { + rc = syscall (SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK); + // if successful, rc should contain the requested number of random bytes + if(rc != sizeof(seed)) { + if (errno != EAGAIN) { + traceEvent(TRACE_ERROR, "n2n_seed faced error errno=%u from getrandom syscall.", errno); + break; + } + } + } + + // if we still see an EAGAIN error here, we must have run out of retries + if(errno == EAGAIN) { + traceEvent(TRACE_ERROR, "n2n_seed saw getrandom syscall indicate not being able to provide enough entropy yet."); + } +#endif + + // as we want randomness, it does no harm to add up even uninitialized values or + // erroneously arbitrary values returned from the syscall for the first time + ret += seed; + + // __RDRND__ is set only if architecturual feature is set, e.g. compiled with -march=native +#ifdef __RDRND__ + for(i = 0; i < RND_RETRIES; i++) { + if(_rdrand64_step((unsigned long long*)&seed)) { + // success! + // from now on, we keep this inside the loop because in case of failure + // and with unchanged values, we do not want to double the previous value + ret += seed; + break; + } + // continue loop to try again otherwise + } + if(i == RND_RETRIES) { + traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDRND."); + } +#endif + + // __RDSEED__ ist set only if architecturual feature is set, e.g. compile with -march=native +#ifdef __RDSEED__ +#if __GNUC__ > 4 + for(i = 0; i < RND_RETRIES; i++) { + if(_rdseed64_step((unsigned long long*)&seed)) { + // success! + ret += seed; + break; + } + // continue loop to try again otherwise + } + if(i == RND_RETRIES) { + traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDSEED."); + } +#endif +#endif + +#ifdef WIN32 + HCRYPTPROV crypto_provider; + CryptAcquireContext (&crypto_provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptGenRandom (crypto_provider, 8, &seed); + CryptReleaseContext (crypto_provider, 0); + ret += seed; +#endif + + seed = time(NULL); /* UTC in seconds */ + ret += seed; + + seed = clock(); /* ticks since program start */ + seed *= 18444244737; + ret += seed; + + return ret; +} + +// an integer squrare root approximation +// from https://stackoverflow.com/a/1100591 +static int ftbl[33] = { + 0, 1, 1, 2, 2, 4, 5, 8, 11, 16, 22, 32, 45, 64, 90, + 128, 181 ,256 ,362, 512, 724, 1024, 1448, 2048, 2896, + 4096, 5792, 8192, 11585, 16384, 23170, 32768, 46340 }; + + +static int ftbl2[32] = { + 32768, 33276, 33776, 34269, 34755, 35235, 35708, 36174, + 36635, 37090, 37540, 37984, 38423, 38858, 39287, 39712, + 40132, 40548, 40960, 41367, 41771, 42170, 42566, 42959, + 43347, 43733, 44115, 44493, 44869, 45241, 45611, 45977 }; + + +static int i_sqrt (int val) { + + int cnt = 0; + int t = val; + + while(t) { + cnt++; + t>>=1; + } + + if(6 >= cnt) + t = (val << (6-cnt)); + else + t = (val >> (cnt-6)); + + return (ftbl[cnt] * ftbl2[t & 31]) >> 15; +} + + +static int32_t int_sqrt (int val) { + + int ret; + + ret = i_sqrt (val); + ret += i_sqrt (val - ret * ret) / 16; + + return ret; +} + + +// returns a random number from [0, max_n] with higher probability towards the borders +uint32_t n2n_rand_sqr (uint32_t max_n) { + + uint32_t raw_max = 0; + uint32_t raw_rnd = 0; + int32_t ret = 0; + + raw_max = (max_n+2) * (max_n+2); + raw_rnd = n2n_rand() % (raw_max); + + ret = int_sqrt(raw_rnd) / 2; + ret = (raw_rnd & 1) ? ret : -ret; + ret = max_n / 2 + ret; + + if(ret < 0) + ret = 0; + if (ret > max_n) + ret = max_n; + + return ret; +} diff --git a/bundles/n2n_ntop_v3/src/sn_management.c b/bundles/n2n_ntop_v3/src/sn_management.c new file mode 100644 index 00000000..0f34a398 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/sn_management.c @@ -0,0 +1,441 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* + * This file has a large amount of duplication with the edge_management.c + * code. In the fullness of time, they should both be merged + */ + +#include "n2n.h" +#include "edge_utils_win32.h" + +int load_allowed_sn_community (n2n_sn_t *sss); /* defined in sn_utils.c */ + +#define FLAG_WROK 1 +typedef struct n2n_mgmt_handler { + int flags; + char *cmd; + char *help; + void (*func)(n2n_sn_t *sss, char *udp_buf, struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv); +} n2n_mgmt_handler_t; + +static void mgmt_error (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, char *tag, char *msg) { + size_t msg_len; + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"error\"," + "\"error\":\"%s\"}\n", + tag, + msg); + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_stop (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(type==N2N_MGMT_WRITE) { + *sss->keep_running = 0; + } + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"keep_running\":%u}\n", + tag, + *sss->keep_running); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_verbose (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(type==N2N_MGMT_WRITE) { + if(argv) { + setTraceLevel(strtoul(argv, NULL, 0)); + } + } + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"traceLevel\":%u}\n", + tag, + getTraceLevel()); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_reload_communities (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + if(type!=N2N_MGMT_WRITE) { + mgmt_error(sss, udp_buf, sender_sock, tag, "writeonly"); + return; + } + + if(!sss->community_file) { + mgmt_error(sss, udp_buf, sender_sock, tag, "nofile"); + return; + } + + int ok = load_allowed_sn_community(sss); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"ok\":%i}\n", + tag, + ok); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_timestamps (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"start_time\":%lu," + "\"last_fwd\":%ld," + "\"last_reg_super\":%ld}\n", + tag, + sss->start_time, + sss->stats.last_fwd, + sss->stats.last_reg_super); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); +} + +static void mgmt_packetstats (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"forward\"," + "\"tx_pkt\":%lu}\n", + tag, + sss->stats.fwd); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"broadcast\"," + "\"tx_pkt\":%lu}\n", + tag, + sss->stats.broadcast); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"reg_super\"," + "\"rx_pkt\":%lu," + "\"nak\":%lu}\n", + tag, + sss->stats.reg_super, + sss->stats.reg_super_nak); + + /* Note: reg_super_nak is not currently incremented anywhere */ + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + /* Generic errors when trying to sendto() */ + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"type\":\"errors\"," + "\"tx_pkt\":%lu}\n", + tag, + sss->stats.errors); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + +} + +static void mgmt_communities (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + struct sn_community *community, *tmp; + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + HASH_ITER(hh, sss->communities, community, tmp) { + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"community\":\"%s\"," + "\"purgeable\":%i," + "\"is_federation\":%i," + "\"ip4addr\":\"%s\"}\n", + tag, + (community->is_federation) ? "-/-" : community->community, + community->purgeable, + community->is_federation, + (community->auto_ip_net.net_addr == 0) ? "" : ip_subnet_to_str(ip_bit_str, &community->auto_ip_net)); + + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + } +} + +static void mgmt_edges (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + struct sn_community *community, *tmp; + struct peer_info *peer, *tmpPeer; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + HASH_ITER(hh, sss->communities, community, tmp) { + HASH_ITER(hh, community->edges, peer, tmpPeer) { + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"community\":\"%s\"," + "\"ip4addr\":\"%s\"," + "\"purgeable\":%i," + "\"macaddr\":\"%s\"," + "\"sockaddr\":\"%s\"," + "\"proto\":\"%s\"," + "\"desc\":\"%s\"," + "\"last_seen\":%li}\n", + tag, + (community->is_federation) ? "-/-" : community->community, + (peer->dev_addr.net_addr == 0) ? "" : ip_subnet_to_str(ip_bit_str, &peer->dev_addr), + peer->purgeable, + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + ((peer->socket_fd >= 0) && (peer->socket_fd != sss->sock)) ? "TCP" : "UDP", + peer->dev_desc, + peer->last_seen); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + } + } +} + +static void mgmt_unimplemented (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + mgmt_error(sss, udp_buf, sender_sock, tag, "unimplemented"); +} + +static void mgmt_help (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv); + +n2n_mgmt_handler_t mgmt_handlers[] = { + { .cmd = "supernodes", .help = "Reserved for edge", .func = mgmt_unimplemented}, + + { .cmd = "stop", .flags = FLAG_WROK, .help = "Gracefully exit edge", .func = mgmt_stop}, + { .cmd = "verbose", .flags = FLAG_WROK, .help = "Manage verbosity level", .func = mgmt_verbose}, + { .cmd = "reload_communities", .flags = FLAG_WROK, .help = "Reloads communities and user's public keys", .func = mgmt_reload_communities}, + { .cmd = "communities", .help = "List current communities", .func = mgmt_communities}, + { .cmd = "edges", .help = "List current edges/peers", .func = mgmt_edges}, + { .cmd = "timestamps", .help = "Event timestamps", .func = mgmt_timestamps}, + { .cmd = "packetstats", .help = "Traffic statistics", .func = mgmt_packetstats}, + { .cmd = "help", .flags = FLAG_WROK, .help = "Show JSON commands", .func = mgmt_help}, + { .cmd = NULL }, +}; + +static void mgmt_help (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *tag, char *argv0, char *argv) { + size_t msg_len; + n2n_mgmt_handler_t *handler; + + /* + * Even though this command is readonly, we deliberately do not check + * the type - allowing help replies to both read and write requests + */ + + for( handler=mgmt_handlers; handler->cmd; handler++ ) { + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{" + "\"_tag\":\"%s\"," + "\"_type\":\"row\"," + "\"cmd\":\"%s\"," + "\"help\":\"%s\"}\n", + tag, + handler->cmd, + handler->help); + + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + } +} + +/* + * Check if the user is authorised for this command. + * - this should be more configurable! + * - for the moment we use some simple heuristics: + * Reads are not dangerous, so they are simply allowed + * Writes are possibly dangerous, so they need a fake password + */ +static int mgmt_auth (n2n_sn_t *sss, const struct sockaddr_in sender_sock, enum n2n_mgmt_type type, char *auth, char *argv0, char *argv) { + + if(auth) { + /* If we have an auth key, it must match */ + if(sss->mgmt_password_hash == pearson_hash_64((uint8_t*)auth, strlen(auth))) { + return 1; + } + return 0; + } + /* if we dont have an auth key, we can still read */ + if(type == N2N_MGMT_READ) { + return 1; + } + + return 0; +} + +void handleMgmtJson_sn (n2n_sn_t *sss, char *udp_buf, const struct sockaddr_in sender_sock) { + + char cmdlinebuf[80]; + enum n2n_mgmt_type type; + char *typechar; + char *options; + char *argv0; + char *argv; + char *tag; + char *flagstr; + int flags; + char *auth; + n2n_mgmt_handler_t *handler; + size_t msg_len; + + /* save a copy of the commandline before we reuse the udp_buf */ + strncpy(cmdlinebuf, udp_buf, sizeof(cmdlinebuf)-1); + cmdlinebuf[sizeof(cmdlinebuf)-1] = 0; + + traceEvent(TRACE_DEBUG, "mgmt json %s", cmdlinebuf); + + typechar = strtok(cmdlinebuf, " \r\n"); + if(!typechar) { + /* should not happen */ + mgmt_error(sss, udp_buf, sender_sock, "-1", "notype"); + return; + } + if(*typechar == 'r') { + type=N2N_MGMT_READ; + } else if(*typechar == 'w') { + type=N2N_MGMT_WRITE; + } else { + /* dunno how we got here */ + mgmt_error(sss, udp_buf, sender_sock, "-1", "badtype"); + return; + } + + /* Extract the tag to use in all reply packets */ + options = strtok(NULL, " \r\n"); + if(!options) { + mgmt_error(sss, udp_buf, sender_sock, "-1", "nooptions"); + return; + } + + argv0 = strtok(NULL, " \r\n"); + if(!argv0) { + mgmt_error(sss, udp_buf, sender_sock, "-1", "nocmd"); + return; + } + + /* + * The entire rest of the line is the argv. We apply no processing + * or arg separation so that the cmd can use it however it needs. + */ + argv = strtok(NULL, "\r\n"); + + /* + * There might be an auth token mixed in with the tag + */ + tag = strtok(options, ":"); + flagstr = strtok(NULL, ":"); + if(flagstr) { + flags = strtoul(flagstr, NULL, 16); + } else { + flags = 0; + } + + /* Only 1 flag bit defined at the moment - "auth option present" */ + if(flags & 1) { + auth = strtok(NULL, ":"); + } else { + auth = NULL; + } + + if(!mgmt_auth(sss, sender_sock, type, auth, argv0, argv)) { + mgmt_error(sss, udp_buf, sender_sock, tag, "badauth"); + return; + } + + for( handler=mgmt_handlers; handler->cmd; handler++ ) { + if(0 == strcmp(handler->cmd, argv0)) { + break; + } + } + if(!handler->cmd) { + mgmt_error(sss, udp_buf, sender_sock, tag, "unknowncmd"); + return; + } + + if((type==N2N_MGMT_WRITE) && !(handler->flags & FLAG_WROK)) { + mgmt_error(sss, udp_buf, sender_sock, tag, "readonly"); + return; + } + + /* + * TODO: + * The tag provided by the requester could contain chars + * that make our JSON invalid. + * - do we care? + */ + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{\"_tag\":\"%s\",\"_type\":\"begin\",\"cmd\":\"%s\"}\n", tag, argv0); + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + + handler->func(sss, udp_buf, sender_sock, type, tag, argv0, argv); + + msg_len = snprintf(udp_buf, N2N_PKT_BUF_SIZE, + "{\"_tag\":\"%s\",\"_type\":\"end\"}\n", tag); + sendto(sss->mgmt_sock, udp_buf, msg_len, 0, + (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); + return; +} diff --git a/bundles/n2n_ntop_v3/src/sn_selection.c b/bundles/n2n_ntop_v3/src/sn_selection.c new file mode 100644 index 00000000..13c0ff13 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/sn_selection.c @@ -0,0 +1,253 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +static SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_read (n2n_edge_t *eee); +static int sn_selection_criterion_sort (peer_info_t *a, peer_info_t *b); + + +/* Initialize selection_criterion field in peer_info structure*/ +int sn_selection_criterion_init (peer_info_t *peer) { + + if(peer != NULL) { + sn_selection_criterion_default(&(peer->selection_criterion)); + } + + return 0; /* OK */ +} + + +/* Set selection_criterion field to default value according to selected strategy. */ +int sn_selection_criterion_default (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion) { + + *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)(UINT64_MAX >> 1) - 1; + + return 0; /* OK */ +} + + +/* Set selection_criterion field to 'bad' value (worse than default) according to selected strategy. */ +int sn_selection_criterion_bad (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion) { + + *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)(UINT64_MAX >> 1); + + return 0; /* OK */ +} + +/* Set selection_criterion field to 'good' value (better than default) according to selected strategy. */ +int sn_selection_criterion_good (SN_SELECTION_CRITERION_DATA_TYPE *selection_criterion) { + + *selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)(UINT64_MAX >> 1) - 2; + + return 0; /* OK */ +} + + +/* Take data from PEER_INFO payload and transform them into a selection_criterion. + * This function is highly dependant of the chosen selection criterion. + */ +int sn_selection_criterion_calculate (n2n_edge_t *eee, peer_info_t *peer, SN_SELECTION_CRITERION_DATA_TYPE *data) { + + SN_SELECTION_CRITERION_DATA_TYPE common_data; + int sum = 0; + + common_data = sn_selection_criterion_common_read(eee); + + switch(eee->conf.sn_selection_strategy) { + + case SN_SELECTION_STRATEGY_LOAD: { + peer->selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)(be32toh(*data) + common_data); + + /* Mitigation of the real supernode load in order to see less oscillations. + * Edges jump from a supernode to another back and forth due to purging. + * Because this behavior has a cost of switching, the real load is mitigated with a stickyness factor. + * This factor is dynamically calculated basing on network size and prevent that unnecessary switching */ + if(peer == eee->curr_sn) { + sum = HASH_COUNT(eee->known_peers) + HASH_COUNT(eee->pending_peers); + peer->selection_criterion = peer->selection_criterion * sum / (sum + 1); + } + break; + } + + case SN_SELECTION_STRATEGY_RTT: { + peer->selection_criterion = (SN_SELECTION_CRITERION_DATA_TYPE)((uint32_t)time_stamp() >> 22) - common_data; + break; + } + + case SN_SELECTION_STRATEGY_MAC: { + peer->selection_criterion = 0; + memcpy(&peer->selection_criterion, /* leftbound, don't mess with pointer arithmetics */ + peer->mac_addr, + N2N_MAC_SIZE); + peer->selection_criterion = be64toh(peer->selection_criterion); + peer->selection_criterion >>= (sizeof(peer->selection_criterion) - N2N_MAC_SIZE) * 8; /* rightbound */ + break; + } + + default: { + // this should never happen + traceEvent(TRACE_ERROR, "selection_criterion unknown selection strategy configuration"); + break; + } + } + + return 0; /* OK */ +} + + +/* Set sn_selection_criterion_common_data field to default value. */ +int sn_selection_criterion_common_data_default (n2n_edge_t *eee) { + + switch(eee->conf.sn_selection_strategy) { + + case SN_SELECTION_STRATEGY_LOAD: { + SN_SELECTION_CRITERION_DATA_TYPE tmp = 0; + + tmp = HASH_COUNT(eee->pending_peers); + if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED) { + tmp *= 2; + } + eee->sn_selection_criterion_common_data = tmp / HASH_COUNT(eee->conf.supernodes); + break; + } + + case SN_SELECTION_STRATEGY_RTT: { + eee->sn_selection_criterion_common_data = (SN_SELECTION_CRITERION_DATA_TYPE)((uint32_t)time_stamp() >> 22); + break; + } + + case SN_SELECTION_STRATEGY_MAC: { + eee->sn_selection_criterion_common_data = 0; + break; + } + + default: { + // this should never happen + traceEvent(TRACE_ERROR, "selection_criterion unknown selection strategy configuration"); + break; + } + } + + return 0; /* OK */ +} + + +/* Return the value of sn_selection_criterion_common_data field. */ +static SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_common_read (n2n_edge_t *eee) { + + return eee->sn_selection_criterion_common_data; +} + + +/* Function that compare two selection_criterion fields and sorts them in ascending order. */ +static int sn_selection_criterion_sort (peer_info_t *a, peer_info_t *b) { + + int ret = 0; + + // comparison function for sorting supernodes in ascending order of their selection_criterion. + if(a->selection_criterion > b->selection_criterion) + ret = 1; + else if(a->selection_criterion < b->selection_criterion) + ret = -2; + + return ret; +} + + +/* Function that sorts peer_list using sn_selection_criterion_sort. */ +int sn_selection_sort (peer_info_t **peer_list) { + + HASH_SORT(*peer_list, sn_selection_criterion_sort); + + return 0; /* OK */ +} + + +/* Function that gathers requested data on a supernode. + * it remains unaffected by selection strategy because it refers to edge behaviour only + */ +SN_SELECTION_CRITERION_DATA_TYPE sn_selection_criterion_gather_data (n2n_sn_t *sss) { + + SN_SELECTION_CRITERION_DATA_TYPE data = 0, tmp = 0; + struct sn_community *comm, *tmp_comm; + + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + // number of nodes in the community + the community itself + tmp = HASH_COUNT(comm->edges) + 1; + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + // double-count encrypted communities (and their nodes): they exert more load on supernode + tmp *= 2; + } + data += tmp; + } + + return htobe64(data); +} + + +/* Convert selection_criterion field in a string for management port output. */ +extern char * sn_selection_criterion_str (n2n_edge_t *eee, selection_criterion_str_t out, peer_info_t *peer) { + + int chars = 0; + + + if(NULL == out) { + return NULL; + } + memset(out, 0, SN_SELECTION_CRITERION_BUF_SIZE); + + // keep off the super-big values (used for "bad" or "good" or "undetermined" supernodes, + // easier to sort to the end of the list). + // Alternatively, typecast to (int16_t) and check for greater or equal zero + if(peer->selection_criterion < (UINT64_MAX >> 2)) { + + switch(eee->conf.sn_selection_strategy) { + + case SN_SELECTION_STRATEGY_LOAD: { + chars = snprintf(out, SN_SELECTION_CRITERION_BUF_SIZE, "load = %8ld", peer->selection_criterion); + break; + } + + case SN_SELECTION_STRATEGY_RTT: { + chars = snprintf(out, SN_SELECTION_CRITERION_BUF_SIZE, "rtt = %6ld ms", peer->selection_criterion); + break; + } + + case SN_SELECTION_STRATEGY_MAC: { + chars = snprintf(out, SN_SELECTION_CRITERION_BUF_SIZE, "%s", (int64_t)peer->selection_criterion > 0 ? "active" : ""); + break; + } + + default: { + // this should never happen + traceEvent(TRACE_ERROR, "selection_criterion unknown selection strategy configuration"); + break; + } + } + + // this test is to make "-Wformat-truncation" less sad + if(chars > SN_SELECTION_CRITERION_BUF_SIZE) { + traceEvent(TRACE_ERROR, "selection_criterion buffer overflow"); + } + } + + return out; +} diff --git a/bundles/n2n_ntop_v3/src/sn_utils.c b/bundles/n2n_ntop_v3/src/sn_utils.c new file mode 100644 index 00000000..40d67468 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/sn_utils.c @@ -0,0 +1,2930 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include "n2n.h" + +#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) + +int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list); +int resolve_check (n2n_resolve_parameter_t *param, uint8_t resolution_request, time_t now); +int resolve_cancel_thread (n2n_resolve_parameter_t *param); + + +static ssize_t sendto_peer (n2n_sn_t *sss, + const struct peer_info *peer, + const uint8_t *pktbuf, + size_t pktsize); + +static int sendto_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size); + +static uint16_t reg_lifetime (n2n_sn_t *sss); + +static int update_edge (n2n_sn_t *sss, + const n2n_common_t* cmn, + const n2n_REGISTER_SUPER_t* reg, + struct sn_community *comm, + const n2n_sock_t *sender_sock, + const SOCKET socket_fd, + n2n_auth_t *answer_auth, + int skip_add, + time_t now); + +static int re_register_and_purge_supernodes (n2n_sn_t *sss, + struct sn_community *comm, + time_t *p_last_re_reg_and_purge, + time_t now, + uint8_t forced); + +static int purge_expired_communities (n2n_sn_t *sss, + time_t* p_last_purge, + time_t now); + +static int sort_communities (n2n_sn_t *sss, + time_t* p_last_sort, + time_t now); + +static int process_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + char *mgmt_buf, + size_t mgmt_size, + time_t now); + +static int process_udp (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const SOCKET socket_fd, + uint8_t *udp_buf, + size_t udp_size, + time_t now); + + +/* ************************************** */ + + +void close_tcp_connection (n2n_sn_t *sss, n2n_tcp_connection_t *conn) { + + struct sn_community *comm, *tmp_comm; + struct peer_info *edge, *tmp_edge; + + if(!conn) + return; + + // find peer by file descriptor + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + HASH_ITER(hh, comm->edges, edge, tmp_edge) { + if(edge->socket_fd == conn->socket_fd) { + // remove peer + HASH_DEL(comm->edges, edge); + free(edge); + goto close_conn; /* break - level 2 */ + } + } + } + + close_conn: + // close the connection + shutdown(conn->socket_fd, SHUT_RDWR); + closesocket(conn->socket_fd); + // forget about the connection, will be deleted later + conn->inactive = 1; +} + + +/* *************************************************** */ + + +// generate shared secrets for user authentication; can be done only after +// federation name is known (-F) and community list completely read (-c) +void calculate_shared_secrets (n2n_sn_t *sss) { + + struct sn_community *comm, *tmp_comm; + sn_user_t *user, *tmp_user; + + traceEvent(TRACE_INFO, "started shared secrets calculation for edge authentication"); + + generate_private_key(sss->private_key, sss->federation->community + 1); /* skip '*' federation leading character */ + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + if(comm->is_federation) { + continue; + } + HASH_ITER(hh, comm->allowed_users, user, tmp_user) { + // calculate common shared secret (ECDH) + generate_shared_secret(user->shared_secret, sss->private_key, user->public_key); + // prepare for use as key + user->shared_secret_ctx = (he_context_t*)calloc(1, sizeof(speck_context_t)); + speck_init((speck_context_t**)&user->shared_secret_ctx, user->shared_secret, 128); + } + } + + traceEvent(TRACE_NORMAL, "calculated shared secrets for edge authentication"); +} + + +// calculate dynamic keys +void calculate_dynamic_keys (n2n_sn_t *sss) { + + struct sn_community *comm, *tmp_comm = NULL; + + traceEvent(TRACE_INFO, "calculating dynamic keys"); + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + // skip federation + if(comm->is_federation) { + continue; + } + + // calculate dynamic keys if this is a user/pw auth'ed community + if(comm->allowed_users) { + calculate_dynamic_key(comm->dynamic_key, /* destination */ + sss->dynamic_key_time, /* time - same for all */ + (uint8_t *)comm->community, /* community name */ + (uint8_t *)sss->federation->community); /* federation name */ + packet_header_change_dynamic_key(comm->dynamic_key, + &(comm->header_encryption_ctx_dynamic), + &(comm->header_iv_ctx_dynamic)); + traceEvent(TRACE_DEBUG, "calculated dynamic key for community '%s'", comm->community); + } + } +} + + +// send RE_REGISTER_SUPER to all edges from user/pw auth'ed communites +void send_re_register_super (n2n_sn_t *sss) { + + struct sn_community *comm, *tmp_comm = NULL; + struct peer_info *edge, *tmp_edge = NULL; + n2n_common_t cmn; + uint8_t rereg_buf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + n2n_sock_str_t sockbuf; + + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + if(comm->is_federation) { + continue; + } + + // send RE_REGISTER_SUPER to edges if this is a user/pw auth community + if(comm->allowed_users) { + // prepare + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_re_register_super; + cmn.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE); + + HASH_ITER(hh, comm->edges, edge, tmp_edge) { + // encode + encx = 0; + encode_common(rereg_buf, &encx, &cmn); + + // send + traceEvent(TRACE_DEBUG, "send RE_REGISTER_SUPER to %s", + sock_to_cstr(sockbuf, &(edge->sock))); + + packet_header_encrypt(rereg_buf, encx, encx, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + time_stamp()); + + /* sent = */ sendto_peer(sss, edge, rereg_buf, encx); + } + } + } +} + + +/** Load the list of allowed communities. Existing/previous ones will be removed, + * return 0 on success, -1 if file not found, -2 if no valid entries found + */ +int load_allowed_sn_community (n2n_sn_t *sss) { + + char buffer[4096], *line, *cmn_str, net_str[20], format[20]; + + sn_user_t *user, *tmp_user; + n2n_desc_t username; + n2n_private_public_key_t public_key; + char ascii_public_key[(N2N_PRIVATE_PUBLIC_KEY_SIZE * 8 + 5) / 6 + 1]; + + dec_ip_str_t ip_str = {'\0'}; + uint8_t bitlen; + in_addr_t net; + uint32_t mask; + FILE *fd = fopen(sss->community_file, "r"); + + struct sn_community *comm, *tmp_comm, *last_added_comm = NULL; + struct peer_info *edge, *tmp_edge; + node_supernode_association_t *assoc, *tmp_assoc; + n2n_tcp_connection_t *conn; + time_t any_time = 0; + + uint32_t num_communities = 0; + + struct sn_community_regular_expression *re, *tmp_re; + uint32_t num_regex = 0; + int has_net; + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "File %s not found", sss->community_file); + return -1; + } + + // reset data structures ------------------------------ + + // send RE_REGISTER_SUPER to all edges from user/pw auth communites, this is safe because + // follow-up REGISTER_SUPER cannot be handled before this function ends + send_re_register_super(sss); + + // remove communities (not: federation) + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + if(comm->is_federation) { + continue; + } + + // remove all edges from community + HASH_ITER(hh, comm->edges, edge, tmp_edge) { + // remove all edge associations (with other supernodes) + HASH_ITER(hh, comm->assoc, assoc, tmp_assoc) { + HASH_DEL(comm->assoc, assoc); + free(assoc); + } + + // close TCP connections, if any (also causes reconnect) + // and delete edge from list + if((edge->socket_fd != sss->sock) && (edge->socket_fd >= 0)) { + HASH_FIND_INT(sss->tcp_connections, &(edge->socket_fd), conn); + close_tcp_connection(sss, conn); /* also deletes the edge */ + } else { + HASH_DEL(comm->edges, edge); + free(edge); + } + } + + // remove allowed users from community + HASH_ITER(hh, comm->allowed_users, user, tmp_user) { + free(user->shared_secret_ctx); + HASH_DEL(comm->allowed_users, user); + free(user); + } + + // remove community + HASH_DEL(sss->communities, comm); + if(NULL != comm->header_encryption_ctx_static) { + // remove header encryption keys + free(comm->header_encryption_ctx_static); + free(comm->header_iv_ctx_static); + free(comm->header_encryption_ctx_dynamic); + free(comm->header_iv_ctx_dynamic); + } + free(comm); + } + + // remove all regular expressions for allowed communities + HASH_ITER(hh, sss->rules, re, tmp_re) { + HASH_DEL(sss->rules, re); + free(re); + } + + // prepare reading data ------------------------------- + + // new key_time for all communities, requires dynamic keys to be recalculated (see further below), + // and edges to re-register (see above) and ... + sss->dynamic_key_time = time(NULL); + // ... federated supernodes to re-register + re_register_and_purge_supernodes(sss, sss->federation, &any_time, any_time, 1 /* forced */); + + // format definition for possible user-key entries + sprintf(format, "%c %%%ds %%%lds", N2N_USER_KEY_LINE_STARTER, N2N_DESC_SIZE - 1, sizeof(ascii_public_key)-1); + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + int len = strlen(line); + + if((len < 2) || line[0] == '#') { + continue; + } + + len--; + while(len > 0) { + if((line[len] == '\n') || (line[len] == '\r')) { + line[len] = '\0'; + len--; + } else { + break; + } + } + // the loop above does not always determine correct 'len' + len = strlen(line); + + // user-key line for edge authentication? + if(line[0] == N2N_USER_KEY_LINE_STARTER) { /* special first character */ + if(sscanf(line, format, username, ascii_public_key) == 2) { /* correct format */ + if(last_added_comm) { /* is there a valid community to add users to */ + user = (sn_user_t*)calloc(1, sizeof(sn_user_t)); + if(user) { + // username + memcpy(user->name, username, sizeof(username)); + // public key + ascii_to_bin(public_key, ascii_public_key); + memcpy(user->public_key, public_key, sizeof(public_key)); + // common shared secret will be calculated later + // add to list + HASH_ADD(hh, last_added_comm->allowed_users, public_key, sizeof(n2n_private_public_key_t), user); + traceEvent(TRACE_INFO, "added user '%s' with public key '%s' to community '%s'", + user->name, ascii_public_key, last_added_comm->community); + // enable header encryption + last_added_comm->header_encryption = HEADER_ENCRYPTION_ENABLED; + packet_header_setup_key(last_added_comm->community, + &(last_added_comm->header_encryption_ctx_static), + &(last_added_comm->header_encryption_ctx_dynamic), + &(last_added_comm->header_iv_ctx_static), + &(last_added_comm->header_iv_ctx_dynamic)); + // dynamic key setup follows at a later point in code + } + continue; + } + } + } + + // --- community name or regular expression + + // cut off any IP sub-network upfront + cmn_str = (char*)calloc(len + 1, sizeof(char)); + has_net = (sscanf(line, "%s %s", cmn_str, net_str) == 2); + + // if it contains typical characters... + if(NULL != strpbrk(cmn_str, ".*+?[]\\")) { + // ...it is treated as regular expression + re = (struct sn_community_regular_expression*)calloc(1, sizeof(struct sn_community_regular_expression)); + if(re) { + re->rule = re_compile(cmn_str); + HASH_ADD_PTR(sss->rules, rule, re); + num_regex++; + traceEvent(TRACE_INFO, "added regular expression for allowed communities '%s'", cmn_str); + free(cmn_str); + last_added_comm = NULL; + continue; + } + } + + comm = (struct sn_community*)calloc(1,sizeof(struct sn_community)); + + if(comm != NULL) { + comm_init(comm, cmn_str); + /* loaded from file, this community is unpurgeable */ + comm->purgeable = COMMUNITY_UNPURGEABLE; + /* we do not know if header encryption is used in this community, + * first packet will show. just in case, setup the key. */ + comm->header_encryption = HEADER_ENCRYPTION_UNKNOWN; + packet_header_setup_key(comm->community, + &(comm->header_encryption_ctx_static), + &(comm->header_encryption_ctx_dynamic), + &(comm->header_iv_ctx_static), + &(comm->header_iv_ctx_dynamic)); + HASH_ADD_STR(sss->communities, community, comm); + last_added_comm = comm; + + num_communities++; + traceEvent(TRACE_INFO, "added allowed community '%s' [total: %u]", + (char*)comm->community, num_communities); + + // check for sub-network address + if(has_net) { + if(sscanf(net_str, "%15[^/]/%hhu", ip_str, &bitlen) != 2) { + traceEvent(TRACE_WARNING, "bad net/bit format '%s' for community '%c', ignoring; see comments inside community.list file", + net_str, cmn_str); + has_net = 0; + } + net = inet_addr(ip_str); + mask = bitlen2mask(bitlen); + if((net == (in_addr_t)(-1)) || (net == INADDR_NONE) || (net == INADDR_ANY) + || ((ntohl(net) & ~mask) != 0)) { + traceEvent(TRACE_WARNING, "bad network '%s/%u' in '%s' for community '%s', ignoring", + ip_str, bitlen, net_str, cmn_str); + has_net = 0; + } + if((bitlen > 30) || (bitlen == 0)) { + traceEvent(TRACE_WARNING, "bad prefix '%hhu' in '%s' for community '%s', ignoring", + bitlen, net_str, cmn_str); + has_net = 0; + } + } + if(has_net) { + comm->auto_ip_net.net_addr = ntohl(net); + comm->auto_ip_net.net_bitlen = bitlen; + traceEvent(TRACE_INFO, "assigned sub-network %s/%u to community '%s'", + inet_ntoa(*(struct in_addr *) &net), + comm->auto_ip_net.net_bitlen, + comm->community); + } else { + assign_one_ip_subnet(sss, comm); + } + } + free(cmn_str); + } + + fclose(fd); + + if((num_regex + num_communities) == 0) { + traceEvent(TRACE_WARNING, "file %s does not contain any valid community names or regular expressions", sss->community_file); + return -2; + } + + traceEvent(TRACE_NORMAL, "loaded %u fixed-name communities from %s", + num_communities, sss->community_file); + + traceEvent(TRACE_NORMAL, "loaded %u regular expressions for community name matching from %s", + num_regex, sss->community_file); + + // calculate allowed user's shared secrets (shared with federation) + calculate_shared_secrets(sss); + + // calculcate communties' dynamic keys + calculate_dynamic_keys(sss); + + // no new communities will be allowed + sss->lock_communities = 1; + + return 0; +} + + +/* *************************************************** */ + + +/** Send a datagram to a file descriptor socket. + * + * @return -1 on error otherwise number of bytes sent + */ +static ssize_t sendto_fd (n2n_sn_t *sss, + SOCKET socket_fd, + const struct sockaddr *socket, + const uint8_t *pktbuf, + size_t pktsize) { + + ssize_t sent = 0; + n2n_tcp_connection_t *conn; + + sent = sendto(socket_fd, (void *)pktbuf, pktsize, 0 /* flags */, + socket, sizeof(struct sockaddr_in)); + + if((sent <= 0) && (errno)) { + char * c = strerror(errno); + traceEvent(TRACE_ERROR, "sendto failed (%d) %s", errno, c); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + // if the erroneous connection is tcp, i.e. not the regular sock... + if((socket_fd >= 0) && (socket_fd != sss->sock)) { + // ...forget about the corresponding peer and the connection + HASH_FIND_INT(sss->tcp_connections, &socket_fd, conn); + close_tcp_connection(sss, conn); + return -1; + } + } else { + traceEvent(TRACE_DEBUG, "sendto sent=%d to ", (signed int)sent); + } + + return sent; +} + + +/** Send a datagram to a network order socket of type struct sockaddr. + * + * @return -1 on error otherwise number of bytes sent + */ +static ssize_t sendto_sock(n2n_sn_t *sss, + SOCKET socket_fd, + const struct sockaddr *socket, + const uint8_t *pktbuf, + size_t pktsize) { + + ssize_t sent = 0; + int value = 0; + + // if the connection is tcp, i.e. not the regular sock... + if((socket_fd >= 0) && (socket_fd != sss->sock)) { + + setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); + value = 1; +#ifdef LINUX + setsockopt(socket_fd, IPPROTO_TCP, TCP_CORK, &value, sizeof(value)); +#endif + + // prepend packet length... + uint16_t pktsize16 = htobe16(pktsize); + sent = sendto_fd(sss, socket_fd, socket, (uint8_t*)&pktsize16, sizeof(pktsize16)); + + if(sent <= 0) + return -1; + // ...before sending the actual data + } + + sent = sendto_fd(sss, socket_fd, socket, pktbuf, pktsize); + + // if the connection is tcp, i.e. not the regular sock... + if((socket_fd >= 0) && (socket_fd != sss->sock)) { + value = 1; /* value should still be set to 1 */ + setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); +#ifdef LINUX + value = 0; + setsockopt(socket_fd, IPPROTO_TCP, TCP_CORK, &value, sizeof(value)); +#endif + } + + return sent; +} + + +/** Send a datagram to a peer whose destination socket is embodied in its sock field of type n2n_sock_t. + * It calls sendto_sock to do the final send. + * + * @return -1 on error otherwise number of bytes sent + */ +static ssize_t sendto_peer (n2n_sn_t *sss, + const struct peer_info *peer, + const uint8_t *pktbuf, + size_t pktsize) { + + n2n_sock_str_t sockbuf; + + if(AF_INET == peer->sock.family) { + + // network order socket + struct sockaddr_in socket; + fill_sockaddr((struct sockaddr *)&socket, sizeof(socket), &(peer->sock)); + + traceEvent(TRACE_DEBUG, "sent %lu bytes to [%s]", + pktsize, + sock_to_cstr(sockbuf, &(peer->sock))); + + return sendto_sock(sss, + (peer->socket_fd >= 0) ? peer->socket_fd : sss->sock, + (const struct sockaddr*)&socket, pktbuf, pktsize); + } else { + /* AF_INET6 not implemented */ + errno = EAFNOSUPPORT; + return -1; + } +} + + +/** Try and broadcast a message to all edges in the community. + * + * This will send the exact same datagram to zero or more edges registered to + * the supernode. + */ +static int try_broadcast (n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t srcMac, + uint8_t from_supernode, + const uint8_t * pktbuf, + size_t pktsize) { + + struct peer_info *scan, *tmp; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + traceEvent(TRACE_DEBUG, "try_broadcast"); + + /* We have to make sure that a broadcast reaches the other supernodes and edges + * connected to them. try_broadcast needs a from_supernode parameter: if set, + * do forward to edges of community only. If unset, forward to all locally known + * nodes of community AND all supernodes associated with the community */ + + if (!from_supernode) { + HASH_ITER(hh, sss->federation->edges, scan, tmp) { + int data_sent_len; + + data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); + + if(data_sent_len != pktsize) { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to supernode [%s] %s failed %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + strerror(errno)); + } else { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to supernode [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } + } + } + + if(comm) { + HASH_ITER(hh, comm->edges, scan, tmp) { + if(memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t)) != 0) { + /* REVISIT: exclude if the destination socket is where the packet came from. */ + int data_sent_len; + + data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); + + if(data_sent_len != pktsize) { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + strerror(errno)); + } else { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } + } + } + } + + return 0; +} + + +static int try_forward (n2n_sn_t * sss, + const struct sn_community *comm, + const n2n_common_t * cmn, + const n2n_mac_t dstMac, + uint8_t from_supernode, + const uint8_t * pktbuf, + size_t pktsize) { + + struct peer_info * scan; + node_supernode_association_t *assoc; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + + HASH_FIND_PEER(comm->edges, dstMac, scan); + + if(NULL != scan) { + int data_sent_len; + data_sent_len = sendto_peer(sss, scan, pktbuf, pktsize); + + if(data_sent_len == pktsize) { + ++(sss->stats.fwd); + traceEvent(TRACE_DEBUG, "unicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } else { + ++(sss->stats.errors); + traceEvent(TRACE_ERROR, "unicast %lu to [%s] %s FAILED (%d: %s)", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + errno, strerror(errno)); + return -1; + } + } else { + if(!from_supernode) { + // check if target edge is associated with a certain supernode + HASH_FIND(hh, comm->assoc, dstMac, sizeof(n2n_mac_t), assoc); + if(assoc) { + traceEvent(TRACE_DEBUG, "found mac address associated with a known supernode, forwarding packet to that supernode"); + sendto_sock(sss, sss->sock, + (const struct sockaddr*)&(assoc->sock), + pktbuf, pktsize); + } else { + // forwarding packet to all federated supernodes + traceEvent(TRACE_DEBUG, "unknown mac address, broadcasting packet to all federated supernodes"); + try_broadcast(sss, NULL, cmn, sss->mac_addr, from_supernode, pktbuf, pktsize); + } + } else { + traceEvent(TRACE_DEBUG, "unknown mac address in packet from a supernode, dropping the packet"); + /* Not a known MAC so drop. */ + return -2; + } + } + + return 0; +} + + +/** Initialise some fields of the community structure **/ +int comm_init (struct sn_community *comm, char *cmn) { + + strncpy((char*)comm->community, cmn, N2N_COMMUNITY_SIZE); + comm->community[N2N_COMMUNITY_SIZE - 1] = '\0'; + comm->is_federation = IS_NO_FEDERATION; + + return 0; /* OK */ +} + + +/** Initialise the supernode structure */ +int sn_init_defaults (n2n_sn_t *sss) { + + char *tmp_string; + +#ifdef WIN32 + initWin32(); +#endif + + pearson_hash_init(); + + memset(sss, 0, sizeof(n2n_sn_t)); + + strncpy(sss->version, GIT_RELEASE, sizeof(n2n_version_t)); + sss->version[sizeof(n2n_version_t) - 1] = '\0'; + sss->daemon = 1; /* By defult run as a daemon. */ + sss->lport = N2N_SN_LPORT_DEFAULT; + sss->mport = N2N_SN_MGMT_PORT; + sss->sock = -1; + sss->mgmt_sock = -1; + sss->min_auto_ip_net.net_addr = inet_addr(N2N_SN_MIN_AUTO_IP_NET_DEFAULT); + sss->min_auto_ip_net.net_addr = ntohl(sss->min_auto_ip_net.net_addr); + sss->min_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; + sss->max_auto_ip_net.net_addr = inet_addr(N2N_SN_MAX_AUTO_IP_NET_DEFAULT); + sss->max_auto_ip_net.net_addr = ntohl(sss->max_auto_ip_net.net_addr); + sss->max_auto_ip_net.net_bitlen = N2N_SN_AUTO_IP_NET_BIT_DEFAULT; + + sss->federation = (struct sn_community *)calloc(1, sizeof(struct sn_community)); + /* Initialize the federation */ + if(sss->federation) { + if(getenv("N2N_FEDERATION")) + snprintf(sss->federation->community, N2N_COMMUNITY_SIZE - 1 ,"*%s", getenv("N2N_FEDERATION")); + else + strncpy(sss->federation->community, (char*)FEDERATION_NAME, N2N_COMMUNITY_SIZE); + sss->federation->community[N2N_COMMUNITY_SIZE - 1] = '\0'; + /* enable the flag for federation */ + sss->federation->is_federation = IS_FEDERATION; + sss->federation->purgeable = COMMUNITY_UNPURGEABLE; + /* header encryption enabled by default */ + sss->federation->header_encryption = HEADER_ENCRYPTION_ENABLED; + /*setup the encryption key */ + packet_header_setup_key(sss->federation->community, + &(sss->federation->header_encryption_ctx_static), + &(sss->federation->header_encryption_ctx_dynamic), + &(sss->federation->header_iv_ctx_static), + &(sss->federation->header_iv_ctx_dynamic)); + sss->federation->edges = NULL; + } + + n2n_srand(n2n_seed()); + + /* Random auth token */ + sss->auth.scheme = n2n_auth_simple_id; + memrnd(sss->auth.token, N2N_AUTH_ID_TOKEN_SIZE); + sss->auth.token_size = N2N_AUTH_ID_TOKEN_SIZE; + + /* Random MAC address */ + memrnd(sss->mac_addr, N2N_MAC_SIZE); + sss->mac_addr[0] &= ~0x01; /* Clear multicast bit */ + sss->mac_addr[0] |= 0x02; /* Set locally-assigned bit */ + + tmp_string = calloc(1, strlen(N2N_MGMT_PASSWORD) + 1); + if(tmp_string) { + strncpy((char*)tmp_string, N2N_MGMT_PASSWORD, strlen(N2N_MGMT_PASSWORD) + 1); + sss->mgmt_password_hash = pearson_hash_64((uint8_t*)tmp_string, strlen(N2N_MGMT_PASSWORD)); + free(tmp_string); + } + + return 0; /* OK */ +} + + +/** Initialise the supernode */ +void sn_init (n2n_sn_t *sss) { + + if(resolve_create_thread(&(sss->resolve_parameter), sss->federation->edges) == 0) { + traceEvent(TRACE_NORMAL, "successfully created resolver thread"); + } +} + + +/** Deinitialise the supernode structure and deallocate any memory owned by + * it. */ +void sn_term (n2n_sn_t *sss) { + + struct sn_community *community, *tmp; + struct sn_community_regular_expression *re, *tmp_re; + n2n_tcp_connection_t *conn, *tmp_conn; + node_supernode_association_t *assoc, *tmp_assoc; + + resolve_cancel_thread(sss->resolve_parameter); + + if(sss->sock >= 0) { + closesocket(sss->sock); + } + sss->sock = -1; + + HASH_ITER(hh, sss->tcp_connections, conn, tmp_conn) { + shutdown(conn->socket_fd, SHUT_RDWR); + closesocket(conn->socket_fd); + HASH_DEL(sss->tcp_connections, conn); + free(conn); + } + + if(sss->tcp_sock >= 0) { + shutdown(sss->tcp_sock, SHUT_RDWR); + closesocket(sss->tcp_sock); + } + sss->tcp_sock = -1; + + if(sss->mgmt_sock >= 0) { + closesocket(sss->mgmt_sock); + } + sss->mgmt_sock = -1; + + HASH_ITER(hh, sss->communities, community, tmp) { + clear_peer_list(&community->edges); + if(NULL != community->header_encryption_ctx_static) { + free(community->header_encryption_ctx_static); + free(community->header_encryption_ctx_dynamic); + } + // remove all associations + HASH_ITER(hh, community->assoc, assoc, tmp_assoc) { + HASH_DEL(community->assoc, assoc); + free(assoc); + } + HASH_DEL(sss->communities, community); + free(community); + } + + HASH_ITER(hh, sss->rules, re, tmp_re) { + HASH_DEL(sss->rules, re); + if (NULL != re->rule) { + free(re->rule); + } + free(re); + } + + if(sss->community_file) + free(sss->community_file); +#ifdef WIN32 + destroyWin32(); +#endif +} + +void update_node_supernode_association (struct sn_community *comm, + n2n_mac_t *edgeMac, const struct sockaddr_in *sender_sock, + time_t now) { + + node_supernode_association_t *assoc; + + HASH_FIND(hh, comm->assoc, edgeMac, sizeof(n2n_mac_t), assoc); + if(!assoc) { + // create a new association + assoc = (node_supernode_association_t*)malloc(sizeof(node_supernode_association_t)); + if(assoc) { + memcpy(&(assoc->mac), edgeMac, sizeof(n2n_mac_t)); + memcpy((struct sockaddr_in*)&(assoc->sock), sender_sock, sizeof(struct sockaddr_in)); + assoc->last_seen = now; + HASH_ADD(hh, comm->assoc, mac, sizeof(n2n_mac_t), assoc); + } else { + // already there, update socket and time only + memcpy((struct sockaddr_in*)&(assoc->sock), sender_sock, sizeof(struct sockaddr_in)); + assoc->last_seen = now; + } + } +} + + +/** Determine the appropriate lifetime for new registrations. + * + * If the supernode has been put into a pre-shutdown phase then this lifetime + * should not allow registrations to continue beyond the shutdown point. + */ +static uint16_t reg_lifetime (n2n_sn_t *sss) { + + /* NOTE: UDP firewalls usually have a 30 seconds timeout */ + return 15; +} + + +/** Verifies authentication tokens from known edges. + * + * It is called by update_edge and during UNREGISTER_SUPER handling + * to verify the stored auth token. + */ +static int auth_edge (const n2n_auth_t *present, const n2n_auth_t *presented, n2n_auth_t *answer, struct sn_community *community) { + + sn_user_t *user = NULL; + + if(present->scheme == n2n_auth_none) { + // n2n_auth_none scheme (set at supernode if cli option '-M') + // if required, zero_token answer (not for NAK) + if(answer) + memset(answer, 0, sizeof(n2n_auth_t)); + // 0 == (always) successful + return 0; + } + + if((present->scheme == n2n_auth_simple_id) && (presented->scheme == n2n_auth_simple_id)) { + // n2n_auth_simple_id scheme: if required, zero_token answer (not for NAK) + if(answer) + memset(answer, 0, sizeof(n2n_auth_t)); + + // 0 = success (tokens are equal) + return (memcmp(present, presented, sizeof(n2n_auth_t))); + } + + if((present->scheme == n2n_auth_user_password) && (presented->scheme == n2n_auth_user_password)) { + // check if submitted public key is in list of allowed users + HASH_FIND(hh, community->allowed_users, &presented->token, sizeof(n2n_private_public_key_t), user); + if(user) { + if(answer) { + memcpy(answer, presented, sizeof(n2n_auth_t)); + + // return a double-encrypted challenge (just encrypt again) in the (first half of) public key field so edge can verify + memcpy(answer->token, answer->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE); + speck_128_encrypt(answer->token, (speck_context_t*)user->shared_secret_ctx); + + // decrypt the challenge using user's shared secret + speck_128_decrypt(answer->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)user->shared_secret_ctx); + // xor-in the community dynamic key + memxor(answer->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, community->dynamic_key, N2N_AUTH_CHALLENGE_SIZE); + // xor-in the user's shared secret + memxor(answer->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, user->shared_secret, N2N_AUTH_CHALLENGE_SIZE); + // encrypt it using user's shared secret + speck_128_encrypt(answer->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)user->shared_secret_ctx); + // user in list? success! (we will see if edge can handle the key for further com) + } + return 0; + } + } + + // if not successful earlier: failure + return -1; +} + + +// provides the current / a new local auth token +// REVISIT: behavior should depend on some local auth scheme setting (to be implemented) +static int get_local_auth (n2n_sn_t *sss, n2n_auth_t *auth) { + + // n2n_auth_simple_id scheme + memcpy(auth, &(sss->auth), sizeof(n2n_auth_t)); + + return 0; +} + + +// handles an incoming (remote) auth token from a so far unknown edge, +// takes action as required by auth scheme, and +// could provide an answer auth token for use in REGISTER_SUPER_ACK +static int handle_remote_auth (n2n_sn_t *sss, const n2n_auth_t *remote_auth, + n2n_auth_t *answer_auth, + struct sn_community *community) { + + sn_user_t *user = NULL; + + if((NULL == community->allowed_users) != (remote_auth->scheme != n2n_auth_user_password)) { + // received token's scheme does not match expected scheme + return -1; + } + + switch(remote_auth->scheme) { + // we do not handle n2n_auth_none because the edge always edge always uses either id or user/password + // auth_none is sn-internal only (skipping MAC/IP address spoofing protection) + case n2n_auth_none: + case n2n_auth_simple_id: + // zero_token answer + memset(answer_auth, 0, sizeof(n2n_auth_t)); + return 0; + case n2n_auth_user_password: + // check if submitted public key is in list of allowed users + HASH_FIND(hh, community->allowed_users, &remote_auth->token, sizeof(n2n_private_public_key_t), user); + if(user) { + memcpy(answer_auth, remote_auth, sizeof(n2n_auth_t)); + + // return a double-encrypted challenge (just encrypt again) in the (first half of) public key field so edge can verify + memcpy(answer_auth->token, answer_auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, N2N_AUTH_CHALLENGE_SIZE); + speck_128_encrypt(answer_auth->token, (speck_context_t*)user->shared_secret_ctx); + + // wrap dynamic key for transmission + // decrypt the challenge using user's shared secret + speck_128_decrypt(answer_auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)user->shared_secret_ctx); + // xor-in the community dynamic key + memxor(answer_auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, community->dynamic_key, N2N_AUTH_CHALLENGE_SIZE); + // xor-in the user's shared secret + memxor(answer_auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, user->shared_secret, N2N_AUTH_CHALLENGE_SIZE); + // encrypt it using user's shared secret + speck_128_encrypt(answer_auth->token + N2N_PRIVATE_PUBLIC_KEY_SIZE, (speck_context_t*)user->shared_secret_ctx); + return 0; + } + break; + default: + break; + } + + // if not successful earlier: failure + return -1; +} + + +/** Update the edge table with the details of the edge which contacted the + * supernode. */ +static int update_edge (n2n_sn_t *sss, + const n2n_common_t* cmn, + const n2n_REGISTER_SUPER_t* reg, + struct sn_community *comm, + const n2n_sock_t *sender_sock, + const SOCKET socket_fd, + n2n_auth_t *answer_auth, + int skip_add, + time_t now) { + + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + struct peer_info *scan, *iter, *tmp; + int ret; + + traceEvent(TRACE_DEBUG, "update_edge for %s [%s]", + macaddr_str(mac_buf, reg->edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + + HASH_FIND_PEER(comm->edges, reg->edgeMac, scan); + + // if unknown, make sure it is also not known by IP address + if(NULL == scan) { + HASH_ITER(hh,comm->edges,iter,tmp) { + if(iter->dev_addr.net_addr == reg->dev_addr.net_addr) { + scan = iter; + HASH_DEL(comm->edges, scan); + memcpy(scan->mac_addr, reg->edgeMac, sizeof(n2n_mac_t)); + HASH_ADD_PEER(comm->edges, scan); + break; + } + } + } + + if(NULL == scan) { + /* Not known */ + if(handle_remote_auth(sss, &(reg->auth), answer_auth, comm) == 0) { + if(skip_add == SN_ADD) { + scan = (struct peer_info *) calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_nodes */ + memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t)); + scan->dev_addr.net_addr = reg->dev_addr.net_addr; + scan->dev_addr.net_bitlen = reg->dev_addr.net_bitlen; + memcpy((char*)scan->dev_desc, reg->dev_desc, N2N_DESC_SIZE); + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + scan->socket_fd = socket_fd; + scan->last_cookie = reg->cookie; + scan->last_valid_time_stamp = initial_time_stamp(); + // eventually, store edge's preferred local socket from REGISTER_SUPER + if(cmn->flags & N2N_FLAGS_SOCKET) + memcpy(&scan->preferred_sock, ®->sock, sizeof(n2n_sock_t)); + else + scan->preferred_sock.family = AF_INVALID; + + // store the submitted auth token + memcpy(&(scan->auth), &(reg->auth), sizeof(n2n_auth_t)); + // manually set to type 'auth_none' if cli option disables MAC/IP address spoofing protection + // for id based auth communities. This will be obsolete when handling public keys only (v4.0?) + if((reg->auth.scheme == n2n_auth_simple_id) && (sss->override_spoofing_protection)) + scan->auth.scheme = n2n_auth_none; + + HASH_ADD_PEER(comm->edges, scan); + + traceEvent(TRACE_INFO, "created edge %s ==> %s", + macaddr_str(mac_buf, reg->edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + } + ret = update_edge_new_sn; + } else { + traceEvent(TRACE_INFO, "authentication failed"); + ret = update_edge_auth_fail; + } + } else { + /* Known */ + if(auth_edge(&(scan->auth), &(reg->auth), answer_auth, comm) == 0) { + if(!sock_equal(sender_sock, &(scan->sock))) { + memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); + scan->socket_fd = socket_fd; + scan->last_cookie = reg->cookie; + // eventually, update edge's preferred local socket from REGISTER_SUPER + if(cmn->flags & N2N_FLAGS_SOCKET) + memcpy(&scan->preferred_sock, ®->sock, sizeof(n2n_sock_t)); + else + scan->preferred_sock.family = AF_INVALID; + + traceEvent(TRACE_INFO, "updated edge %s ==> %s", + macaddr_str(mac_buf, reg->edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + ret = update_edge_sock_change; + } else { + scan->last_cookie = reg->cookie; + + traceEvent(TRACE_DEBUG, "edge unchanged %s ==> %s", + macaddr_str(mac_buf, reg->edgeMac), + sock_to_cstr(sockbuf, sender_sock)); + + ret = update_edge_no_change; + } + } else { + traceEvent(TRACE_INFO, "authentication failed"); + ret = update_edge_auth_fail; + } + } + + if((scan != NULL) && (ret != update_edge_auth_fail)) { + scan->last_seen = now; + } + + return ret; +} + + +/** checks if a certain ip address is still available, i.e. not used by any other edge of a given community */ +static int ip_addr_available (struct sn_community *comm, n2n_ip_subnet_t *ip_addr) { + + int success = 1; + struct peer_info *peer, *tmp_peer; + + // prerequisite: list of peers is sorted according to peer's tap ip address + HASH_ITER(hh, comm->edges, peer, tmp_peer) { + if(peer->dev_addr.net_addr > ip_addr->net_addr) { + break; + } + if(peer->dev_addr.net_addr == ip_addr->net_addr) { + success = 0; + break; + } + } + + return success; +} + + +static signed int peer_tap_ip_sort (struct peer_info *a, struct peer_info *b) { + + uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen)); + uint32_t b_host_id = b->dev_addr.net_addr & (~bitlen2mask(b->dev_addr.net_bitlen)); + + return ((signed int)a_host_id - (signed int)b_host_id); +} + + +/** The IP address assigned to the edge by the auto ip address function of sn. */ +static int assign_one_ip_addr (struct sn_community *comm, n2n_desc_t dev_desc, n2n_ip_subnet_t *ip_addr) { + + uint32_t tmp, success, net_id, mask, max_host, host_id = 1; + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + mask = bitlen2mask(comm->auto_ip_net.net_bitlen); + net_id = comm->auto_ip_net.net_addr & mask; + max_host = ~mask; + + // sorting is a prerequisite for more efficient availabilitiy check + HASH_SORT(comm->edges, peer_tap_ip_sort); + + // first proposal derived from hash of mac address + tmp = pearson_hash_32(dev_desc, sizeof(n2n_desc_t)) & max_host; + if(tmp == 0) tmp++; /* avoid 0 host */ + if(tmp == max_host) tmp--; /* avoid broadcast address */ + tmp |= net_id; + + // candidate + ip_addr->net_bitlen = comm->auto_ip_net.net_bitlen; + + // check for availability starting from proposal, then downwards, ... + for(host_id = tmp; host_id > net_id; host_id--) { + ip_addr->net_addr = host_id; + success = ip_addr_available(comm, ip_addr); + if(success) { + break; + } + } + // ... then upwards + if(!success) { + for(host_id = tmp + 1; host_id < (net_id + max_host); host_id++) { + ip_addr->net_addr = host_id; + success = ip_addr_available(comm, ip_addr); + if(success) { + break; + } + } + } + + if(success) { + traceEvent(TRACE_INFO, "assign IP %s to tap adapter of edge", ip_subnet_to_str(ip_bit_str, ip_addr)); + return 0; + } else { + traceEvent(TRACE_WARNING, "no assignable IP to edge tap adapter"); + return -1; + } +} + + +/** checks if a certain sub-network is still available, i.e. does not cut any other community's sub-network */ +int subnet_available (n2n_sn_t *sss, + struct sn_community *comm, + uint32_t net_id, + uint32_t mask) { + + struct sn_community *cmn, *tmpCmn; + int success = 1; + + HASH_ITER(hh, sss->communities, cmn, tmpCmn) { + if(cmn == comm) { + continue; + } + if(cmn->is_federation == IS_FEDERATION) { + continue; + } + if((net_id <= (cmn->auto_ip_net.net_addr + ~bitlen2mask(cmn->auto_ip_net.net_bitlen))) + &&(net_id + ~mask >= cmn->auto_ip_net.net_addr)) { + success = 0; + break; + } + } + + return success; +} + + +/** The IP address range (subnet) assigned to the community by the auto ip address function of sn. */ +int assign_one_ip_subnet (n2n_sn_t *sss, + struct sn_community *comm) { + + uint32_t net_id, net_id_i, mask, net_increment; + uint32_t no_subnets; + uint8_t success; + in_addr_t net; + + mask = bitlen2mask(sss->min_auto_ip_net.net_bitlen); + // number of possible sub-networks + no_subnets = (sss->max_auto_ip_net.net_addr - sss->min_auto_ip_net.net_addr); + no_subnets >>= (32 - sss->min_auto_ip_net.net_bitlen); + no_subnets += 1; + + // proposal for sub-network to choose + net_id = pearson_hash_32((const uint8_t *)comm->community, N2N_COMMUNITY_SIZE) % no_subnets; + net_id = sss->min_auto_ip_net.net_addr + (net_id << (32 - sss->min_auto_ip_net.net_bitlen)); + + // check for availability starting from net_id, then downwards, ... + net_increment = (~mask+1); + for(net_id_i = net_id; net_id_i >= sss->min_auto_ip_net.net_addr; net_id_i -= net_increment) { + success = subnet_available(sss, comm, net_id_i, mask); + if(success) { + break; + } + } + // ... then upwards + if(!success) { + for(net_id_i = net_id + net_increment; net_id_i <= sss->max_auto_ip_net.net_addr; net_id_i += net_increment) { + success = subnet_available(sss, comm, net_id_i, mask); + if(success) { + break; + } + } + } + + if(success) { + comm->auto_ip_net.net_addr = net_id_i; + comm->auto_ip_net.net_bitlen = sss->min_auto_ip_net.net_bitlen; + net = htonl(comm->auto_ip_net.net_addr); + traceEvent(TRACE_INFO, "assigned sub-network %s/%u to community '%s'", + inet_ntoa(*(struct in_addr *) &net), + comm->auto_ip_net.net_bitlen, + comm->community); + return 0; + } else { + comm->auto_ip_net.net_addr = 0; + comm->auto_ip_net.net_bitlen = 0; + traceEvent(TRACE_WARNING, "no assignable sub-network left for community '%s'", + comm->community); + return -1; + } +} + + +/*** + * + * For a given packet, find the apporopriate internal last valid time stamp for lookup + * and verify it (and also update, if applicable). + */ +static int find_edge_time_stamp_and_verify (struct peer_info * edges, + peer_info_t *sn, n2n_mac_t mac, + uint64_t stamp, int allow_jitter) { + + uint64_t *previous_stamp = NULL; + + if(sn) { + previous_stamp = &(sn->last_valid_time_stamp); + } else { + struct peer_info *edge; + HASH_FIND_PEER(edges, mac, edge); + + if(edge) { + // time_stamp_verify_and_update allows the pointer a previous stamp to be NULL + // if it is a (so far) unknown edge + previous_stamp = &(edge->last_valid_time_stamp); + } + } + + // failure --> 0; success --> 1 + return time_stamp_verify_and_update(stamp, previous_stamp, allow_jitter); +} + + +static int re_register_and_purge_supernodes (n2n_sn_t *sss, struct sn_community *comm, time_t *p_last_re_reg_and_purge, time_t now, uint8_t forced) { + + time_t time; + struct peer_info *peer, *tmp; + + if(!forced) { + if((now - (*p_last_re_reg_and_purge)) < RE_REG_AND_PURGE_FREQUENCY) { + return 0; + } + + // purge long-time-not-seen supernodes + purge_expired_nodes(&(comm->edges), sss->sock, &sss->tcp_connections, p_last_re_reg_and_purge, + RE_REG_AND_PURGE_FREQUENCY, LAST_SEEN_SN_INACTIVE); + } + + if(comm != NULL) { + HASH_ITER(hh,comm->edges,peer,tmp) { + + time = now - peer->last_seen; + + if(!forced) { + if(time <= LAST_SEEN_SN_ACTIVE) { + continue; + } + } + + /* re-register (send REGISTER_SUPER) */ + uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0}; + size_t idx; + /* ssize_t sent; */ + n2n_common_t cmn; + n2n_REGISTER_SUPER_t reg; + n2n_sock_str_t sockbuf; + + memset(&cmn, 0, sizeof(cmn)); + memset(®, 0, sizeof(reg)); + + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_register_super; + cmn.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn.community, comm->community, N2N_COMMUNITY_SIZE); + + reg.cookie = n2n_rand(); + peer->last_cookie = reg.cookie; + + reg.dev_addr.net_addr = ntohl(peer->dev_addr.net_addr); + reg.dev_addr.net_bitlen = mask2bitlen(ntohl(peer->dev_addr.net_bitlen)); + get_local_auth(sss, &(reg.auth)); + + reg.key_time = sss->dynamic_key_time; + + idx = 0; + encode_mac(reg.edgeMac, &idx, sss->mac_addr); + + idx = 0; + encode_REGISTER_SUPER(pktbuf, &idx, &cmn, ®); + + traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s", + sock_to_cstr(sockbuf, &(peer->sock))); + + packet_header_encrypt(pktbuf, idx, idx, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, + time_stamp()); + + /* sent = */ sendto_peer(sss, peer, pktbuf, idx); + } + } + + return 0; /* OK */ +} + + +static int purge_expired_communities (n2n_sn_t *sss, + time_t* p_last_purge, + time_t now) { + + struct sn_community *comm, *tmp_comm; + node_supernode_association_t *assoc, *tmp_assoc; + size_t num_reg = 0; + size_t num_assoc = 0; + + if((now - (*p_last_purge)) < PURGE_REGISTRATION_FREQUENCY) { + return 0; + } + + traceEvent(TRACE_DEBUG, "purging old communities and edges"); + + HASH_ITER(hh, sss->communities, comm, tmp_comm) { + // federation is taken care of in re_register_and_purge_supernodes() + if(comm->is_federation == IS_FEDERATION) + continue; + + // purge the community's local peers + num_reg += purge_peer_list(&comm->edges, sss->sock, &sss->tcp_connections, now - REGISTRATION_TIMEOUT); + + // purge the community's associated peers (connected to other supernodes) + HASH_ITER(hh, comm->assoc, assoc, tmp_assoc) { + if(comm->assoc->last_seen < (now - 3 * REGISTRATION_TIMEOUT)) { + HASH_DEL(comm->assoc, assoc); + free(assoc); + num_assoc++; + } + } + + if((comm->edges == NULL) && (comm->purgeable == COMMUNITY_PURGEABLE)) { + traceEvent(TRACE_INFO, "purging idle community %s", comm->community); + if(NULL != comm->header_encryption_ctx_static) { + /* this should not happen as 'purgeable' and thus only communities w/o encrypted header here */ + free(comm->header_encryption_ctx_static); + free(comm->header_iv_ctx_static); + free(comm->header_encryption_ctx_dynamic); + free(comm->header_iv_ctx_dynamic); + } + // remove all associations + HASH_ITER(hh, comm->assoc, assoc, tmp_assoc) { + HASH_DEL(comm->assoc, assoc); + free(assoc); + } + HASH_DEL(sss->communities, comm); + free(comm); + } + } + (*p_last_purge) = now; + + traceEvent(TRACE_DEBUG, "purge_expired_communities removed %ld locally registered edges and %ld remotely associated edges", + num_reg, num_assoc); + + return 0; +} + + +static int number_enc_packets_sort (struct sn_community *a, struct sn_community *b) { + + // comparison function for sorting communities in descending order of their + // number_enc_packets-fields + return (b->number_enc_packets - a->number_enc_packets); +} + + +static int sort_communities (n2n_sn_t *sss, + time_t* p_last_sort, + time_t now) { + + struct sn_community *comm, *tmp; + + if((now - (*p_last_sort)) < SORT_COMMUNITIES_INTERVAL) { + return 0; + } + + // this routine gets periodically called as defined in SORT_COMMUNITIES_INTERVAL + // it sorts the communities in descending order of their number_enc_packets-fields... + HASH_SORT(sss->communities, number_enc_packets_sort); + + // ... and afterward resets the number_enc__packets-fields to zero + // (other models could reset it to half of their value to respect history) + HASH_ITER(hh, sss->communities, comm, tmp) { + comm->number_enc_packets = 0; + } + + (*p_last_sort) = now; + + return 0; +} + + +static int process_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + char *mgmt_buf, + size_t mgmt_size, + time_t now) { + + char resbuf[N2N_SN_PKTBUF_SIZE]; + size_t ressize = 0; + uint32_t num_edges = 0; + uint32_t num_comm = 0; + uint32_t num = 0; + struct sn_community *community, *tmp; + struct peer_info *peer, *tmpPeer; + macstr_t mac_buf; + n2n_sock_str_t sockbuf; + char time_buf[10]; /* 9 digits + 1 terminating zero */ + dec_ip_bit_str_t ip_bit_str = {'\0'}; + + traceEvent(TRACE_DEBUG, "process_mgmt"); + + /* avoid parsing any uninitialized junk from the stack */ + mgmt_buf[mgmt_size] = 0; + + // process input, if any + if((0 == memcmp(mgmt_buf, "help", 4)) || (0 == memcmp(mgmt_buf, "?", 1))) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "Help for supernode management console:\n" + "\thelp | This help message\n" + "\treload_communities | Reloads communities and user's public keys\n" + "\t | Display status and statistics\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + + if(0 == memcmp(mgmt_buf, "reload_communities", 18)) { + if(!sss->community_file) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "No community file provided (-c command line option)\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + traceEvent(TRACE_NORMAL, "'reload_communities' command"); + + if(load_allowed_sn_community(sss)) { + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "Error while re-loading community file (not found or no valid content)\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "OK.\n"); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + return 0; /* no status output afterwards */ + } + + if((mgmt_buf[0] == 'r' || mgmt_buf[0] == 'w') && (mgmt_buf[1] == ' ')) { + /* this is a JSON request */ + handleMgmtJson_sn(sss, mgmt_buf, *sender_sock); + return 0; + } + + // output current status + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + " ### | TAP | MAC | EDGE | HINT | LAST SEEN\n"); + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "========================================================================================================\n"); + HASH_ITER(hh, sss->communities, community, tmp) { + if(num_comm) + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "--------------------------------------------------------------------------------------------------------\n"); + num_comm++; + num_edges += HASH_COUNT(community->edges); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "%s '%s'\n", + (community->is_federation) ? "FEDERATION" : + ((community->purgeable == COMMUNITY_UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"), + (community->is_federation) ? "-/-" : community->community); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + ressize = 0; + + num = 0; + HASH_ITER(hh, community->edges, peer, tmpPeer) { + sprintf (time_buf, "%9u", (unsigned int)(now - peer->last_seen)); + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "%4u | %-19s | %-17s | %-21s %-3s | %-15s | %9s\n", + ++num, + (peer->dev_addr.net_addr == 0) ? ((peer->purgeable == SN_UNPURGEABLE) ? "-l" : "") : + ip_subnet_to_str(ip_bit_str, &peer->dev_addr), + (is_null_mac(peer->mac_addr)) ? "" : macaddr_str(mac_buf, peer->mac_addr), + sock_to_cstr(sockbuf, &(peer->sock)), + ((peer->socket_fd >= 0) && (peer->socket_fd != sss->sock)) ? "TCP" : "", + peer->dev_desc, + (peer->last_seen) ? time_buf : ""); + + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + ressize = 0; + } + } + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "========================================================================================================\n"); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "uptime %lu | ", (now - sss->start_time)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "edges %u | ", + num_edges); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_sup %u | ", + (unsigned int) sss->stats.reg_super); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "reg_nak %u | ", + (unsigned int) sss->stats.reg_super_nak); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "errors %u \n", + (unsigned int) sss->stats.errors); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "fwd %u | ", + (unsigned int) sss->stats.fwd); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "broadcast %u | ", + (unsigned int) sss->stats.broadcast); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "cur_cmnts %u\n", HASH_COUNT(sss->communities)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last_fwd %lu sec ago | ", + (long unsigned int) (now - sss->stats.last_fwd)); + + ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, + "last reg %lu sec ago\n\n", + (long unsigned int) (now - sss->stats.last_reg_super)); + + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); + + return 0; +} + + +static int sendto_mgmt (n2n_sn_t *sss, + const struct sockaddr_in *sender_sock, + const uint8_t *mgmt_buf, + size_t mgmt_size) { + + ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/, + (struct sockaddr *)sender_sock, sizeof (struct sockaddr_in)); + + if(r <= 0) { + ++(sss->stats.errors); + traceEvent (TRACE_ERROR, "sendto_mgmt : sendto failed. %s", strerror (errno)); + return -1; + } + + return 0; +} + +/** Examine a datagram and determine what to do with it. + * + */ +static int process_udp (n2n_sn_t * sss, + const struct sockaddr_in *sender_sock, + const SOCKET socket_fd, + uint8_t * udp_buf, + size_t udp_size, + time_t now) { + + n2n_common_t cmn; /* common fields in the packet header */ + size_t rem; + size_t idx; + size_t msg_type; + uint8_t from_supernode; + peer_info_t *sn = NULL; + n2n_sock_t sender; + macstr_t mac_buf; + macstr_t mac_buf2; + n2n_sock_str_t sockbuf; + char buf[32]; + uint8_t hash_buf[16] = {0}; /* always size of 16 (max) despite the actual value of N2N_REG_SUP_HASH_CHECK_LEN (<= 16) */ + + struct sn_community *comm, *tmp; + uint32_t header_enc = 0; /* 1 == encrypted by static key, 2 == encrypted by dynamic key */ + uint64_t stamp; + int skip_add; + time_t any_time = 0; + + traceEvent(TRACE_DEBUG, "processing incoming UDP packet [len: %lu][sender: %s:%u]", + udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)), + ntohs(sender_sock->sin_port)); + + /* check if header is unencrypted. the following check is around 99.99962 percent reliable. + * it heavily relies on the structure of packet's common part + * changes to wire.c:encode/decode_common need to go together with this code */ + if(udp_size < 24) { + traceEvent(TRACE_DEBUG, "dropped a packet too short to be valid"); + return -1; + } + if((udp_buf[23] == (uint8_t)0x00) // null terminated community name + && (udp_buf[00] == N2N_PKT_VERSION) // correct packet version + && ((be16toh(*(uint16_t*)&(udp_buf[02])) & N2N_FLAGS_TYPE_MASK) <= MSG_TYPE_MAX_TYPE) // message type + && ( be16toh(*(uint16_t*)&(udp_buf[02])) < N2N_FLAGS_OPTIONS) // flags + ) { + /* most probably unencrypted */ + /* make sure, no downgrading happens here and no unencrypted packets can be + * injected in a community which definitely deals with encrypted headers */ + HASH_FIND_COMMUNITY(sss->communities, (char *)&udp_buf[04], comm); + if(comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + traceEvent(TRACE_DEBUG, "dropped a packet with unencrypted header " + "addressed to community '%s' which uses encrypted headers", + comm->community); + return -1; + } + if(comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { + traceEvent(TRACE_INFO, "locked community '%s' to " + "unencrypted headers", comm->community); + /* set 'no encryption' in case it is not set yet */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx_static = NULL; + comm->header_encryption_ctx_dynamic = NULL; + } + } + } else { + /* most probably encrypted */ + /* cycle through the known communities (as keys) to eventually decrypt */ + HASH_ITER(hh, sss->communities, comm, tmp) { + /* skip the definitely unencrypted communities */ + if(comm->header_encryption == HEADER_ENCRYPTION_NONE) { + continue; + } + + // match with static (1) or dynamic (2) ctx? + // check dynamic first as it is identical to static in normal header encryption mode + if(packet_header_decrypt(udp_buf, udp_size, + comm->community, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + &stamp)) { + header_enc = 2; + } + if(!header_enc) { + pearson_hash_128(hash_buf, udp_buf, max(0, (int)udp_size - (int)N2N_REG_SUP_HASH_CHECK_LEN)); + header_enc = packet_header_decrypt(udp_buf, max(0, (int)udp_size - (int)N2N_REG_SUP_HASH_CHECK_LEN), comm->community, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, &stamp); + } + + if(header_enc) { + // time stamp verification follows in the packet specific section as it requires to determine the + // sender from the hash list by its MAC, this all depends on packet type and packet structure + // (MAC is not always in the same place) + + if(comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { + traceEvent(TRACE_INFO, "locked community '%s' to " + "encrypted headers", comm->community); + /* set 'encrypted' in case it is not set yet */ + comm->header_encryption = HEADER_ENCRYPTION_ENABLED; + } + // count the number of encrypted packets for sorting the communities from time to time + // for the HASH_ITER a few lines above gets faster for the more busy communities + (comm->number_enc_packets)++; + // no need to test further communities + break; + } + } + if(!header_enc) { + // no matching key/community + traceEvent(TRACE_DEBUG, "dropped a packet with seemingly encrypted header " + "for which no matching community which uses encrypted headers was found"); + return -1; + } + } + + /* Use decode_common() to determine the kind of packet then process it: + * + * REGISTER_SUPER adds an edge and generate a return REGISTER_SUPER_ACK + * + * REGISTER, REGISTER_ACK and PACKET messages are forwarded to their + * destination edge. If the destination is not known then PACKETs are + * broadcast. + */ + + rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ + idx = 0; /* marches through packet header as parts are decoded. */ + + if(decode_common(&cmn, udp_buf, &rem, &idx) < 0) { + traceEvent(TRACE_ERROR, "failed to decode common section"); + return -1; /* failed to decode packet */ + } + + msg_type = cmn.pc; /* packet code */ + + // special case for user/pw auth + // community's auth scheme and message type need to match the used key (dynamic) + if(comm) { + if((comm->allowed_users) + && (msg_type != MSG_TYPE_REGISTER_SUPER) + && (msg_type != MSG_TYPE_REGISTER_SUPER_ACK) + && (msg_type != MSG_TYPE_REGISTER_SUPER_NAK)) { + if(header_enc != 2) { + traceEvent(TRACE_WARNING, "dropped packet encrypted with static key where expecting dynamic key"); + return -1; + } + } + } + + /* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which + * IP transport version the packet arrived on. May need to UDP sockets. */ + memset(&sender, 0, sizeof(n2n_sock_t)); + sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */ + sender.port = ntohs(sender_sock->sin_port); + memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + from_supernode = cmn.flags & N2N_FLAGS_FROM_SUPERNODE; + if(from_supernode) { + skip_add = SN_ADD_SKIP; + sn = add_sn_to_list_by_mac_or_sock (&(sss->federation->edges), &sender, null_mac, &skip_add); + // only REGISTER_SUPER allowed from unknown supernodes + if((!sn) && (msg_type != MSG_TYPE_REGISTER_SUPER)) { + traceEvent(TRACE_DEBUG, "dropped incoming data from unknown supernode"); + return -1; + } + } + + if(cmn.ttl < 1) { + traceEvent(TRACE_WARNING, "expired TTL"); + return 0; /* Don't process further */ + } + + --(cmn.ttl); /* The value copied into all forwarded packets. */ + + switch(msg_type) { + case MSG_TYPE_PACKET: { + /* PACKET from one edge to another edge via supernode. */ + + /* pkt will be modified in place and recoded to an output of potentially + * different size due to addition of the socket.*/ + n2n_PACKET_t pkt; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "PACKET with unknown community %s", cmn.community); + return -1; + } + + sss->stats.last_fwd = now; + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); + + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, pkt.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped PACKET due to time stamp error"); + return -1; + } + } + + unicast = (0 == is_multi_broadcast(pkt.dstMac)); + + traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s", + (unicast ? "unicast" : "multicast"), + macaddr_str(mac_buf, pkt.srcMac), + macaddr_str(mac_buf2, pkt.dstMac), + (from_supernode ? "from sn" : "local")); + + if(!from_supernode) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + + pkt.sock.family = AF_INET; + pkt.sock.port = ntohs(sender_sock->sin_port); + memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + rec_buf = encbuf; + /* Re-encode the header. */ + encode_PACKET(encbuf, &encx, &cmn2, &pkt); + + uint16_t oldEncx = encx; + + /* Copy the original payload unchanged */ + encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx)); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + // in case of user-password auth, also encrypt the iv of payload assuming ChaCha20 and SPECK having the same iv size + packet_header_encrypt(rec_buf, oldEncx + (NULL != comm->allowed_users) * min(encx - oldEncx, N2N_SPECK_IVEC_SIZE), encx, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + time_stamp()); + } + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + traceEvent(TRACE_DEBUG, "Rx PACKET fwd unmodified"); + + rec_buf = udp_buf; + encx = udp_size; + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + // in case of user-password auth, also encrypt the iv of payload assuming ChaCha20 and SPECK having the same iv size + packet_header_encrypt(rec_buf, idx + (NULL != comm->allowed_users) * min(encx - idx, N2N_SPECK_IVEC_SIZE), encx, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + time_stamp()); + } + } + + /* Common section to forward the final product. */ + if(unicast) { + try_forward(sss, comm, &cmn, pkt.dstMac, from_supernode, rec_buf, encx); + } else { + try_broadcast(sss, comm, &cmn, pkt.srcMac, from_supernode, rec_buf, encx); + } + break; + } + + case MSG_TYPE_REGISTER: { + /* Forwarding a REGISTER from one edge to the next */ + + n2n_REGISTER_t reg; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "REGISTER from unknown community %s", cmn.community); + return -1; + } + + sss->stats.last_fwd = now; + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, reg.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER due to time stamp error"); + return -1; + } + } + + unicast = (0 == is_multi_broadcast(reg.dstMac)); + + if(unicast) { + traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", + macaddr_str(mac_buf, reg.srcMac), + macaddr_str(mac_buf2, reg.dstMac), + ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE) ? "from sn" : "local")); + + if(0 == (cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + + reg.sock.family = AF_INET; + reg.sock.port = ntohs(sender_sock->sin_port); + memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + /* Re-encode the header. */ + encode_REGISTER(encbuf, &encx, &cmn2, ®); + + rec_buf = encbuf; + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ + + rec_buf = udp_buf; + encx = udp_size; + } + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(rec_buf, encx, encx, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + time_stamp()); + } + try_forward(sss, comm, &cmn, reg.dstMac, from_supernode, rec_buf, encx); /* unicast only */ + } else { + traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); + } + break; + } + + case MSG_TYPE_REGISTER_ACK: { + traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (not implemented) should not be via supernode"); + break; + } + + case MSG_TYPE_REGISTER_SUPER: { + n2n_REGISTER_SUPER_t reg; + n2n_REGISTER_SUPER_ACK_t ack; + n2n_REGISTER_SUPER_NAK_t nak; + n2n_common_t cmn2; + uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; + uint8_t payload_buf[REG_SUPER_ACK_PAYLOAD_SPACE]; + n2n_REGISTER_SUPER_ACK_payload_t *payload; + size_t encx = 0; + struct sn_community_regular_expression *re, *tmp_re; + struct peer_info *peer, *tmp_peer, *p; + int8_t allowed_match = -1; + uint8_t match = 0; + int match_length = 0; + n2n_ip_subnet_t ipaddr; + int num = 0; + int skip; + int ret_value; + sn_user_t *user = NULL; + + memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); + memset(&nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t)); + + /* Edge/supernode requesting registration with us. */ + sss->stats.last_reg_super=now; + ++(sss->stats.reg_super); + decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx); + + if(comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, reg.edgeMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER due to time stamp error"); + return -1; + } + } + } + + /* + Before we move any further, we need to check if the requested + community is allowed by the supernode. In case it is not we do + not report any message back to the edge to hide the supernode + existance (better from the security standpoint) + */ + + if(!comm && sss->lock_communities) { + HASH_ITER(hh, sss->rules, re, tmp_re) { + allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length); + + if((allowed_match != -1) + && (match_length == strlen((const char *)cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted) + && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted) + match = 1; + break; + } + } + if(match != 1) { + traceEvent(TRACE_INFO, "discarded registration with unallowed community '%s'", + (char*)cmn.community); + return -1; + } + } + + if(!comm && (!sss->lock_communities || (match == 1))) { + comm = (struct sn_community*)calloc(1, sizeof(struct sn_community)); + + if(comm) { + comm_init(comm, (char *)cmn.community); + /* new communities introduced by REGISTERs could not have had encrypted header... */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx_static = NULL; + comm->header_encryption_ctx_dynamic = NULL; + /* ... and also are purgeable during periodic purge */ + comm->purgeable = COMMUNITY_PURGEABLE; + comm->number_enc_packets = 0; + HASH_ADD_STR(sss->communities, community, comm); + + traceEvent(TRACE_INFO, "new community: %s", comm->community); + assign_one_ip_subnet(sss, comm); + } + } + + if(!comm) { + traceEvent(TRACE_INFO, "discarded registration with unallowed community '%s'", + (char*)cmn.community); + return -1; + } + + // hash check (user/pw auth only) + if(comm->allowed_users) { + // check if submitted public key is in list of allowed users + HASH_FIND(hh, comm->allowed_users, ®.auth.token, sizeof(n2n_private_public_key_t), user); + if(user) { + speck_128_encrypt(hash_buf, (speck_context_t*)user->shared_secret_ctx); + if(memcmp(hash_buf, udp_buf + udp_size - N2N_REG_SUP_HASH_CHECK_LEN /* length has already been checked */, N2N_REG_SUP_HASH_CHECK_LEN)) { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER with wrong hash"); + return -1; + } + } else { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER from unknown user"); + // continue and let auth check do the rest (otherwise, no NAK is sent) + } + } + + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_register_super_ack; + cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); + + ack.cookie = reg.cookie; + memcpy(ack.srcMac, sss->mac_addr, sizeof(n2n_mac_t)); + + if(comm->is_federation != IS_FEDERATION) { /* alternatively, do not send zero tap ip address in federation REGISTER_SUPER */ + if((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) || + ((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) { + memset(&ipaddr, 0, sizeof(n2n_ip_subnet_t)); + assign_one_ip_addr(comm, reg.dev_desc, &ipaddr); + ack.dev_addr.net_addr = ipaddr.net_addr; + ack.dev_addr.net_bitlen = ipaddr.net_bitlen; + } + } + + ack.lifetime = reg_lifetime(sss); + + ack.sock.family = AF_INET; + ack.sock.port = ntohs(sender_sock->sin_port); + memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + /* Add sender's data to federation (or update it) */ + if(comm->is_federation == IS_FEDERATION) { + skip_add = SN_ADD; + p = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(ack.sock), reg.edgeMac, &skip_add); + p->last_seen = now; + // communication with other supernodes happens via standard udp port + p->socket_fd = sss->sock; + } + + /* Skip random numbers of supernodes before payload assembling, calculating an appropriate random_number. + * That way, all supernodes have a chance to be propagated with REGISTER_SUPER_ACK. */ + skip = HASH_COUNT(sss->federation->edges) - (int)(REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE / REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE); + skip = (skip < 0) ? 0 : n2n_rand_sqr(skip); + + /* Assembling supernode list for REGISTER_SUPER_ACK payload */ + payload = (n2n_REGISTER_SUPER_ACK_payload_t*)payload_buf; + HASH_ITER(hh, sss->federation->edges, peer, tmp_peer) { + if(skip) { + skip--; + continue; + } + if(peer->sock.family == (uint8_t)AF_INVALID) + continue; /* do not add unresolved supernodes to payload */ + if(memcmp(&(peer->sock), &(ack.sock), sizeof(n2n_sock_t)) == 0) continue; /* a supernode doesn't add itself to the payload */ + if((now - peer->last_seen) >= LAST_SEEN_SN_NEW) continue; /* skip long-time-not-seen supernodes. + * We need to allow for a little extra time because supernodes sometimes exceed + * their SN_ACTIVE time before they get re-registred to. */ + if(((++num)*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE) > REG_SUPER_ACK_PAYLOAD_SPACE) break; /* no more space available in REGISTER_SUPER_ACK payload */ + memcpy(&(payload->sock), &(peer->sock), sizeof(n2n_sock_t)); + memcpy(payload->mac, peer->mac_addr, sizeof(n2n_mac_t)); + // shift to next payload entry + payload++; + } + ack.num_sn = num; + + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); + + // check authentication + ret_value = update_edge_no_change; + if(comm->is_federation != IS_FEDERATION) { /* REVISIT: auth among supernodes is not implemented yet */ + if(cmn.flags & N2N_FLAGS_FROM_SUPERNODE) { + ret_value = update_edge(sss, &cmn, ®, comm, &(ack.sock), socket_fd, &(ack.auth), SN_ADD_SKIP, now); + } else { + // do not add in case of null mac (edge asking for ip address) + ret_value = update_edge(sss, &cmn, ®, comm, &(ack.sock), socket_fd, &(ack.auth), is_null_mac(reg.edgeMac) ? SN_ADD_SKIP : SN_ADD, now); + } + } + + if(ret_value == update_edge_auth_fail) { + // send REGISTER_SUPER_NAK + cmn2.pc = n2n_register_super_nak; + nak.cookie = reg.cookie; + memcpy(nak.srcMac, reg.edgeMac, sizeof(n2n_mac_t)); + + encode_REGISTER_SUPER_NAK(ackbuf, &encx, &cmn2, &nak); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(ackbuf, encx, encx, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, + time_stamp()); + // if user-password-auth + if(comm->allowed_users) { + encode_buf(ackbuf, &encx, hash_buf /* no matter what content */, N2N_REG_SUP_HASH_CHECK_LEN); + } + } + sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, ackbuf, encx); + + traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_NAK for %s", + macaddr_str(mac_buf, reg.edgeMac)); + } else { + // if this is not already from a supernode ... + // and not from federation, ... + if((!(cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) || (!(cmn.flags & N2N_FLAGS_SOCKET))) { + // ... forward to all other supernodes (note try_broadcast()'s behavior with + // NULL comm and from_supernode parameter) + // exception: do not forward auto ip draw + if(!is_null_mac(reg.edgeMac)) { + reg.sock.family = AF_INET; + reg.sock.port = ntohs(sender_sock->sin_port); + memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + cmn2.pc = n2n_register_super; + encode_REGISTER_SUPER(ackbuf, &encx, &cmn2, ®); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(ackbuf, encx, encx, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, + time_stamp()); + // if user-password-auth + if(comm->allowed_users) { + // append an encrypted packet hash + pearson_hash_128(hash_buf, ackbuf, encx); + // same 'user' as above + speck_128_encrypt(hash_buf, (speck_context_t*)user->shared_secret_ctx); + encode_buf(ackbuf, &encx, hash_buf, N2N_REG_SUP_HASH_CHECK_LEN); + } + } + + try_broadcast(sss, NULL, &cmn, reg.edgeMac, from_supernode, ackbuf, encx); + } + + // dynamic key time handling if appropriate + ack.key_time = 0; + if(comm->is_federation == IS_FEDERATION) { + if(reg.key_time > sss->dynamic_key_time) { + traceEvent(TRACE_DEBUG, "setting new key time"); + // have all edges re_register (using old dynamic key) + send_re_register_super(sss); + // set new key time + sss->dynamic_key_time = reg.key_time; + // calculate new dynamic keys for all communities + calculate_dynamic_keys(sss); + // force re-register with all supernodes + re_register_and_purge_supernodes(sss, sss->federation, &any_time, now, 1 /* forced */); + } + ack.key_time = sss->dynamic_key_time; + } + + // send REGISTER_SUPER_ACK + encx = 0; + cmn2.pc = n2n_register_super_ack; + + encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack, payload_buf); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(ackbuf, encx, encx, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, + time_stamp()); + // if user-password-auth + if(comm->allowed_users) { + // append an encrypted packet hash + pearson_hash_128(hash_buf, ackbuf, encx); + // same 'user' as above + speck_128_encrypt(hash_buf, (speck_context_t*)user->shared_secret_ctx); + encode_buf(ackbuf, &encx, hash_buf, N2N_REG_SUP_HASH_CHECK_LEN); + } + } + + sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, ackbuf, encx); + + traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); + } else { + // this is an edge with valid authentication registering with another supernode, so ... + // 1- ... associate it with that other supernode + update_node_supernode_association(comm, &(reg.edgeMac), sender_sock, now); + // 2- ... we can delete it from regular list if present (can happen) + HASH_FIND_PEER(comm->edges, reg.edgeMac, peer); + if(peer != NULL) { + if((peer->socket_fd != sss->sock) && (peer->socket_fd >= 0)) { + n2n_tcp_connection_t *conn; + HASH_FIND_INT(sss->tcp_connections, &(peer->socket_fd), conn); + close_tcp_connection(sss, conn); /* also deletes the peer */ + } else { + HASH_DEL(comm->edges, peer); + free(peer); + } + } + } + } + + break; + } + + case MSG_TYPE_UNREGISTER_SUPER: { + n2n_UNREGISTER_SUPER_t unreg; + struct peer_info *peer; + int auth; + + + memset(&unreg, 0, sizeof(n2n_UNREGISTER_SUPER_t)); + + if(!comm) { + traceEvent(TRACE_DEBUG, "dropped UNREGISTER_SUPER with unknown community %s", cmn.community); + return -1; + } + + if((from_supernode == 1) || (comm->is_federation == IS_FEDERATION)) { + traceEvent(TRACE_DEBUG, "dropped UNREGISTER_SUPER: should not come from a supernode or federation."); + return -1; + } + + decode_UNREGISTER_SUPER(&unreg, &cmn, udp_buf, &rem, &idx); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, unreg.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped UNREGISTER_SUPER due to time stamp error"); + return -1; + } + } + + traceEvent(TRACE_DEBUG, "Rx UNREGISTER_SUPER from %s", + macaddr_str(mac_buf, unreg.srcMac)); + + HASH_FIND_PEER(comm->edges, unreg.srcMac, peer); + if(peer != NULL) { + if((auth = auth_edge(&(peer->auth), &unreg.auth, NULL, comm)) == 0) { + if((peer->socket_fd != sss->sock) && (peer->socket_fd >= 0)) { + n2n_tcp_connection_t *conn; + HASH_FIND_INT(sss->tcp_connections, &(peer->socket_fd), conn); + close_tcp_connection(sss, conn); /* also deletes the peer */ + } else { + HASH_DEL(comm->edges, peer); + free(peer); + } + } + } + break; + } + + case MSG_TYPE_REGISTER_SUPER_ACK: { + n2n_REGISTER_SUPER_ACK_t ack; + struct peer_info *scan, *tmp; + n2n_sock_str_t sockbuf1; + n2n_sock_str_t sockbuf2; + macstr_t mac_buf1; + n2n_sock_t sender; + n2n_sock_t *orig_sender; + int i; + uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE]; + n2n_REGISTER_SUPER_ACK_payload_t *payload; + + memset(&sender, 0, sizeof(n2n_sock_t)); + sender.family = AF_INET; + sender.port = ntohs(sender_sock->sin_port); + memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + orig_sender = &sender; + + memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); + + if(!comm) { + traceEvent(TRACE_DEBUG, "REGISTER_SUPER_ACK with unknown community %s", cmn.community); + return -1; + } + + if((from_supernode == 0) || (comm->is_federation == IS_NO_FEDERATION)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER_ACK, should not come from an edge or regular community"); + return -1; + } + + decode_REGISTER_SUPER_ACK(&ack, &cmn, udp_buf, &rem, &idx, dec_tmpbuf); + orig_sender = &(ack.sock); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, ack.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER_ACK due to time stamp error"); + return -1; + } + } + + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK from MAC %s [%s] (external %s)", + macaddr_str(mac_buf1, ack.srcMac), + sock_to_cstr(sockbuf1, &sender), + sock_to_cstr(sockbuf2, orig_sender)); + + skip_add = SN_ADD_SKIP; + scan = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &sender, ack.srcMac, &skip_add); + if(scan != NULL) { + scan->last_seen = now; + } else { + traceEvent(TRACE_DEBUG, "dropped REGISTER_SUPER_ACK due to an unknown supernode"); + break; + } + + if(ack.cookie == scan->last_cookie) { + + payload = (n2n_REGISTER_SUPER_ACK_payload_t *)dec_tmpbuf; + for(i = 0; i < ack.num_sn; i++) { + skip_add = SN_ADD; + tmp = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), &(payload->sock), payload->mac, &skip_add); + // other supernodes communicate via standard udp socket + tmp->socket_fd = sss->sock; + + if(skip_add == SN_ADD_ADDED) { + tmp->last_seen = now - LAST_SEEN_SN_NEW; + } + + // shift to next payload entry + payload++; + } + + if(ack.key_time > sss->dynamic_key_time) { + traceEvent(TRACE_DEBUG, "setting new key time"); + // have all edges re_register (using old dynamic key) + send_re_register_super(sss); + // set new key time + sss->dynamic_key_time = ack.key_time; + // calculate new dynamic keys for all communities + calculate_dynamic_keys(sss); + // force re-register with all supernodes + re_register_and_purge_supernodes(sss, sss->federation, &any_time, now, 1 /* forced */); + } + + } else { + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with wrong or old cookie"); + } + break; + } + + case MSG_TYPE_REGISTER_SUPER_NAK: { + n2n_REGISTER_SUPER_NAK_t nak; + uint8_t nakbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + struct peer_info *peer; + n2n_sock_str_t sockbuf; + macstr_t mac_buf; + n2n_sock_t sender; + + memset(&sender, 0, sizeof(n2n_sock_t)); + sender.family = AF_INET; + sender.port = ntohs(sender_sock->sin_port); + memcpy(&(sender.addr.v4), &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + + memset(&nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t)); + + if(!comm) { + traceEvent(TRACE_DEBUG, "REGISTER_SUPER_NAK with unknown community %s", cmn.community); + return -1; + } + + decode_REGISTER_SUPER_NAK(&nak, &cmn, udp_buf, &rem, &idx); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, nak.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER_NAK due to time stamp error"); + return -1; + } + } + + traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_NAK from %s [%s]", + macaddr_str(mac_buf, nak.srcMac), + sock_to_cstr(sockbuf, &sender)); + + HASH_FIND_PEER(comm->edges, nak.srcMac, peer); + if(comm->is_federation == IS_NO_FEDERATION) { + if(peer != NULL) { + // this is a NAK for one of the edges conencted to this supernode, forward, + // i.e. re-assemble (memcpy from udpbuf to nakbuf could be sufficient as well) + + // use incoming cmn (with already decreased TTL) + // NAK (cookie, srcMac, auth) remains unchanged + + encode_REGISTER_SUPER_NAK(nakbuf, &encx, &cmn, &nak); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(nakbuf, encx, encx, + comm->header_encryption_ctx_static, comm->header_iv_ctx_static, + time_stamp()); + // if user-password-auth + if(comm->allowed_users) { + encode_buf(nakbuf, &encx, hash_buf /* no matter what content */, N2N_REG_SUP_HASH_CHECK_LEN); + } + } + + sendto_peer(sss, peer, nakbuf, encx); + + if((peer->socket_fd != sss->sock) && (peer->socket_fd >= 0)) { + n2n_tcp_connection_t *conn; + HASH_FIND_INT(sss->tcp_connections, &(peer->socket_fd), conn); + close_tcp_connection(sss, conn); /* also deletes the peer */ + } else { + HASH_DEL(comm->edges, peer); + free(peer); + } + } + } + break; + } + + case MSG_TYPE_QUERY_PEER: { + n2n_QUERY_PEER_t query; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + n2n_common_t cmn2; + n2n_PEER_INFO_t pi; + struct sn_community_regular_expression *re, *tmp_re; + int8_t allowed_match = -1; + uint8_t match = 0; + int match_length = 0; + + if(!comm && sss->lock_communities) { + HASH_ITER(hh, sss->rules, re, tmp_re) { + allowed_match = re_matchp(re->rule, (const char *)cmn.community, &match_length); + + if((allowed_match != -1) + && (match_length == strlen((const char *)cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted) + && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted) + match = 1; + break; + } + } + if(match != 1) { + traceEvent(TRACE_DEBUG, "QUERY_PEER from unknown community %s", cmn.community); + return -1; + } + } + + if(!comm && sss->lock_communities && (match == 0)) { + traceEvent(TRACE_DEBUG, "QUERY_PEER from not allowed community %s", cmn.community); + return -1; + } + + decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx ); + + // to answer a PING, it is sufficient if the provided communtiy would be a valid one, there does not + // neccessarily need to be a comm entry present, e.g. because there locally are no edges of the + // community connected (several supernodes in a federation setup) + if(comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, query.srcMac, stamp, TIME_STAMP_ALLOW_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped QUERY_PEER due to time stamp error"); + return -1; + } + } + } + + if(is_null_mac(query.targetMac)) { + traceEvent(TRACE_DEBUG, "Rx PING from %s", + macaddr_str(mac_buf, query.srcMac)); + + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_peer_info; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); + + pi.aflags = 0; + memcpy(pi.mac, query.targetMac, sizeof(n2n_mac_t)); + memcpy(pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t)); + pi.sock.family = AF_INET; + pi.sock.port = ntohs(sender_sock->sin_port); + memcpy(pi.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + pi.load = sn_selection_criterion_gather_data(sss); + + snprintf(pi.version, sizeof(pi.version), "%s", sss->version); + pi.uptime = now - sss->start_time; + + encode_PEER_INFO(encbuf, &encx, &cmn2, &pi); + + if(comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(encbuf, encx, encx, comm->header_encryption_ctx_dynamic, + comm->header_iv_ctx_dynamic, + time_stamp()); + } + } + + sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, encbuf, encx); + + traceEvent(TRACE_DEBUG, "Tx PONG to %s", + macaddr_str(mac_buf, query.srcMac)); + + } else { + traceEvent(TRACE_DEBUG, "Rx QUERY_PEER from %s for %s", + macaddr_str(mac_buf, query.srcMac), + macaddr_str(mac_buf2, query.targetMac)); + + struct peer_info *scan; + + // as opposed to the special case 'PING', proper QUERY_PEER processing requires a locally actually present community entry + if(!comm) { + traceEvent(TRACE_DEBUG, "QUERY_PEER with unknown community %s", cmn.community); + return -1; + } + + HASH_FIND_PEER(comm->edges, query.targetMac, scan); + if(scan) { + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_peer_info; + cmn2.flags = N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); + + pi.aflags = 0; + memcpy(pi.srcMac, query.srcMac, sizeof(n2n_mac_t)); + memcpy(pi.mac, query.targetMac, sizeof(n2n_mac_t)); + pi.sock = scan->sock; + if(scan->preferred_sock.family != (uint8_t)AF_INVALID) { + cmn2.flags |= N2N_FLAGS_SOCKET; + pi.preferred_sock = scan->preferred_sock; + } + + encode_PEER_INFO(encbuf, &encx, &cmn2, &pi); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(encbuf, encx, encx, comm->header_encryption_ctx_dynamic, + comm->header_iv_ctx_dynamic, + time_stamp()); + } + // back to sender, be it edge or supernode (which will forward to edge) + sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, encbuf, encx); + + traceEvent(TRACE_DEBUG, "Tx PEER_INFO to %s", + macaddr_str(mac_buf, query.srcMac)); + + } else { + + if(from_supernode) { + traceEvent(TRACE_DEBUG, "QUERY_PEER on unknown edge from supernode %s, dropping the packet", + macaddr_str(mac_buf, query.srcMac)); + } else { + traceEvent(TRACE_DEBUG, "QUERY_PEER from unknown edge %s, forwarding to all other supernodes", + macaddr_str(mac_buf, query.srcMac)); + + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + cmn2.flags |= N2N_FLAGS_FROM_SUPERNODE; + + encode_QUERY_PEER(encbuf, &encx, &cmn2, &query); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(encbuf, encx, encx, comm->header_encryption_ctx_dynamic, + comm->header_iv_ctx_dynamic, + time_stamp()); + } + + try_broadcast(sss, NULL, &cmn, query.srcMac, from_supernode, encbuf, encx); + } + } + } + break; + } + + case MSG_TYPE_PEER_INFO: { + n2n_PEER_INFO_t pi; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx = 0; + struct peer_info *peer; + + if(!comm) { + traceEvent(TRACE_DEBUG, "PEER_INFO with unknown community %s", cmn.community); + return -1; + } + + decode_PEER_INFO(&pi, &cmn, udp_buf, &rem, &idx); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify(comm->edges, sn, pi.srcMac, stamp, TIME_STAMP_NO_JITTER)) { + traceEvent(TRACE_DEBUG, "dropped PEER_INFO due to time stamp error"); + return -1; + } + } + + traceEvent(TRACE_INFO, "Rx PEER_INFO from %s [%s]", + macaddr_str(mac_buf, pi.srcMac), + sock_to_cstr(sockbuf, &sender)); + + HASH_FIND_PEER(comm->edges, pi.srcMac, peer); + if(peer != NULL) { + if((comm->is_federation == IS_NO_FEDERATION) && (!is_null_mac(pi.srcMac))) { + // snoop on the information to use for supernode forwarding (do not wait until first remote REGISTER_SUPER) + update_node_supernode_association(comm, &(pi.mac), sender_sock, now); + + // this is a PEER_INFO for one of the edges conencted to this supernode, forward, + // i.e. re-assemble (memcpy of udpbuf to encbuf could be sufficient as well) + + // use incoming cmn (with already decreased TTL) + // PEER_INFO remains unchanged + + encode_PEER_INFO(encbuf, &encx, &cmn, &pi); + + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + packet_header_encrypt(encbuf, encx, encx, + comm->header_encryption_ctx_dynamic, comm->header_iv_ctx_dynamic, + time_stamp()); + } + + sendto_peer(sss, peer, encbuf, encx); + } + } + break; + } + + default: + /* Not a known message type */ + traceEvent(TRACE_WARNING, "unable to handle packet type %d: ignored", (signed int)msg_type); + } /* switch(msg_type) */ + + return 0; +} + + +/** Long lived processing entry point. Split out from main to simply + * daemonisation on some platforms. */ +int run_sn_loop (n2n_sn_t *sss) { + + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; + time_t last_purge_edges = 0; + time_t last_sort_communities = 0; + time_t last_re_reg_and_purge = 0; + + sss->start_time = time(NULL); + + while(*sss->keep_running) { + int rc; + ssize_t bread; + int max_sock; + fd_set socket_mask; + n2n_tcp_connection_t *conn, *tmp_conn; + +#ifdef N2N_HAVE_TCP + SOCKET tmp_sock; + n2n_sock_str_t sockbuf; +#endif + struct timeval wait_time; + time_t before, now = 0; + + FD_ZERO(&socket_mask); + + FD_SET(sss->sock, &socket_mask); +#ifdef N2N_HAVE_TCP + FD_SET(sss->tcp_sock, &socket_mask); +#endif + FD_SET(sss->mgmt_sock, &socket_mask); + + max_sock = MAX(MAX(sss->sock, sss->mgmt_sock), sss->tcp_sock); + +#ifdef N2N_HAVE_TCP + // add the tcp connections' sockets + HASH_ITER(hh, sss->tcp_connections, conn, tmp_conn) { + //socket descriptor + FD_SET(conn->socket_fd, &socket_mask); + if(conn->socket_fd > max_sock) + max_sock = conn->socket_fd; + } +#endif + + wait_time.tv_sec = 10; + wait_time.tv_usec = 0; + + before = time(NULL); + + rc = select(max_sock + 1, &socket_mask, NULL, NULL, &wait_time); + + now = time(NULL); + + if(rc > 0) { + + // external udp + if(FD_ISSET(sss->sock, &socket_mask)) { + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sss->sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if((bread < 0) +#ifdef WIN32 + && (WSAGetLastError() != WSAECONNRESET) +#endif + ) { + /* For UDP bread of zero just means no data (unlike TCP). */ + /* The fd is no good now. Maybe we lost our interface. */ + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + *sss->keep_running = 0; + break; + } + + // we have a datagram to process... + if(bread > 0) { + // ...and the datagram has data (not just a header) + process_udp(sss, &sender_sock, sss->sock, pktbuf, bread, now); + } + } + +#ifdef N2N_HAVE_TCP + // the so far known tcp connections + + // beware: current conn and other items of the connection list may be found + // due for deletion while processing packets. Even OTHER connections, e.g. if + // forwarding to another edge node fails. connections due for deletion will + // not immediately be deleted but marked 'inactive' for later deletion + HASH_ITER(hh, sss->tcp_connections, conn, tmp_conn) { + // do not process entries that have been marked inactive, those will be deleted + // immediately after this loop + if(conn->inactive) + continue; + + if(FD_ISSET(conn->socket_fd, &socket_mask)) { + + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + bread = recvfrom(conn->socket_fd, + conn->buffer + conn->position, conn->expected - conn->position, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if(bread <= 0) { + traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock)); + traceEvent(TRACE_DEBUG, "recvfrom() returns %d and sees errno %d (%s)", bread, errno, strerror(errno)); +#ifdef WIN32 + traceEvent(TRACE_DEBUG, "WSAGetLastError(): %u", WSAGetLastError()); +#endif + close_tcp_connection(sss, conn); + continue; + } + conn->position += bread; + + if(conn->position == conn->expected) { + if(conn->position == sizeof(uint16_t)) { + // the prepended length has been read, preparing for the packet + conn->expected += be16toh(*(uint16_t*)(conn->buffer)); + if(conn->expected > N2N_SN_PKTBUF_SIZE) { + traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock)); + traceEvent(TRACE_DEBUG, "too many bytes in tcp packet expected"); + close_tcp_connection(sss, conn); + continue; + } + } else { + // full packet read, handle it + process_udp(sss, (struct sockaddr_in*)&(conn->sock), conn->socket_fd, + conn->buffer + sizeof(uint16_t), conn->position - sizeof(uint16_t), now); + + // reset, await new prepended length + conn->expected = sizeof(uint16_t); + conn->position = 0; + } + } + } + } + + // remove inactive / already closed tcp connections from list + HASH_ITER(hh, sss->tcp_connections, conn, tmp_conn) { + if(conn->inactive) { + HASH_DEL(sss->tcp_connections, conn); + free(conn); + } + } + + // accept new incoming tcp connection + if(FD_ISSET(sss->tcp_sock, &socket_mask)) { + struct sockaddr_in sender_sock; + socklen_t i; + + i = sizeof(sender_sock); + if((HASH_COUNT(sss->tcp_connections) + 4) < FD_SETSIZE) { + tmp_sock = accept(sss->tcp_sock, (struct sockaddr *)&sender_sock, (socklen_t *)&i); + if(tmp_sock >= 0) { + conn = (n2n_tcp_connection_t*)malloc(sizeof(n2n_tcp_connection_t)); + if(conn) { + conn->socket_fd = tmp_sock; + memcpy(&(conn->sock), &sender_sock, sizeof(struct sockaddr_in)); + conn->inactive = 0; + conn->expected = sizeof(uint16_t); + conn->position = 0; + HASH_ADD_INT(sss->tcp_connections, socket_fd, conn); + traceEvent(TRACE_INFO, "accepted incoming TCP connection from [%s]", + sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock)); + } + } + } else { + // no space to store the socket for a new connection, close immediately + traceEvent(TRACE_DEBUG, "denied incoming TCP connection from [%s] due to max connections limit hit", + sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock)); + } + } +#endif /* N2N_HAVE_TCP */ + + // handle management port input + if(FD_ISSET(sss->mgmt_sock, &socket_mask)) { + struct sockaddr_in sender_sock; + size_t i; + + i = sizeof(sender_sock); + bread = recvfrom(sss->mgmt_sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); + + if(bread <= 0) { + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); + *sss->keep_running = 0; + break; + } + + // we have a datagram to process + process_mgmt(sss, &sender_sock, (char *)pktbuf, bread, now); + } + + } else { + if(((now - before) < wait_time.tv_sec) && (*sss->keep_running)){ + // this is no real timeout, something went wrong with one of the tcp connections (probably) + // close them all, edges will re-open if they detect closure + traceEvent(TRACE_DEBUG, "falsly claimed timeout, assuming issue with tcp connection, closing them all"); + HASH_ITER(hh, sss->tcp_connections, conn, tmp_conn) + close_tcp_connection(sss, conn); + } else + traceEvent(TRACE_DEBUG, "timeout"); + } + + re_register_and_purge_supernodes(sss, sss->federation, &last_re_reg_and_purge, now, 0 /* not forced */); + purge_expired_communities(sss, &last_purge_edges, now); + sort_communities(sss, &last_sort_communities, now); + resolve_check(sss->resolve_parameter, 0 /* presumably, no special resolution requirement */, now); + } /* while */ + + sn_term(sss); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/speck.c b/bundles/n2n_ntop_v3/src/speck.c new file mode 100644 index 00000000..f0f28096 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/speck.c @@ -0,0 +1,1026 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +// cipher SPECK -- 128 bit block size -- 128 and 256 bit key size -- CTR mode +// taken from (and modified: removed pure crypto-stream generation and seperated key expansion) +// https://github.com/nsacyber/simon-speck-supercop/blob/master/crypto_stream/speck128256ctr/ + + +#include "speck.h" + + +#if defined (__AVX512F__) // AVX512 support ---------------------------------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define SET _mm512_set_epi64 +#define XOR _mm512_xor_si512 +#define ADD _mm512_add_epi64 +#define AND _mm512_and_si512 +#define ROL(X,r) (_mm512_rol_epi64(X,r)) +#define ROR(X,r) (_mm512_ror_epi64(X,r)) + +#define _q8 SET(0x7LL,0x3LL,0x6LL,0x2LL,0x5LL,0x1LL,0x4LL,0x0LL) +#define _eight SET(0x8LL,0x8LL,0x8LL,0x8LL,0x8LL,0x8LL,0x8LL,0x8LL) + +#define SET1(X,c) (X=SET(c,c,c,c,c,c,c,c)) +#define SET8(X,c) (X=SET(c,c,c,c,c,c,c,c), X=ADD(X,_q8)) + +#define LOW _mm512_unpacklo_epi64 +#define HIGH _mm512_unpackhi_epi64 +#define LD(ip) (_mm512_load_epi64(((void *)(ip)))) +#define ST(ip,X) _mm512_storeu_si512((void *)(ip),X) +#define STORE(out,X,Y) (ST(out,LOW(Y,X)), ST(out+64,HIGH(Y,X))) +#define XOR_STORE(in,out,X,Y) (ST(out,XOR(LD(in),LOW(Y,X))), ST(out+64,XOR(LD(in+64),HIGH(Y,X)))) + +#define Rx8(X,Y,k) (X[0]=XOR(ADD(ROR(X[0],8),Y[0]),k), \ + Y[0]=XOR(ROL(Y[0],3),X[0])) +#define Rx16(X,Y,k) (X[0]=XOR(ADD(ROR(X[0],8),Y[0]),k), X[1]=XOR(ADD(ROR(X[1],8),Y[1]),k), \ + Y[0]=XOR(ROL(Y[0],3),X[0]), Y[1]=XOR(ROL(Y[1],3),X[1])) +#define Rx24(X,Y,k) (X[0]=XOR(ADD(ROR(X[0],8),Y[0]),k), X[1]=XOR(ADD(ROR(X[1],8),Y[1]),k), X[2]=XOR(ADD(ROR(X[2],8),Y[2]),k), \ + Y[0]=XOR(ROL(Y[0],3),X[0]), Y[1]=XOR(ROL(Y[1],3),X[1]), Y[2]=XOR(ROL(Y[2],3),X[2])) +#define Rx32(X,Y,k) (X[0]=XOR(ADD(ROR(X[0],8),Y[0]),k), X[1]=XOR(ADD(ROR(X[1],8),Y[1]),k), \ + X[2]=XOR(ADD(ROR(X[2],8),Y[2]),k), X[3]=XOR(ADD(ROR(X[3],8),Y[3]),k), \ + Y[0]=XOR(ROL(Y[0],3),X[0]), Y[1]=XOR(ROL(Y[1],3),X[1]), \ + Y[2]=XOR(ROL(Y[2],3),X[2]), Y[3]=XOR(ROL(Y[3],3),X[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) +#define Rx2(x,y,k) (x[0]=RCS(x[0],8), x[1]=RCS(x[1],8), x[0]+=y[0], x[1]+=y[1], \ + x[0]^=k, x[1]^=k, y[0]=LCS(y[0],3), y[1]=LCS(y[1],3), y[0]^=x[0], y[1]^=x[1]) + +#define Encrypt_128(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31])) + +#define Encrypt_256(X,Y,k,n) (Encrypt_128(X,Y,k,n), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + +#define Encrypt_Dispatcher(keysize) \ + u64 x[2], y[2]; \ + u512 X[4], Y[4]; \ + unsigned char block1024[128]; \ + \ + if(numbytes == 16) { \ + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x, y, ctx->key, 1); \ + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; \ + return 0; \ + } \ + \ + if(numbytes == 32) { \ + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; \ + x[1] = nonce[1]; y[1] = nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x, y, ctx->key, 2); \ + ((u64 *)out)[1] = x[0] ^ ((u64 *)in)[1]; ((u64 *)out)[0] = y[0] ^ ((u64 *)in)[0]; \ + ((u64 *)out)[3] = x[1] ^ ((u64 *)in)[3]; ((u64 *)out)[2] = y[1] ^ ((u64 *)in)[2]; \ + return 0; \ + } \ + \ + if(numbytes == 64) { \ + SET1(X[0], nonce[1]); \ + SET8(Y[0], nonce[0]); \ + Encrypt_##keysize(X, Y, ctx->rk, 8); \ + nonce[0] += (numbytes >> 4); \ + memcpy(block1024, in, 64); \ + XOR_STORE(block1024, block1024, X[0], Y[0]); \ + memcpy(out, block1024, 64); \ + return 0; \ + } \ + \ + SET1(X[0], nonce[1]); SET8(Y[0], nonce[0]); \ + \ + if(numbytes == 128) \ + Encrypt_##keysize(X, Y, ctx->rk, 8); \ + else { \ + X[1] = X[0]; \ + Y[1] = ADD(Y[0], _eight); \ + if(numbytes == 256) \ + Encrypt_##keysize(X, Y, ctx->rk, 16); \ + else { \ + X[2] = X[0]; \ + Y[2] = ADD(Y[1], _eight); \ + if(numbytes == 384) \ + Encrypt_##keysize(X, Y, ctx->rk, 24); \ + else { \ + X[3] = X[0]; \ + Y[3] = ADD(Y[2], _eight); \ + Encrypt_##keysize(X, Y, ctx->rk, 32); \ + } \ + } \ + } \ + \ + nonce[0] += (numbytes >> 4); \ + \ + XOR_STORE(in, out, X[0], Y[0]); \ + if (numbytes >= 256) \ + XOR_STORE(in + 128, out + 128, X[1], Y[1]); \ + if(numbytes >= 384) \ + XOR_STORE(in + 256, out + 256, X[2], Y[2]); \ + if(numbytes >= 512) \ + XOR_STORE(in + 384, out + 384, X[3], Y[3]); \ + \ + return 0 + + +static int speck_encrypt_xor(unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { + + if(ctx->keysize == 256) { + Encrypt_Dispatcher(256); + } else { + Encrypt_Dispatcher(128); + } +} + + +static int internal_speck_ctr(unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while(inlen >= 512) { + speck_encrypt_xor(out, in, nonce, ctx, 512); + in += 512; inlen -= 512; out += 512; + } + + if(inlen >= 384) { + speck_encrypt_xor(out, in, nonce, ctx, 384); + in += 384; inlen -= 384; out += 384; + } + + if(inlen >= 256) { + speck_encrypt_xor(out, in, nonce, ctx, 256); + in += 256; inlen -= 256; out += 256; + } + + if(inlen >= 128) { + speck_encrypt_xor(out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if(inlen >= 64) { + speck_encrypt_xor(out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if(inlen >= 32) { + speck_encrypt_xor(out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if(inlen >= 16) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if(inlen > 0) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + for(i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +static int speck_expand_key (speck_context_t *ctx, const unsigned char *k, int keysize) { + + u64 K[4]; + size_t i; + + for(i = 0; i < (keysize >> 6); i++) + K[i] = ((u64 *)k)[i]; + + // 128 bit has only two keys A and B thus replacing both C and D with B then + if(keysize == 128) { + EK(K[0], K[1], K[1], K[1], ctx->rk, ctx->key); + } else { + EK(K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + } + + ctx->keysize = keysize; + + return 0; +} + + +#elif defined (__AVX2__) // AVX2 support ------------------------------------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR _mm256_xor_si256 +#define AND _mm256_and_si256 +#define ADD _mm256_add_epi64 +#define SL _mm256_slli_epi64 +#define SR _mm256_srli_epi64 + +#define _q SET(0x3,0x1,0x2,0x0) +#define _four SET(0x4,0x4,0x4,0x4) + +#define SET _mm256_set_epi64x +#define SET1(X,c) (X=SET(c,c,c,c)) +#define SET4(X,c) (X=SET(c,c,c,c), X=ADD(X,_q)) + +#define LOW _mm256_unpacklo_epi64 +#define HIGH _mm256_unpackhi_epi64 +#define LD(ip) _mm256_loadu_si256((__m256i *)(ip)) +#define ST(ip,X) _mm256_storeu_si256((__m256i *)(ip),X) +#define STORE(out,X,Y) (ST(out,LOW(Y,X)), ST(out+32,HIGH(Y,X))) +#define STORE_ALT(out,X,Y) (ST(out,LOW(X,Y)), ST(out+32,HIGH(X,Y))) +#define XOR_STORE(in,out,X,Y) (ST(out,XOR(LD(in),LOW(Y,X))), ST(out+32,XOR(LD(in+32),HIGH(Y,X)))) +#define XOR_STORE_ALT(in,out,X,Y) (ST(out,XOR(LD(in),LOW(X,Y))), ST(out+32,XOR(LD(in+32),HIGH(X,Y)))) + +#define SHFL _mm256_shuffle_epi8 +#define R8 SET(0x080f0e0d0c0b0a09LL,0x0007060504030201LL,0x080f0e0d0c0b0a09LL,0x0007060504030201LL) +#define L8 SET(0x0e0d0c0b0a09080fLL,0x0605040302010007LL,0x0e0d0c0b0a09080fLL,0x0605040302010007LL) +#define ROL8(X) (SHFL(X,L8)) +#define ROR8(X) (SHFL(X,R8)) +#define ROL(X,r) (XOR(SL(X,r),SR(X,(64-r)))) +#define ROR(X,r) (XOR(SR(X,r),SL(X,(64-r)))) + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx4(X,Y,k) (R(X[0],Y[0],k)) +#define Rx8(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx12(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) +#define Rx16(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), \ + X[0]=XOR(X[0],k), X[1]=XOR(X[1],k), X[2]=XOR(X[2],k), X[3]=XOR(X[3],k), \ + Z[0]=Y[0], Z[1]=Y[1], Z[2]=Y[2], Z[3]=Y[3], \ + Z[0]=SL(Z[0],3), Y[0]=SR(Y[0],61), Z[1]=SL(Z[1],3), Y[1]=SR(Y[1],61), \ + Z[2]=SL(Z[2],3), Y[2]=SR(Y[2],61), Z[3]=SL(Z[3],3), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) +#define Rx2(x,y,k) (x[0]=RCS(x[0],8), x[1]=RCS(x[1],8), x[0]+=y[0], x[1]+=y[1], \ + x[0]^=k, x[1]^=k, y[0]=LCS(y[0],3), y[1]=LCS(y[1],3), y[0]^=x[0], y[1]^=x[1]) + +#define Encrypt_128(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31])) + +#define Encrypt_256(X,Y,k,n) (Encrypt_128(X,Y,k,n), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + +#define Encrypt_Dispatcher(keysize) \ + u64 x[2], y[2]; \ + u256 X[4], Y[4], Z[4]; \ + \ + if(numbytes == 16) { \ + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x, y, ctx->key, 1); \ + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; \ + return 0; \ + } \ + \ + if(numbytes == 32) { \ + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; \ + x[1] = nonce[1]; y[1] = nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x , y, ctx->key, 2); \ + ((u64 *)out)[1] = x[0] ^ ((u64 *)in)[1]; ((u64 *)out)[0] = y[0] ^ ((u64 *)in)[0]; \ + ((u64 *)out)[3] = x[1] ^ ((u64 *)in)[3]; ((u64 *)out)[2] = y[1] ^ ((u64 *)in)[2]; \ + return 0; \ + } \ + \ + SET1(X[0], nonce[1]); SET4(Y[0], nonce[0]); \ + \ + if(numbytes == 64) \ + Encrypt_##keysize(X, Y, ctx->rk, 4); \ + else { \ + X[1] = X[0]; \ + Y[1] = ADD(Y[0], _four); \ + if(numbytes == 128) \ + Encrypt_##keysize(X, Y, ctx->rk, 8); \ + else { \ + X[2] = X[0]; \ + Y[2] = ADD(Y[1], _four); \ + if(numbytes == 192) \ + Encrypt_##keysize(X, Y, ctx->rk, 12); \ + else { \ + X[3] = X[0]; \ + Y[3] = ADD(Y[2], _four); \ + Encrypt_##keysize(X, Y, ctx->rk, 16); \ + } \ + } \ + } \ + \ + nonce[0] += (numbytes >> 4); \ + \ + XOR_STORE(in, out, X[0], Y[0]); \ + if (numbytes >= 128) \ + XOR_STORE(in + 64, out + 64, X[1], Y[1]); \ + if(numbytes >= 192) \ + XOR_STORE(in + 128, out + 128, X[2], Y[2]); \ + if(numbytes >= 256) \ + XOR_STORE(in + 192, out + 192, X[3], Y[3]); \ + \ + return 0 + + +static int speck_encrypt_xor(unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { + + if(ctx->keysize == 256) { + Encrypt_Dispatcher(256); + } else { + Encrypt_Dispatcher(128); + } +} + + +static int internal_speck_ctr(unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if (!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while(inlen >= 256) { + speck_encrypt_xor(out, in, nonce, ctx, 256); + in += 256; inlen -= 256; out += 256; + } + + if(inlen >= 192) { + speck_encrypt_xor(out, in, nonce, ctx, 192); + in += 192; inlen -= 192; out += 192; + } + + if(inlen >= 128) { + speck_encrypt_xor(out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if(inlen >= 64) { + speck_encrypt_xor(out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if(inlen >= 32) { + speck_encrypt_xor(out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if(inlen >= 16) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if(inlen > 0) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + for(i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +static int speck_expand_key (speck_context_t *ctx, const unsigned char *k, int keysize) { + + u64 K[4]; + size_t i; + + for(i = 0; i < (keysize >> 6); i++) + K[i] = ((u64 *)k)[i]; + + // 128 bit has only two keys A and B thus replacing both C and D with B then + if(keysize == 128) { + EK(K[0], K[1], K[1], K[1], ctx->rk, ctx->key); + } else { + EK(K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + } + + ctx->keysize = keysize; + + return 0; +} + + +#elif defined (__SSE2__) // SSE support --------------------------------------------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR _mm_xor_si128 +#define AND _mm_and_si128 +#define ADD _mm_add_epi64 +#define SL _mm_slli_epi64 +#define SR _mm_srli_epi64 + +#define _q SET(0x1,0x0) +#define _two SET(0x2,0x2) + +#define SET _mm_set_epi64x +#define SET1(X,c) (X=SET(c,c)) +#define SET2(X,c) (X=SET(c,c), X=ADD(X,_q)) + +#define LOW _mm_unpacklo_epi64 +#define HIGH _mm_unpackhi_epi64 +#define LD(ip) _mm_loadu_si128((__m128i *)(ip)) +#define ST(ip,X) _mm_storeu_si128((__m128i *)(ip),X) +#define STORE(out,X,Y) (ST(out,LOW(Y,X)), ST(out+16,HIGH(Y,X))) +#define STORE_ALT(out,X,Y) (ST(out,LOW(X,Y)), ST(out+16,HIGH(X,Y))) +#define XOR_STORE(in,out,X,Y) (ST(out,XOR(LD(in),LOW(Y,X))), ST(out+16,XOR(LD(in+16),HIGH(Y,X)))) +#define XOR_STORE_ALT(in,out,X,Y) (ST(out,XOR(LD(in),LOW(X,Y))), ST(out+16,XOR(LD(in+16),HIGH(X,Y)))) + +#define ROL(X,r) (XOR(SL(X,r),SR(X,(64-r)))) +#define ROR(X,r) (XOR(SR(X,r),SL(X,(64-r)))) + +#if defined (__SSSE3__) // even SSSE3 ------------------------------- +#define SHFL _mm_shuffle_epi8 +#define R8 _mm_set_epi64x(0x080f0e0d0c0b0a09LL,0x0007060504030201LL) +#define L8 _mm_set_epi64x(0x0e0d0c0b0a09080fLL,0x0605040302010007LL) +#define ROL8(X) (SHFL(X,L8)) +#define ROR8(X) (SHFL(X,R8)) +#else // regular SSE2 ------------------------------------------------ +#define ROL8(X) (ROL(X,8)) +#define ROR8(X) (ROR(X,8)) +#endif // SSS3 vs. SSE2 ---------------------------------------------- + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx2(X,Y,k) (R(X[0],Y[0],k)) +#define Rx4(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx6(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) +#define Rx8(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), \ + X[0]=XOR(X[0],k), X[1]=XOR(X[1],k), X[2]=XOR(X[2],k), X[3]=XOR(X[3],k), \ + Z[0]=Y[0], Z[1]=Y[1], Z[2]=Y[2], Z[3]=Y[3], \ + Z[0]=SL(Z[0],3), Y[0]=SR(Y[0],61), Z[1]=SL(Z[1],3), Y[1]=SR(Y[1],61), \ + Z[2]=SL(Z[2],3), Y[2]=SR(Y[2],61), Z[3]=SL(Z[3],3), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) + +#define Encrypt_128(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31])) + +#define Encrypt_256(X,Y,k,n) (Encrypt_128(X,Y,k,n), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + +#define Encrypt_Dispatcher(keysize) \ + u64 x[2], y[2]; \ + u128 X[4], Y[4], Z[4]; \ + \ + if(numbytes == 16) { \ + x[0] = nonce[1]; y[0] = nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x, y, ctx.key, 1); \ + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; \ + return 0; \ + } \ + \ + SET1(X[0], nonce[1]); SET2(Y[0], nonce[0]); \ + \ + if(numbytes == 32) \ + Encrypt_##keysize(X, Y, ctx.rk, 2); \ + else { \ + X[1] = X[0]; Y[1] = ADD(Y[0], _two); \ + if(numbytes == 64) \ + Encrypt_##keysize(X, Y, ctx.rk, 4); \ + else { \ + X[2] = X[0]; Y[2] = ADD(Y[1], _two); \ + if(numbytes == 96) \ + Encrypt_##keysize(X, Y, ctx.rk, 6); \ + else { \ + X[3] = X[0]; Y[3] = ADD(Y[2], _two); \ + Encrypt_##keysize(X, Y, ctx.rk, 8); \ + } \ + } \ + } \ + \ + nonce[0] += (numbytes >> 4); \ + \ + XOR_STORE(in, out, X[0], Y[0]); \ + if(numbytes >= 64) \ + XOR_STORE(in + 32, out + 32, X[1], Y[1]); \ + if(numbytes >= 96) \ + XOR_STORE(in + 64, out + 64, X[2], Y[2]); \ + if(numbytes >= 128) \ + XOR_STORE(in + 96, out + 96, X[3], Y[3]); \ + \ + return 0 + + +// attention: ctx is provided by value as it is faster in this case, astonishingly +static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], const speck_context_t ctx, int numbytes) { + + if(ctx.keysize == 256) { + Encrypt_Dispatcher(256); + } else { + Encrypt_Dispatcher(128); + } +} + + +// attention: ctx is provided by value as it is faster in this case, astonishingly +static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, const speck_context_t ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 * const block64 = (u64 *)block; + + if(!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while(inlen >= 128) { + speck_encrypt_xor(out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if(inlen >= 96) { + speck_encrypt_xor(out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if(inlen >= 64) { + speck_encrypt_xor(out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if(inlen >= 32) { + speck_encrypt_xor(out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if(inlen >= 16) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if(inlen > 0) { + speck_encrypt_xor (block, in, nonce, ctx, 16); + for(i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +static int speck_expand_key (speck_context_t *ctx, const unsigned char *k, int keysize) { + + u64 K[4]; + size_t i; + + for(i = 0; i < (keysize >> 6 ); i++) + K[i] = ((u64 *)k)[i]; + + // 128 bit has only two keys A and B thus replacing both C and D with B then + if(keysize == 128) { + EK(K[0], K[1], K[1], K[1], ctx->rk, ctx->key); + } else { + EK(K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + } + + ctx->keysize = keysize; + + return 0; +} + + +#elif defined (__ARM_NEON) && defined (SPECK_ARM_NEON) // NEON support --------------------------------------- + + +#define LCS(x,r) (((x)<>(64-r))) +#define RCS(x,r) (((x)>>r)|((x)<<(64-r))) + +#define XOR veorq_u64 +#define AND vandq_u64 +#define ADD vaddq_u64 +#define SL vshlq_n_u64 +#define SR vshrq_n_u64 + +#define SET(a,b) vcombine_u64((uint64x1_t)(a),(uint64x1_t)(b)) +#define SET1(X,c) (X=SET(c,c)) +#define SET2(X,c) (SET1(X,c), X=ADD(X,SET(0x1ll,0x0ll)),c+=2) + +#define LOW(Z) vgetq_lane_u64(Z,0) +#define HIGH(Z) vgetq_lane_u64(Z,1) +#define STORE(ip,X,Y) (((u64 *)(ip))[0]=HIGH(Y), ((u64 *)(ip))[1]=HIGH(X), ((u64 *)(ip))[2]=LOW(Y), ((u64 *)(ip))[3]=LOW(X)) +#define XOR_STORE(in,out,X,Y) (Y=XOR(Y,SET(((u64 *)(in))[2],((u64 *)(in))[0])), X=XOR(X,SET(((u64 *)(in))[3],((u64 *)(in))[1])), STORE(out,X,Y)) + +#define ROR(X,r) vsriq_n_u64(SL(X,(64-r)),X,r) +#define ROL(X,r) ROR(X,(64-r)) + +#define tableR vcreate_u8(0x0007060504030201LL) +#define tableL vcreate_u8(0x0605040302010007LL) +#define ROR8(X) SET(vtbl1_u8((uint8x8_t)vget_low_u64(X),tableR), vtbl1_u8((uint8x8_t)vget_high_u64(X),tableR)) +#define ROL8(X) SET(vtbl1_u8((uint8x8_t)vget_low_u64(X),tableL), vtbl1_u8((uint8x8_t)vget_high_u64(X),tableL)) + +#define R(X,Y,k) (X=XOR(ADD(ROR8(X),Y),k), Y=XOR(ROL(Y,3),X)) + +#define Rx2(X,Y,k) (R(X[0],Y[0],k)) +#define Rx4(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k)) +#define Rx6(X,Y,k) (R(X[0],Y[0],k), R(X[1],Y[1],k), R(X[2],Y[2],k)) +#define Rx8(X,Y,k) (X[0]=ROR8(X[0]), X[0]=ADD(X[0],Y[0]), X[0]=XOR(X[0],k), X[1]=ROR8(X[1]), X[1]=ADD(X[1],Y[1]), X[1]=XOR(X[1],k), \ + X[2]=ROR8(X[2]), X[2]=ADD(X[2],Y[2]), X[2]=XOR(X[2],k), X[3]=ROR8(X[3]), X[3]=ADD(X[3],Y[3]), X[3]=XOR(X[3],k), \ + Z[0]=SL(Y[0],3), Z[1]=SL(Y[1],3), Z[2]=SL(Y[2],3), Z[3]=SL(Y[3],3), \ + Y[0]=SR(Y[0],61), Y[1]=SR(Y[1],61), Y[2]=SR(Y[2],61), Y[3]=SR(Y[3],61), \ + Y[0]=XOR(Y[0],Z[0]), Y[1]=XOR(Y[1],Z[1]), Y[2]=XOR(Y[2],Z[2]), Y[3]=XOR(Y[3],Z[3]), \ + Y[0]=XOR(X[0],Y[0]), Y[1]=XOR(X[1],Y[1]), Y[2]=XOR(X[2],Y[2]), Y[3]=XOR(X[3],Y[3])) + +#define Rx1(x,y,k) (x[0]=RCS(x[0],8), x[0]+=y[0], x[0]^=k, y[0]=LCS(y[0],3), y[0]^=x[0]) +#define Rx1b(x,y,k) (x=RCS(x,8), x+=y, x^=k, y=LCS(y,3), y^=x) + +#define Encrypt_128(X,Y,k,n) (Rx##n(X,Y,k[0]), Rx##n(X,Y,k[1]), Rx##n(X,Y,k[2]), Rx##n(X,Y,k[3]), Rx##n(X,Y,k[4]), Rx##n(X,Y,k[5]), Rx##n(X,Y,k[6]), Rx##n(X,Y,k[7]), \ + Rx##n(X,Y,k[8]), Rx##n(X,Y,k[9]), Rx##n(X,Y,k[10]), Rx##n(X,Y,k[11]), Rx##n(X,Y,k[12]), Rx##n(X,Y,k[13]), Rx##n(X,Y,k[14]), Rx##n(X,Y,k[15]), \ + Rx##n(X,Y,k[16]), Rx##n(X,Y,k[17]), Rx##n(X,Y,k[18]), Rx##n(X,Y,k[19]), Rx##n(X,Y,k[20]), Rx##n(X,Y,k[21]), Rx##n(X,Y,k[22]), Rx##n(X,Y,k[23]), \ + Rx##n(X,Y,k[24]), Rx##n(X,Y,k[25]), Rx##n(X,Y,k[26]), Rx##n(X,Y,k[27]), Rx##n(X,Y,k[28]), Rx##n(X,Y,k[29]), Rx##n(X,Y,k[30]), Rx##n(X,Y,k[31])) + +#define Encrypt_256(X,Y,k,n) (Encrypt_128(X,Y,k,n), \ + Rx##n(X,Y,k[32]), Rx##n(X,Y,k[33])) + +#define RK(X,Y,k,key,i) (SET1(k[i],Y), key[i]=Y, X=RCS(X,8), X+=Y, X^=i, Y=LCS(Y,3), Y^=X) + +#define EK(A,B,C,D,k,key) (RK(B,A,k,key,0), RK(C,A,k,key,1), RK(D,A,k,key,2), RK(B,A,k,key,3), RK(C,A,k,key,4), RK(D,A,k,key,5), RK(B,A,k,key,6), \ + RK(C,A,k,key,7), RK(D,A,k,key,8), RK(B,A,k,key,9), RK(C,A,k,key,10), RK(D,A,k,key,11), RK(B,A,k,key,12), RK(C,A,k,key,13), \ + RK(D,A,k,key,14), RK(B,A,k,key,15), RK(C,A,k,key,16), RK(D,A,k,key,17), RK(B,A,k,key,18), RK(C,A,k,key,19), RK(D,A,k,key,20), \ + RK(B,A,k,key,21), RK(C,A,k,key,22), RK(D,A,k,key,23), RK(B,A,k,key,24), RK(C,A,k,key,25), RK(D,A,k,key,26), RK(B,A,k,key,27), \ + RK(C,A,k,key,28), RK(D,A,k,key,29), RK(B,A,k,key,30), RK(C,A,k,key,31), RK(D,A,k,key,32), RK(B,A,k,key,33)) + +#define Encrypt_Dispatcher(keysize) \ + u64 x[2], y[2]; \ + u128 X[4], Y[4], Z[4]; \ + \ + if(numbytes == 16) { \ + x[0] = nonce[1]; y[0]=nonce[0]; nonce[0]++; \ + Encrypt_##keysize(x, y, ctx->key, 1); \ + ((u64 *)out)[1] = x[0]; ((u64 *)out)[0] = y[0]; \ + return 0; \ + } \ + \ + SET1(X[0], nonce[1]); SET2(Y[0], nonce[0]); \ + \ + if(numbytes == 32) \ + Encrypt_##keysize(X, Y, ctx->rk, 2); \ + else { \ + X[1] = X[0]; SET2(Y[1], nonce[0]); \ + if(numbytes == 64) \ + Encrypt_##keysize(X, Y, ctx->rk, 4); \ + else { \ + X[2] = X[0]; SET2(Y[2], nonce[0]); \ + if(numbytes == 96) \ + Encrypt_##keysize(X, Y, ctx->rk, 6); \ + else { \ + X[3] = X[0]; SET2(Y[3], nonce[0]); \ + Encrypt_##keysize(X, Y, ctx->rk, 8); \ + } \ + } \ + } \ + \ + XOR_STORE(in, out, X[0], Y[0]); \ + if(numbytes >= 64) \ + XOR_STORE(in + 32, out + 32, X[1], Y[1]); \ + if(numbytes >= 96) \ + XOR_STORE(in + 64, out + 64, X[2], Y[2]); \ + if(numbytes >= 128) \ + XOR_STORE(in + 96, out + 96, X[3], Y[3]); \ + \ + return 0 + + +static int speck_encrypt_xor (unsigned char *out, const unsigned char *in, u64 nonce[], speck_context_t *ctx, int numbytes) { + + if(ctx->keysize == 256) { + Encrypt_Dispatcher(256); + } else { + Encrypt_Dispatcher(128); + } +} + + +static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + int i; + u64 nonce[2]; + unsigned char block[16]; + u64 *const block64 = (u64 *)block; + + if(!inlen) + return 0; + + nonce[0] = ((u64 *)n)[0]; + nonce[1] = ((u64 *)n)[1]; + + while(inlen >= 128) { + speck_encrypt_xor(out, in, nonce, ctx, 128); + in += 128; inlen -= 128; out += 128; + } + + if(inlen >= 96) { + speck_encrypt_xor(out, in, nonce, ctx, 96); + in += 96; inlen -= 96; out += 96; + } + + if(inlen >= 64) { + speck_encrypt_xor(out, in, nonce, ctx, 64); + in += 64; inlen -= 64; out += 64; + } + + if(inlen >= 32) { + speck_encrypt_xor(out, in, nonce, ctx, 32); + in += 32; inlen -= 32; out += 32; + } + + if(inlen >= 16) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + ((u64 *)out)[0] = block64[0] ^ ((u64 *)in)[0]; + ((u64 *)out)[1] = block64[1] ^ ((u64 *)in)[1]; + in += 16; inlen -= 16; out += 16; + } + + if(inlen > 0) { + speck_encrypt_xor(block, in, nonce, ctx, 16); + for(i = 0; i < inlen; i++) + out[i] = block[i] ^ in[i]; + } + + return 0; +} + + +static int speck_expand_key (speck_context_t *ctx, const unsigned char *k, int keysize) { + + u64 K[4]; + size_t i; + + for(i = 0; i < (keysize >> 6); i++) + K[i] = ((u64 *)k)[i]; + + // 128 bit has only two keys A and B thus replacing both C and D with B then + if(keysize == 128) { + EK(K[0], K[1], K[1], K[1], ctx->rk, ctx->key); + } else { + EK(K[0], K[1], K[2], K[3], ctx->rk, ctx->key); + } + + ctx->keysize = keysize; + + return 0; +} + + +#else // plain C ---------------------------------------------------------------------------------------- + + +#define ROR(x,r) (((x)>>(r))|((x)<<(64-(r)))) +#define ROL(x,r) (((x)<<(r))|((x)>>(64-(r)))) +#define R(x,y,k) (x=ROR(x,8), x+=y, x^=k, y=ROL(y,3), y^=x) + + +static int speck_encrypt (u64 *u, u64 *v, speck_context_t *ctx, int numrounds) { + + u64 i, x = *u, y = *v; + + for(i = 0; i < numrounds; i++) + R(x, y, ctx->key[i]); + *u = x; *v = y; + + return 0; +} + + +static int internal_speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + u64 i, nonce[2], x, y, t; + unsigned char *block = malloc(16); + int numrounds = (ctx->keysize == 256)?34:32; + + if(!inlen) { + free(block); + return 0; + } + nonce[0] = htole64( ((u64*)n)[0] ); + nonce[1] = htole64( ((u64*)n)[1] ); + + t=0; + while(inlen >= 16) { + x = nonce[1]; y = nonce[0]; nonce[0]++; + speck_encrypt(&x, &y, ctx, numrounds); + ((u64 *)out)[1+t] = htole64(x ^ ((u64 *)in)[1+t]); + ((u64 *)out)[0+t] = htole64(y ^ ((u64 *)in)[0+t]); + t += 2; + inlen -= 16; + } + + if(inlen > 0) { + x = nonce[1]; y = nonce[0]; + speck_encrypt(&x, &y, ctx, numrounds); + ((u64 *)block)[1] = htole64(x); ((u64 *)block)[0] = htole64(y); + for(i = 0; i < inlen; i++) + out[i + 8*t] = block[i] ^ in[i + 8*t]; + } + + free(block); + + return 0; +} + + +static int speck_expand_key (speck_context_t *ctx, const unsigned char *k, int keysize) { + + u64 K[4]; + u64 i; + + for(i = 0; i < (keysize >> 6); i++) + K[i] = htole64( ((u64 *)k)[i] ); + + for(i = 0; i < 33; i += 3) { + ctx->key[i ] = K[0]; + R(K[1], K[0], i ); + + if(keysize == 256) { + ctx->key[i+1] = K[0]; + R(K[2], K[0], i + 1); + ctx->key[i+2] = K[0]; + R(K[3], K[0], i + 2); + } else { + // counter the i += 3 to make the loop go one by one in this case + // we can afford the unused 31 and 32 + i -= 2; + } + } + ctx->key[33] = K[0]; + + ctx->keysize = keysize; + + return 1; +} + + +#endif // AVX, SSE, NEON, plain C ------------------------------------------------------------------------ + + +// this functions wraps the call to internal_speck_ctr functions which have slightly different +// signature -- ctx by value for SSE with SPECK_CTX_BYVAL defined in speck.h, by name otherwise +int speck_ctr (unsigned char *out, const unsigned char *in, unsigned long long inlen, + const unsigned char *n, speck_context_t *ctx) { + + return internal_speck_ctr(out, in, inlen, n, +#if defined (SPECK_CTX_BYVAL) + *ctx); +#else + ctx); +#endif +} + + +// create context loaded with round keys ready for use, key size either 128 or 256 (bits) +int speck_init (speck_context_t **ctx, const unsigned char *k, int keysize) { + +#if defined (SPECK_ALIGNED_CTX) + *ctx = (speck_context_t*)_mm_malloc(sizeof(speck_context_t), SPECK_ALIGNED_CTX); +#else + *ctx = (speck_context_t*)calloc(1, sizeof(speck_context_t)); +#endif + if(!(*ctx)) { + return -1; + } + + return speck_expand_key(*ctx, k, keysize); +} + + +int speck_deinit (speck_context_t *ctx) { + + if(ctx) { +#if defined (SPECK_ALIGNED_CTX) + _mm_free(ctx); +#else + free(ctx); +#endif + } + + return 0; +} + + +// ---------------------------------------------------------------------------------------------------------------- + + +// cipher SPECK -- 128 bit block size -- 128 bit key size -- ECB mode (decrypt only) +// follows endianess rules as used in official implementation guide and NOT as in original 2013 cipher presentation +// used for IV in header encryption (one block) and challenge encryption (user/password) +// for now: just plain C -- probably no need for AVX, SSE, NEON + + +#define ROTL64(x,r) (((x)<<(r))|((x)>>(64-(r)))) +#define ROTR64(x,r) (((x)>>(r))|((x)<<(64-(r)))) +#define DR128(x,y,k) (y^=x, y=ROTR64(y,3), x^=k, x-=y, x=ROTL64(x,8)) +#define ER128(x,y,k) (x=(ROTR64(x,8)+y)^k, y=ROTL64(y,3)^x) + +int speck_128_decrypt (unsigned char *inout, speck_context_t *ctx) { + + u64 x, y; + int i; + + x = le64toh( *(u64*)&inout[8] ); + y = le64toh( *(u64*)&inout[0] ); + + for(i = 31; i >= 0; i--) + DR128(x, y, ctx->key[i]); + + ((u64*)inout)[1] = htole64(x); + ((u64*)inout)[0] = htole64(y); + + return 0; +} + + +int speck_128_encrypt (unsigned char *inout, speck_context_t *ctx) { + + u64 x, y; + int i; + + x = le64toh( *(u64*)&inout[8] ); + y = le64toh( *(u64*)&inout[0] ); + + for(i = 0; i < 32; i++) + ER128(x, y, ctx->key[i]); + + ((u64*)inout)[1] = htole64(x); + ((u64*)inout)[0] = htole64(y); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/supernode.c b/bundles/n2n_ntop_v3/src/supernode.c new file mode 100644 index 00000000..7266aab7 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/supernode.c @@ -0,0 +1,674 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/* Supernode for n2n-2.x */ + +#include "n2n.h" +#include "header_encryption.h" + +#define HASH_FIND_COMMUNITY(head, name, out) HASH_FIND_STR(head, name, out) + +static n2n_sn_t sss_node; + +void close_tcp_connection (n2n_sn_t *sss, n2n_tcp_connection_t *conn); +void calculate_shared_secrets (n2n_sn_t *sss); +int load_allowed_sn_community (n2n_sn_t *sss); +int resolve_create_thread (n2n_resolve_parameter_t **param, struct peer_info *sn_list); + + +/** Help message to print if the command line arguments are not valid. */ +static void help (int level) { + + if(level == 0) /* no help required */ + return; + + printf("\n"); + print_n2n_version(); + + if(level == 1) /* short help */ { + + printf(" basic usage: supernode (see supernode.conf)\n" + "\n" + " or supernode " + "[optional parameters, at least one] " + "\n " + "\n technically, all parameters are optional, but the supernode executable" + "\n requires at least one parameter to run, .e.g. -v or -f, as otherwise this" + "\n short help text is displayed" + "\n\n -h shows a quick reference including all available options" + "\n --help gives a detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + + } else if(level == 2) /* quick reference */ { + + printf(" general usage: supernode (see supernode.conf)\n" + "\n" + " or supernode " + "[-p ] " + "\n " + "[-F ] " + "\n options for under- " + "[-l ] " + "\n lying connection " +#ifdef SN_MANUAL_MAC + "[-m ] " +#endif + "[-M] " + "[-V ] " + "\n\n overlay network " + "[-c ] " + "\n configuration " + "[-a -/] " + "\n\n local options " +#if defined(N2N_HAVE_DAEMON) + "[-f] " +#endif + "[-t ] " + "\n " + "[--management-password ] " + "[-v] " +#ifndef WIN32 + "\n " + "[-u ]" + "[-g ]" +#endif + "\n\n meaning of the " + "[-M] disable MAC and IP address spoofing protection" + "\n flag options " +#if defined(N2N_HAVE_DAEMON) + "[-f] do not fork but run in foreground" + "\n " +#endif + "[-v] make more verbose, repeat as required" + "\n " + "\n technically, all parameters are optional, but the supernode executable" + "\n requires at least one parameter to run, .e.g. -v or -f, as otherwise a" + "\n short help text is displayed" + "\n\n -h shows this quick reference including all available options" + "\n --help gives a detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + + } else /* long help */ { + + printf(" general usage: supernode (see supernode.conf)\n" + "\n" + " or supernode [optional parameters, at least one]\n\n" + ); + printf (" OPTIONS FOR THE UNDERLYING NETWORK CONNECTION\n"); + printf (" ---------------------------------------------\n\n"); + printf(" -p | fixed local UDP port, defaults to %u\n", N2N_SN_LPORT_DEFAULT); + printf(" -F | name of the supernode's federation, defaults to\n" + " | '%s'\n", (char *)FEDERATION_NAME); + printf(" -l | ip address or name, and port of known supernode\n"); +#ifdef SN_MANUAL_MAC + printf(" -m | fixed MAC address for the supernode, e.g.\n" + " | '-m 10:20:30:40:50:60', random otherwise\n"); +#endif + printf(" -M | disable MAC and IP address spoofing protection for all\n" + " | non-username-password-authenticating communities\n"); + printf(" -V | sends a custom supernode version string of max 19 letters \n" + " | length to edges, visible in their management port output\n"); + printf ("\n"); + printf (" TAP DEVICE AND OVERLAY NETWORK CONFIGURATION\n"); + printf (" --------------------------------------------\n\n"); + printf(" -c | file containing the allowed communities\n"); + printf(" -a | subnet range for auto ip address service, e.g.\n" + " | '-a 192.168.0.0-192.168.255.0/24', defaults\n" + " | to '10.128.255.0-10.255.255.0/24'\n"); + printf ("\n"); + printf (" LOCAL OPTIONS\n"); + printf (" -------------\n\n"); +#if defined(N2N_HAVE_DAEMON) + printf(" -f | do not fork and run as a daemon, rather run in foreground\n"); +#endif + printf(" -t | management UDP port, for multiple supernodes on a machine,\n" + " | defaults to %u\n", N2N_SN_MGMT_PORT); + printf(" --management_... | management port password, defaults to '%s'\n" + " ...password | \n", N2N_MGMT_PASSWORD); + printf(" -v | make more verbose, repeat as required\n"); +#ifndef WIN32 + printf(" -u | numeric user ID to use when privileges are dropped\n"); + printf(" -g | numeric group ID to use when privileges are dropped\n"); +#endif + printf("\n technically, all parameters are optional, but the supernode executable" + "\n requires at least one parameter to run, .e.g. -v or -f, as otherwise a" + "\n short help text is displayed" + "\n\n -h shows a quick reference including all available options" + "\n --help gives this detailed parameter description" + "\n man files for n2n, edge, and superndode contain in-depth information" + "\n\n"); + } + + exit(0); +} + + +/* *************************************************** */ + +static int setOption (int optkey, char *_optarg, n2n_sn_t *sss) { + + //traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : ""); + + switch(optkey) { + case 'p': /* local-port */ + sss->lport = atoi(_optarg); + + if(sss->lport == 0) + traceEvent(TRACE_WARNING, "bad local port format, defaulting to %u", N2N_SN_LPORT_DEFAULT); + // default is made sure in sn_init() + + break; + + case 't': /* mgmt-port */ + sss->mport = atoi(_optarg); + + if(sss->mport == 0) + traceEvent(TRACE_WARNING, "bad management port format, defaulting to %u", N2N_SN_MGMT_PORT); + // default is made sure in sn_init() + + break; + + case 'l': { /* supernode:port */ + n2n_sock_t *socket; + struct peer_info *anchor_sn; + size_t length; + int rv = -1; + int skip_add; + char *double_column = strchr(_optarg, ':'); + + length = strlen(_optarg); + if(length >= N2N_EDGE_SN_HOST_SIZE) { + traceEvent(TRACE_WARNING, "size of -l argument too long: %zu; maximum size is %d", length, N2N_EDGE_SN_HOST_SIZE); + return 1; + } + + if(!double_column) { + traceEvent(TRACE_WARNING, "invalid -l format, missing port"); + return 1; + } + + socket = (n2n_sock_t *)calloc(1, sizeof(n2n_sock_t)); + rv = supernode2sock(socket, _optarg); + + if(rv < -2) { /* we accept resolver failure as it might resolve later */ + traceEvent(TRACE_WARNING, "invalid supernode parameter"); + free(socket); + return 1; + } + + if(sss->federation != NULL) { + skip_add = SN_ADD; + anchor_sn = add_sn_to_list_by_mac_or_sock(&(sss->federation->edges), socket, null_mac, &skip_add); + + if(anchor_sn != NULL) { + anchor_sn->ip_addr = calloc(1, N2N_EDGE_SN_HOST_SIZE); + if(anchor_sn->ip_addr) { + strncpy(anchor_sn->ip_addr, _optarg, N2N_EDGE_SN_HOST_SIZE - 1); + memcpy(&(anchor_sn->sock), socket, sizeof(n2n_sock_t)); + memcpy(anchor_sn->mac_addr, null_mac, sizeof(n2n_mac_t)); + anchor_sn->purgeable = SN_UNPURGEABLE; + anchor_sn->last_valid_time_stamp = initial_time_stamp(); + } + } + } + + free(socket); + break; + } + + case 'a': { + dec_ip_str_t ip_min_str = {'\0'}; + dec_ip_str_t ip_max_str = {'\0'}; + in_addr_t net_min, net_max; + uint8_t bitlen; + uint32_t mask; + + if(sscanf(_optarg, "%15[^\\-]-%15[^/]/%hhu", ip_min_str, ip_max_str, &bitlen) != 3) { + traceEvent(TRACE_WARNING, "bad net-net/bit format '%s'.", _optarg); + return 2; + } + + net_min = inet_addr(ip_min_str); + net_max = inet_addr(ip_max_str); + mask = bitlen2mask(bitlen); + if((net_min == (in_addr_t)(-1)) || (net_min == INADDR_NONE) || (net_min == INADDR_ANY) + || (net_max == (in_addr_t)(-1)) || (net_max == INADDR_NONE) || (net_max == INADDR_ANY) + || (ntohl(net_min) > ntohl(net_max)) + || ((ntohl(net_min) & ~mask) != 0) || ((ntohl(net_max) & ~mask) != 0)) { + traceEvent(TRACE_WARNING, "bad network range '%s...%s/%u' in '%s', defaulting to '%s...%s/%d'", + ip_min_str, ip_max_str, bitlen, _optarg, + N2N_SN_MIN_AUTO_IP_NET_DEFAULT, N2N_SN_MAX_AUTO_IP_NET_DEFAULT, N2N_SN_AUTO_IP_NET_BIT_DEFAULT); + return 2; + } + + if((bitlen > 30) || (bitlen == 0)) { + traceEvent(TRACE_WARNING, "bad prefix '%hhu' in '%s', defaulting to '%s...%s/%d'", + bitlen, _optarg, + N2N_SN_MIN_AUTO_IP_NET_DEFAULT, N2N_SN_MAX_AUTO_IP_NET_DEFAULT, N2N_SN_AUTO_IP_NET_BIT_DEFAULT); + return 2; + } + + traceEvent(TRACE_NORMAL, "the network range for community ip address service is '%s...%s/%hhu'", ip_min_str, ip_max_str, bitlen); + + sss->min_auto_ip_net.net_addr = ntohl(net_min); + sss->min_auto_ip_net.net_bitlen = bitlen; + sss->max_auto_ip_net.net_addr = ntohl(net_max); + sss->max_auto_ip_net.net_bitlen = bitlen; + + break; + } +#ifndef WIN32 + case 'u': /* unprivileged uid */ + sss->userid = atoi(_optarg); + break; + + case 'g': /* unprivileged uid */ + sss->groupid = atoi(_optarg); + break; +#endif + case 'F': { /* federation name */ + snprintf(sss->federation->community, N2N_COMMUNITY_SIZE - 1 ,"*%s", _optarg); + sss->federation->community[N2N_COMMUNITY_SIZE - 1] = '\0'; + break; + } +#ifdef SN_MANUAL_MAC + case 'm': {/* MAC address */ + str2mac(sss->mac_addr,_optarg); + break; + } +#endif + case 'M': /* override spoofing protection */ + sss->override_spoofing_protection = 1; + break; + + case 'V': /* version text */ + strncpy(sss->version, _optarg, sizeof(n2n_version_t)); + sss->version[sizeof(n2n_version_t) - 1] = '\0'; + break; + case 'c': /* community file */ + sss->community_file = calloc(1, strlen(_optarg) + 1); + if(sss->community_file) + strcpy(sss->community_file, _optarg); + break; + + case ']': /* password for management port */ { + sss->mgmt_password_hash = pearson_hash_64((uint8_t*)_optarg, strlen(_optarg)); + + break; + } +#if defined(N2N_HAVE_DAEMON) + case 'f': /* foreground */ + sss->daemon = 0; + break; +#endif + case 'h': /* quick reference */ + return 2; + + case '@': /* long help */ + return 3; + + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + + default: + traceEvent(TRACE_WARNING, "unknown option -%c:", (char) optkey); + return 2; + } + + return 0; +} + + +/* *********************************************** */ + +static const struct option long_options[] = { + {"communities", required_argument, NULL, 'c'}, +#if defined(N2N_HAVE_DAEMON) + {"foreground", no_argument, NULL, 'f'}, +#endif + {"local-port", required_argument, NULL, 'p'}, + {"mgmt-port", required_argument, NULL, 't'}, + {"autoip", required_argument, NULL, 'a'}, + {"verbose", no_argument, NULL, 'v'}, + {"help", no_argument, NULL, '@'}, /* special character '@' to identify long help case */ + {"management-password", required_argument, NULL, ']' }, /* ']' management port password */ + {NULL, 0, NULL, 0} +}; + +/* *************************************************** */ + +/* read command line options */ +static int loadFromCLI (int argc, char * const argv[], n2n_sn_t *sss) { + + u_char c; + + while((c = getopt_long(argc, argv, + "p:l:t:a:c:F:vhMV:" +#ifdef SN_MANUAL_MAC + "m:" +#endif +#if defined(N2N_HAVE_DAEMON) + "f" +#endif +#ifndef WIN32 + "u:g:" +#endif + , + long_options, NULL)) != '?') { + if(c == 255) { + break; + } + help(setOption(c, optarg, sss)); + } + + return 0; +} + +/* *************************************************** */ + +static char *trim (char *s) { + + char *end; + + while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\'')) { + s++; + } + + if(s[0] == 0) { + return s; + } + + end = &s[strlen(s) - 1]; + while(end > s && (isspace(end[0])|| (end[0] == '"') || (end[0] == '\''))) { + end--; + } + end[1] = 0; + + return s; +} + +/* *************************************************** */ + +/* parse the configuration file */ +static int loadFromFile (const char *path, n2n_sn_t *sss) { + + char buffer[4096], *line; + char *line_vec[3]; + int tmp; + + FILE *fd; + + fd = fopen(path, "r"); + + if(fd == NULL) { + traceEvent(TRACE_WARNING, "config file %s not found", path); + return -1; + } + + // we mess around with optind, better save it + tmp = optind; + + while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) { + line = trim(line); + + if(strlen(line) < 2 || line[0] == '#') { + continue; + } + + // executable, cannot be omitted, content can be anything + line_vec[0] = line; + // first token, e.g. `-p`, eventually followed by a whitespace or '=' delimiter + line_vec[1] = strtok(line, "\t ="); + // separate parameter option, if present + line_vec[2] = strtok(NULL, "\t "); + + // not to duplicate the option parser code, call loadFromCLI and pretend we have no option read yet + optind = 0; + // if separate second token present (optional argument, not part of first), then announce 3 vector members + loadFromCLI(line_vec[2] ? 3 : 2, line_vec, sss); + } + + fclose(fd); + optind = tmp; + + return 0; +} + +/* *************************************************** */ + +/* Add the federation to the communities list of a supernode */ +static int add_federation_to_communities (n2n_sn_t *sss) { + + uint32_t num_communities = 0; + + if(sss->federation != NULL) { + HASH_ADD_STR(sss->communities, community, sss->federation); + + num_communities = HASH_COUNT(sss->communities); + + traceEvent(TRACE_INFO, "added federation '%s' to the list of communities [total: %u]", + (char*)sss->federation->community, num_communities); + } + + return 0; +} + +/* *************************************************** */ + +#ifdef __linux__ +static void dump_registrations (int signo) { + + struct sn_community *comm, *ctmp; + struct peer_info *list, *tmp; + char buf[32]; + time_t now = time(NULL); + u_int num = 0; + + traceEvent(TRACE_NORMAL, "===================================="); + + HASH_ITER(hh, sss_node.communities, comm, ctmp) { + traceEvent(TRACE_NORMAL, "dumping community: %s", comm->community); + + HASH_ITER(hh, comm->edges, list, tmp) { + if(list->sock.family == AF_INET) { + traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][last seen: %u sec ago]", + ++num, macaddr_str(buf, list->mac_addr), + list->sock.addr.v4[0], list->sock.addr.v4[1], list->sock.addr.v4[2], list->sock.addr.v4[3], + list->sock.port, + now - list->last_seen); + } else { + traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: IPv6:%u][last seen: %u sec ago]", + ++num, macaddr_str(buf, list->mac_addr), list->sock.port, + now - list->last_seen); + } + } + } + + traceEvent(TRACE_NORMAL, "===================================="); +} +#endif + +/* *************************************************** */ + +static int keep_running; + +#if defined(__linux__) || defined(WIN32) +#ifdef WIN32 +BOOL WINAPI term_handler (DWORD sig) +#else + static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "ok, I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "shutting down..."); + called = 1; + } + + keep_running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} +#endif /* defined(__linux__) || defined(WIN32) */ + +/* *************************************************** */ + +/** Main program entry point from kernel. */ +int main (int argc, char * const argv[]) { + + int rc; +#ifndef WIN32 + struct passwd *pw = NULL; +#endif + struct peer_info *scan, *tmp; + + + sn_init_defaults(&sss_node); + add_federation_to_communities(&sss_node); + + if((argc >= 2) && (argv[1][0] != '-')) { + rc = loadFromFile(argv[1], &sss_node); + if(argc > 2) { + rc = loadFromCLI(argc, argv, &sss_node); + } + } else if(argc > 1) { + rc = loadFromCLI(argc, argv, &sss_node); + } else + +#ifdef WIN32 + // load from current directory + rc = loadFromFile("supernode.conf", &sss_node); +#else + rc = -1; +#endif + + if(rc < 0) { + help(1); /* short help */ + } + + if(sss_node.community_file) + load_allowed_sn_community(&sss_node); + +#if defined(N2N_HAVE_DAEMON) + if(sss_node.daemon) { + setUseSyslog(1); /* traceEvent output now goes to syslog. */ + + if(-1 == daemon(0, 0)) { + traceEvent(TRACE_ERROR, "failed to become daemon"); + exit(-5); + } + } +#endif /* #if defined(N2N_HAVE_DAEMON) */ + + // warn on default federation name + if(!strcmp(sss_node.federation->community, FEDERATION_NAME)) { + traceEvent(TRACE_WARNING, "using default federation name; FOR TESTING ONLY, usage of a custom federation name (-F) is highly recommended!"); + } + + if(sss_node.override_spoofing_protection) { + traceEvent(TRACE_WARNING, "disabled MAC and IP address spoofing protection; FOR TESTING ONLY, usage of user-password authentication (-I, -J, -P) recommended instead!"); + } + + calculate_shared_secrets(&sss_node); + + traceEvent(TRACE_DEBUG, "traceLevel is %d", getTraceLevel()); + + sss_node.sock = open_socket(sss_node.lport, INADDR_ANY, 0 /* UDP */); + if(-1 == sss_node.sock) { + traceEvent(TRACE_ERROR, "failed to open main socket. %s", strerror(errno)); + exit(-2); + } else { + traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (main)", sss_node.lport); + } + +#ifdef N2N_HAVE_TCP + sss_node.tcp_sock = open_socket(sss_node.lport, INADDR_ANY, 1 /* TCP */); + if(-1 == sss_node.tcp_sock) { + traceEvent(TRACE_ERROR, "failed to open auxiliary TCP socket, %s", strerror(errno)); + exit(-2); + } else { + traceEvent(TRACE_NORMAL, "supernode opened TCP %u (aux)", sss_node.lport); + } + + if(-1 == listen(sss_node.tcp_sock, N2N_TCP_BACKLOG_QUEUE_SIZE)) { + traceEvent(TRACE_ERROR, "failed to listen on auxiliary TCP socket, %s", strerror(errno)); + exit(-2); + } else { + traceEvent(TRACE_NORMAL, "supernode is listening on TCP %u (aux)", sss_node.lport); + } +#endif + + sss_node.mgmt_sock = open_socket(sss_node.mport, INADDR_LOOPBACK, 0 /* UDP */); + if(-1 == sss_node.mgmt_sock) { + traceEvent(TRACE_ERROR, "failed to open management socket, %s", strerror(errno)); + exit(-2); + } else { + traceEvent(TRACE_NORMAL, "supernode is listening on UDP %u (management)", sss_node.mport); + } + + HASH_ITER(hh, sss_node.federation->edges, scan, tmp) + scan->socket_fd = sss_node.sock; + +#ifndef WIN32 + if(((pw = getpwnam ("n2n")) != NULL) || ((pw = getpwnam ("nobody")) != NULL)) { + sss_node.userid = sss_node.userid == 0 ? pw->pw_uid : 0; + sss_node.groupid = sss_node.groupid == 0 ? pw->pw_gid : 0; + } + if((sss_node.userid != 0) || (sss_node.groupid != 0)) { + traceEvent(TRACE_NORMAL, "dropping privileges to uid=%d, gid=%d", + (signed int)sss_node.userid, (signed int)sss_node.groupid); + + /* Finished with the need for root privileges. Drop to unprivileged user. */ + if((setgid(sss_node.groupid) != 0) + || (setuid(sss_node.userid) != 0)) { + traceEvent(TRACE_ERROR, "unable to drop privileges [%u/%s]", errno, strerror(errno)); + exit(1); + } + } + + if((getuid() == 0) || (getgid() == 0)) { + traceEvent(TRACE_WARNING, "running as root is discouraged, check out the -u/-g options"); + } +#endif + + sn_init(&sss_node); + + traceEvent(TRACE_NORMAL, "supernode started"); + +#ifdef __linux__ + signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); + signal(SIGHUP, dump_registrations); +#endif +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#endif + + keep_running = 1; + sss_node.keep_running = &keep_running; + return run_sn_loop(&sss_node); +} diff --git a/bundles/n2n_ntop_v3/src/tf.c b/bundles/n2n_ntop_v3/src/tf.c new file mode 100644 index 00000000..418ba4e8 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/tf.c @@ -0,0 +1,619 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +// taken (and modified) from github/fudanchii/twofish as of August 2020 +// which itself is a modified copy of Andrew T. Csillag's implementation +// published on github/drewcsillag/twofish + + +/** + * The MIT License (MIT) + * + * Copyright (c) 2015 Andrew T. Csillag + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "tf.h" + + +const uint8_t RS[4][8] = { { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, }, + { 0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5, }, + { 0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19, }, + { 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03 } }; + +const uint8_t Q0[] = { 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, + 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, + 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, + 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, + 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, + 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, + 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, + 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, + 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 }; + +const uint8_t Q1[] = { 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, + 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, + 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, + 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, + 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, + 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, + 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, + 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, + 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, + 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 }; + +const uint8_t mult5B[] = { 0x00, 0x5B, 0xB6, 0xED, 0x05, 0x5E, 0xB3, 0xE8, 0x0A, 0x51, 0xBC, 0xE7, 0x0F, 0x54, 0xB9, 0xE2, + 0x14, 0x4F, 0xA2, 0xF9, 0x11, 0x4A, 0xA7, 0xFC, 0x1E, 0x45, 0xA8, 0xF3, 0x1B, 0x40, 0xAD, 0xF6, + 0x28, 0x73, 0x9E, 0xC5, 0x2D, 0x76, 0x9B, 0xC0, 0x22, 0x79, 0x94, 0xCF, 0x27, 0x7C, 0x91, 0xCA, + 0x3C, 0x67, 0x8A, 0xD1, 0x39, 0x62, 0x8F, 0xD4, 0x36, 0x6D, 0x80, 0xDB, 0x33, 0x68, 0x85, 0xDE, + 0x50, 0x0B, 0xE6, 0xBD, 0x55, 0x0E, 0xE3, 0xB8, 0x5A, 0x01, 0xEC, 0xB7, 0x5F, 0x04, 0xE9, 0xB2, + 0x44, 0x1F, 0xF2, 0xA9, 0x41, 0x1A, 0xF7, 0xAC, 0x4E, 0x15, 0xF8, 0xA3, 0x4B, 0x10, 0xFD, 0xA6, + 0x78, 0x23, 0xCE, 0x95, 0x7D, 0x26, 0xCB, 0x90, 0x72, 0x29, 0xC4, 0x9F, 0x77, 0x2C, 0xC1, 0x9A, + 0x6C, 0x37, 0xDA, 0x81, 0x69, 0x32, 0xDF, 0x84, 0x66, 0x3D, 0xD0, 0x8B, 0x63, 0x38, 0xD5, 0x8E, + 0xA0, 0xFB, 0x16, 0x4D, 0xA5, 0xFE, 0x13, 0x48, 0xAA, 0xF1, 0x1C, 0x47, 0xAF, 0xF4, 0x19, 0x42, + 0xB4, 0xEF, 0x02, 0x59, 0xB1, 0xEA, 0x07, 0x5C, 0xBE, 0xE5, 0x08, 0x53, 0xBB, 0xE0, 0x0D, 0x56, + 0x88, 0xD3, 0x3E, 0x65, 0x8D, 0xD6, 0x3B, 0x60, 0x82, 0xD9, 0x34, 0x6F, 0x87, 0xDC, 0x31, 0x6A, + 0x9C, 0xC7, 0x2A, 0x71, 0x99, 0xC2, 0x2F, 0x74, 0x96, 0xCD, 0x20, 0x7B, 0x93, 0xC8, 0x25, 0x7E, + 0xF0, 0xAB, 0x46, 0x1D, 0xF5, 0xAE, 0x43, 0x18, 0xFA, 0xA1, 0x4C, 0x17, 0xFF, 0xA4, 0x49, 0x12, + 0xE4, 0xBF, 0x52, 0x09, 0xE1, 0xBA, 0x57, 0x0C, 0xEE, 0xB5, 0x58, 0x03, 0xEB, 0xB0, 0x5D, 0x06, + 0xD8, 0x83, 0x6E, 0x35, 0xDD, 0x86, 0x6B, 0x30, 0xD2, 0x89, 0x64, 0x3F, 0xD7, 0x8C, 0x61, 0x3A, + 0xCC, 0x97, 0x7A, 0x21, 0xC9, 0x92, 0x7F, 0x24, 0xC6, 0x9D, 0x70, 0x2B, 0xC3, 0x98, 0x75, 0x2E }; + +const uint8_t multEF[] = { 0x00, 0xEF, 0xB7, 0x58, 0x07, 0xE8, 0xB0, 0x5F, 0x0E, 0xE1, 0xB9, 0x56, 0x09, 0xE6, 0xBE, 0x51, + 0x1C, 0xF3, 0xAB, 0x44, 0x1B, 0xF4, 0xAC, 0x43, 0x12, 0xFD, 0xA5, 0x4A, 0x15, 0xFA, 0xA2, 0x4D, + 0x38, 0xD7, 0x8F, 0x60, 0x3F, 0xD0, 0x88, 0x67, 0x36, 0xD9, 0x81, 0x6E, 0x31, 0xDE, 0x86, 0x69, + 0x24, 0xCB, 0x93, 0x7C, 0x23, 0xCC, 0x94, 0x7B, 0x2A, 0xC5, 0x9D, 0x72, 0x2D, 0xC2, 0x9A, 0x75, + 0x70, 0x9F, 0xC7, 0x28, 0x77, 0x98, 0xC0, 0x2F, 0x7E, 0x91, 0xC9, 0x26, 0x79, 0x96, 0xCE, 0x21, + 0x6C, 0x83, 0xDB, 0x34, 0x6B, 0x84, 0xDC, 0x33, 0x62, 0x8D, 0xD5, 0x3A, 0x65, 0x8A, 0xD2, 0x3D, + 0x48, 0xA7, 0xFF, 0x10, 0x4F, 0xA0, 0xF8, 0x17, 0x46, 0xA9, 0xF1, 0x1E, 0x41, 0xAE, 0xF6, 0x19, + 0x54, 0xBB, 0xE3, 0x0C, 0x53, 0xBC, 0xE4, 0x0B, 0x5A, 0xB5, 0xED, 0x02, 0x5D, 0xB2, 0xEA, 0x05, + 0xE0, 0x0F, 0x57, 0xB8, 0xE7, 0x08, 0x50, 0xBF, 0xEE, 0x01, 0x59, 0xB6, 0xE9, 0x06, 0x5E, 0xB1, + 0xFC, 0x13, 0x4B, 0xA4, 0xFB, 0x14, 0x4C, 0xA3, 0xF2, 0x1D, 0x45, 0xAA, 0xF5, 0x1A, 0x42, 0xAD, + 0xD8, 0x37, 0x6F, 0x80, 0xDF, 0x30, 0x68, 0x87, 0xD6, 0x39, 0x61, 0x8E, 0xD1, 0x3E, 0x66, 0x89, + 0xC4, 0x2B, 0x73, 0x9C, 0xC3, 0x2C, 0x74, 0x9B, 0xCA, 0x25, 0x7D, 0x92, 0xCD, 0x22, 0x7A, 0x95, + 0x90, 0x7F, 0x27, 0xC8, 0x97, 0x78, 0x20, 0xCF, 0x9E, 0x71, 0x29, 0xC6, 0x99, 0x76, 0x2E, 0xC1, + 0x8C, 0x63, 0x3B, 0xD4, 0x8B, 0x64, 0x3C, 0xD3, 0x82, 0x6D, 0x35, 0xDA, 0x85, 0x6A, 0x32, 0xDD, + 0xA8, 0x47, 0x1F, 0xF0, 0xAF, 0x40, 0x18, 0xF7, 0xA6, 0x49, 0x11, 0xFE, 0xA1, 0x4E, 0x16, 0xF9, + 0xB4, 0x5B, 0x03, 0xEC, 0xB3, 0x5C, 0x04, 0xEB, 0xBA, 0x55, 0x0D, 0xE2, 0xBD, 0x52, 0x0A, 0xE5 }; + + +#define RS_MOD 0x14D +#define RHO 0x01010101L + +#define ROL(x,n) (((x) << ((n) & 0x1F)) | ((x) >> (32-((n) & 0x1F)))) +#define ROR(x,n) (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F)))) + +#define _b(x, N) (((x) >> (N*8)) & 0xFF) + +#define b0(x) ((uint8_t)(x)) +#define b1(x) ((uint8_t)((x) >> 8)) +#define b2(x) ((uint8_t)((x) >> 16)) +#define b3(x) ((uint8_t)((x) >> 24)) + +#define U8ARRAY_TO_U32(r) ((r[0] << 24) ^ (r[1] << 16) ^ (r[2] << 8) ^ r[3]) +#define U8S_TO_U32(r0, r1, r2, r3) ((r0 << 24) ^ (r1 << 16) ^ (r2 << 8) ^ r3) + + +// multiply two polynomials represented as u32's, actually called with bytes +uint32_t polyMult(uint32_t a, uint32_t b) { + + uint32_t t=0; + + while(a) { + if(a & 1) + t^=b; + b <<= 1; + a >>= 1; + } + + return t; +} + + +// take the polynomial t and return the t % modulus in GF(256) +uint32_t gfMod(uint32_t t, uint32_t modulus) { + + int i; + uint32_t tt; + + modulus <<= 7; + for(i = 0; i < 8; i++) { + tt = t ^ modulus; + if(tt < t) + t = tt; + modulus >>= 1; + } + + return t; +} + + +// multiply a and b and return the modulus +#define gfMult(a, b, modulus) gfMod(polyMult(a, b), modulus) + + +// return a u32 containing the result of multiplying the RS Code matrix by the sd matrix +uint32_t RSMatrixMultiply(uint8_t sd[8]) { + + int j, k; + uint8_t t; + uint8_t result[4]; + + for(j = 0; j < 4; j++) { + t = 0; + for(k = 0; k < 8; k++) { + t ^= gfMult(RS[j][k], sd[k], RS_MOD); + } + result[3-j] = t; + } + + return U8ARRAY_TO_U32(result); +} + + +// the Zero-keyed h function (used by the key setup routine) +uint32_t h(uint32_t X, uint32_t L[4], int k) { + + uint8_t y0, y1, y2, y3; + uint8_t z0, z1, z2, z3; + + y0 = b0(X); + y1 = b1(X); + y2 = b2(X); + y3 = b3(X); + + switch(k) { + case 4: + y0 = Q1[y0] ^ b0(L[3]); + y1 = Q0[y1] ^ b1(L[3]); + y2 = Q0[y2] ^ b2(L[3]); + y3 = Q1[y3] ^ b3(L[3]); + case 3: + y0 = Q1[y0] ^ b0(L[2]); + y1 = Q1[y1] ^ b1(L[2]); + y2 = Q0[y2] ^ b2(L[2]); + y3 = Q0[y3] ^ b3(L[2]); + case 2: + y0 = Q1[ Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ]; + y1 = Q0[ Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ]; + y2 = Q1[ Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ]; + y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ]; + } + + // inline the MDS matrix multiply + z0 = multEF[y0] ^ y1 ^ multEF[y2] ^ mult5B[y3]; + z1 = multEF[y0] ^ mult5B[y1] ^ y2 ^ multEF[y3]; + z2 = mult5B[y0] ^ multEF[y1] ^ multEF[y2] ^ y3; + z3 = y0 ^ multEF[y1] ^ mult5B[y2] ^ mult5B[y3]; + + return U8S_TO_U32(z0, z1, z2, z3); +} + + +// given the Sbox keys, create the fully keyed QF +void fullKey(uint32_t L[4], int k, uint32_t QF[4][256]) { + + uint8_t y0, y1, y2, y3; + int i; + + // for all input values to the Q permutations + for(i = 0; i < 256; i++) { + // run the Q permutations + y0 = i; y1 = i; y2 = i; y3 = i; + switch(k) { + case 4: + y0 = Q1[y0] ^ b0(L[3]); + y1 = Q0[y1] ^ b1(L[3]); + y2 = Q0[y2] ^ b2(L[3]); + y3 = Q1[y3] ^ b3(L[3]); + case 3: + y0 = Q1[y0] ^ b0(L[2]); + y1 = Q1[y1] ^ b1(L[2]); + y2 = Q0[y2] ^ b2(L[2]); + y3 = Q0[y3] ^ b3(L[2]); + case 2: + y0 = Q1[ Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ]; + y1 = Q0[ Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ]; + y2 = Q1[ Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ]; + y3 = Q0[ Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ]; + } + + // now do the partial MDS matrix multiplies + QF[0][i] = ((multEF[y0] << 24) + | (multEF[y0] << 16) + | (mult5B[y0] << 8) + | y0); + QF[1][i] = ((y1 << 24) + | (mult5B[y1] << 16) + | (multEF[y1] << 8) + | multEF[y1]); + QF[2][i] = ((multEF[y2] << 24) + | (y2 << 16) + | (multEF[y2] << 8) + | mult5B[y2]); + QF[3][i] = ((mult5B[y3] << 24) + | (multEF[y3] << 16) + | (y3 << 8) + | mult5B[y3]); + } +} + +// ---------------------------------------------------------------------------------------------------------------- + + +// fully keyed h (aka g) function +#define fkh(X) (ctx->QF[0][b0(X)]^ctx->QF[1][b1(X)]^ctx->QF[2][b2(X)]^ctx->QF[3][b3(X)]) + + +// ---------------------------------------------------------------------------------------------------------------- + + +// one encryption round +#define ENC_ROUND(R0, R1, R2, R3, round) \ + T0 = fkh(R0); \ + T1 = fkh(ROL(R1, 8)); \ + R2 = ROR(R2 ^ (T1 + T0 + ctx->K[2*round+8]), 1); \ + R3 = ROL(R3, 1) ^ (2*T1 + T0 + ctx->K[2*round+9]); + + +void twofish_internal_encrypt(uint8_t PT[16], tf_context_t *ctx) { + + uint32_t R0, R1, R2, R3; + uint32_t T0, T1; + + // load/byteswap/whiten input + R3 = ctx->K[3] ^ le32toh(((uint32_t*)PT)[3]); + R2 = ctx->K[2] ^ le32toh(((uint32_t*)PT)[2]); + R1 = ctx->K[1] ^ le32toh(((uint32_t*)PT)[1]); + R0 = ctx->K[0] ^ le32toh(((uint32_t*)PT)[0]); + + ENC_ROUND(R0, R1, R2, R3, 0); + ENC_ROUND(R2, R3, R0, R1, 1); + ENC_ROUND(R0, R1, R2, R3, 2); + ENC_ROUND(R2, R3, R0, R1, 3); + ENC_ROUND(R0, R1, R2, R3, 4); + ENC_ROUND(R2, R3, R0, R1, 5); + ENC_ROUND(R0, R1, R2, R3, 6); + ENC_ROUND(R2, R3, R0, R1, 7); + ENC_ROUND(R0, R1, R2, R3, 8); + ENC_ROUND(R2, R3, R0, R1, 9); + ENC_ROUND(R0, R1, R2, R3, 10); + ENC_ROUND(R2, R3, R0, R1, 11); + ENC_ROUND(R0, R1, R2, R3, 12); + ENC_ROUND(R2, R3, R0, R1, 13); + ENC_ROUND(R0, R1, R2, R3, 14); + ENC_ROUND(R2, R3, R0, R1, 15); + + // whiten/byteswap/store output + ((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[7]); + ((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[6]); + ((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[5]); + ((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[4]); +} + + +// ---------------------------------------------------------------------------------------------------------------- + + +// one decryption round +#define DEC_ROUND(R0, R1, R2, R3, round) \ + T0 = fkh(R0); \ + T1 = fkh(ROL(R1, 8)); \ + R2 = ROL(R2, 1) ^ (T0 + T1 + ctx->K[2*round+8]); \ + R3 = ROR(R3 ^ (T0 + 2*T1 + ctx->K[2*round+9]), 1); + + +void twofish_internal_decrypt(uint8_t PT[16], const uint8_t CT[16], tf_context_t *ctx) { + + uint32_t T0, T1; + uint32_t R0, R1, R2, R3; + + // load/byteswap/whiten input + R3 = ctx->K[7] ^ le32toh(((uint32_t*)CT)[3]); + R2 = ctx->K[6] ^ le32toh(((uint32_t*)CT)[2]); + R1 = ctx->K[5] ^ le32toh(((uint32_t*)CT)[1]); + R0 = ctx->K[4] ^ le32toh(((uint32_t*)CT)[0]); + + DEC_ROUND(R0, R1, R2, R3, 15); + DEC_ROUND(R2, R3, R0, R1, 14); + DEC_ROUND(R0, R1, R2, R3, 13); + DEC_ROUND(R2, R3, R0, R1, 12); + DEC_ROUND(R0, R1, R2, R3, 11); + DEC_ROUND(R2, R3, R0, R1, 10); + DEC_ROUND(R0, R1, R2, R3, 9); + DEC_ROUND(R2, R3, R0, R1, 8); + DEC_ROUND(R0, R1, R2, R3, 7); + DEC_ROUND(R2, R3, R0, R1, 6); + DEC_ROUND(R0, R1, R2, R3, 5); + DEC_ROUND(R2, R3, R0, R1, 4); + DEC_ROUND(R0, R1, R2, R3, 3); + DEC_ROUND(R2, R3, R0, R1, 2); + DEC_ROUND(R0, R1, R2, R3, 1); + DEC_ROUND(R2, R3, R0, R1, 0); + + // whiten/byteswap/store output + ((uint32_t*)PT)[3] = htole32(R1 ^ ctx->K[3]); + ((uint32_t*)PT)[2] = htole32(R0 ^ ctx->K[2]); + ((uint32_t*)PT)[1] = htole32(R3 ^ ctx->K[1]); + ((uint32_t*)PT)[0] = htole32(R2 ^ ctx->K[0]); +} + + +// ------------------------------------------------------------------------------------- + + +// the key schedule routine +void keySched(const uint8_t M[], int N, uint32_t **S, uint32_t K[40], int *k) { + + uint32_t Mo[4], Me[4]; + int i, j; + uint8_t vector[8]; + uint32_t A, B; + + *k = (N + 63) / 64; + *S = (uint32_t*)malloc(sizeof(uint32_t) * (*k)); + + for(i = 0; i < *k; i++) { + Me[i] = le32toh(((uint32_t*)M)[2*i]); + Mo[i] = le32toh(((uint32_t*)M)[2*i+1]); + } + + for(i = 0; i < *k; i++) { + for(j = 0; j < 4; j++) + vector[j] = _b(Me[i], j); + for(j = 0; j < 4; j++) + vector[j+4] = _b(Mo[i], j); + (*S)[(*k)-i-1] = RSMatrixMultiply(vector); + } + + for(i = 0; i < 20; i++) { + A = h(2*i*RHO, Me, *k); + B = ROL(h(2*i*RHO + RHO, Mo, *k), 8); + K[2*i] = A+B; + K[2*i+1] = ROL(A + 2*B, 9); + } +} + + +// ---------------------------------------------------------------------------------------------------------------- + + +#define fix_xor(target, source) *(uint32_t*)&(target)[0] = *(uint32_t*)&(target)[0] ^ *(uint32_t*)&(source)[0]; *(uint32_t*)&(target)[4] = *(uint32_t*)&(target)[4] ^ *(uint32_t*)&(source)[4]; \ + *(uint32_t*)&(target)[8] = *(uint32_t*)&(target)[8] ^ *(uint32_t*)&(source)[8]; *(uint32_t*)&(target)[12] = *(uint32_t*)&(target)[12] ^ *(uint32_t*)&(source)[12]; + +// ---------------------------------------------------------------------------------------------------------------- + + +// public API + + +int tf_ecb_decrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) { + + twofish_internal_decrypt(out, in, ctx); + + return TF_BLOCK_SIZE; +} + + +// not used +int tf_ecb_encrypt (unsigned char *out, const unsigned char *in, tf_context_t *ctx) { + + memcpy(out, in, TF_BLOCK_SIZE); + twofish_internal_encrypt(out, ctx); + + return TF_BLOCK_SIZE; +} + + +int tf_cbc_encrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, tf_context_t *ctx) { + + uint8_t tmp[TF_BLOCK_SIZE]; + size_t i; + size_t n; + + memcpy(tmp, iv, TF_BLOCK_SIZE); + + n = in_len / TF_BLOCK_SIZE; + for(i = 0; i < n; i++) { + fix_xor(tmp, &in[i * TF_BLOCK_SIZE]); + twofish_internal_encrypt(tmp, ctx); + memcpy(&out[i * TF_BLOCK_SIZE], tmp, TF_BLOCK_SIZE); + } + + return n * TF_BLOCK_SIZE; +} + + +int tf_cbc_decrypt (unsigned char *out, const unsigned char *in, size_t in_len, + const unsigned char *iv, tf_context_t *ctx) { + + int n; /* number of blocks */ + /* int ret = (int)in_len & 15; remainder, unused*/ + + uint8_t ivec[TF_BLOCK_SIZE]; /* the ivec/old handling might be optimized if we */ + uint8_t old[TF_BLOCK_SIZE]; /* can be sure that in != out */ + + memcpy(ivec, iv, TF_BLOCK_SIZE); + + // 3 parallel rails of twofish decryption + for(n = in_len / TF_BLOCK_SIZE; n > 2; n -=3) { + memcpy(old, in + 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE); + + uint32_t T0, T1; + uint32_t Q0, Q1, Q2, Q3, R0, R1, R2, R3, S0, S1, S2, S3; + + // load/byteswap/whiten input/iv + Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]); + Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]); + Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]); + Q0 = ctx->K[4] ^ le32toh(((uint32_t*)in)[0]); + + R3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[7]); + R2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[6]); + R1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[5]); + R0 = ctx->K[4] ^ le32toh(((uint32_t*)in)[4]); + + S3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[11]); + S2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[10]); + S1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[9]); + S0 = ctx->K[4] ^ le32toh(((uint32_t*)in)[8]); + + DEC_ROUND(Q0, Q1, Q2, Q3, 15); DEC_ROUND(R0, R1, R2, R3, 15); DEC_ROUND(S0, S1, S2, S3, 15); + DEC_ROUND(Q2, Q3, Q0, Q1, 14); DEC_ROUND(R2, R3, R0, R1, 14); DEC_ROUND(S2, S3, S0, S1, 14); + DEC_ROUND(Q0, Q1, Q2, Q3, 13); DEC_ROUND(R0, R1, R2, R3, 13); DEC_ROUND(S0, S1, S2, S3, 13); + DEC_ROUND(Q2, Q3, Q0, Q1, 12); DEC_ROUND(R2, R3, R0, R1, 12); DEC_ROUND(S2, S3, S0, S1, 12); + DEC_ROUND(Q0, Q1, Q2, Q3, 11); DEC_ROUND(R0, R1, R2, R3, 11); DEC_ROUND(S0, S1, S2, S3, 11); + DEC_ROUND(Q2, Q3, Q0, Q1, 10); DEC_ROUND(R2, R3, R0, R1, 10); DEC_ROUND(S2, S3, S0, S1, 10); + DEC_ROUND(Q0, Q1, Q2, Q3, 9); DEC_ROUND(R0, R1, R2, R3, 9); DEC_ROUND(S0, S1, S2, S3, 9); + DEC_ROUND(Q2, Q3, Q0, Q1, 8); DEC_ROUND(R2, R3, R0, R1, 8); DEC_ROUND(S2, S3, S0, S1, 8); + DEC_ROUND(Q0, Q1, Q2, Q3, 7); DEC_ROUND(R0, R1, R2, R3, 7); DEC_ROUND(S0, S1, S2, S3, 7); + DEC_ROUND(Q2, Q3, Q0, Q1, 6); DEC_ROUND(R2, R3, R0, R1, 6); DEC_ROUND(S2, S3, S0, S1, 6); + DEC_ROUND(Q0, Q1, Q2, Q3, 5); DEC_ROUND(R0, R1, R2, R3, 5); DEC_ROUND(S0, S1, S2, S3, 5); + DEC_ROUND(Q2, Q3, Q0, Q1, 4); DEC_ROUND(R2, R3, R0, R1, 4); DEC_ROUND(S2, S3, S0, S1, 4); + DEC_ROUND(Q0, Q1, Q2, Q3, 3); DEC_ROUND(R0, R1, R2, R3, 3); DEC_ROUND(S0, S1, S2, S3, 3); + DEC_ROUND(Q2, Q3, Q0, Q1, 2); DEC_ROUND(R2, R3, R0, R1, 2); DEC_ROUND(S2, S3, S0, S1, 2); + DEC_ROUND(Q0, Q1, Q2, Q3, 1); DEC_ROUND(R0, R1, R2, R3, 1); DEC_ROUND(S0, S1, S2, S3, 1); + DEC_ROUND(Q2, Q3, Q0, Q1, 0); DEC_ROUND(R2, R3, R0, R1, 0); DEC_ROUND(S2, S3, S0, S1, 0); + + // whiten/byteswap/store output/iv + ((uint32_t*)out)[11] = htole32(S1 ^ ctx->K[3] ^ ((uint32_t*)in)[7]); + ((uint32_t*)out)[10] = htole32(S0 ^ ctx->K[2] ^ ((uint32_t*)in)[6]); + ((uint32_t*)out)[9] = htole32(S3 ^ ctx->K[1] ^ ((uint32_t*)in)[5]); + ((uint32_t*)out)[8] = htole32(S2 ^ ctx->K[0] ^ ((uint32_t*)in)[4]); + + ((uint32_t*)out)[7] = htole32(R1 ^ ctx->K[3] ^ ((uint32_t*)in)[3]); + ((uint32_t*)out)[6] = htole32(R0 ^ ctx->K[2] ^ ((uint32_t*)in)[2]); + ((uint32_t*)out)[5] = htole32(R3 ^ ctx->K[1] ^ ((uint32_t*)in)[1]); + ((uint32_t*)out)[4] = htole32(R2 ^ ctx->K[0] ^ ((uint32_t*)in)[0]); + + ((uint32_t*)out)[3] = htole32(Q1 ^ ctx->K[3] ^ ((uint32_t*)ivec)[3]); + ((uint32_t*)out)[2] = htole32(Q0 ^ ctx->K[2] ^ ((uint32_t*)ivec)[2]); + ((uint32_t*)out)[1] = htole32(Q3 ^ ctx->K[1] ^ ((uint32_t*)ivec)[1]); + ((uint32_t*)out)[0] = htole32(Q2 ^ ctx->K[0] ^ ((uint32_t*)ivec)[0]); + + in += 3 * TF_BLOCK_SIZE; out += 3 * TF_BLOCK_SIZE; + + memcpy(ivec, old, TF_BLOCK_SIZE); + } + + // handle the two or less remaining block on a single rail + for(; n != 0; n--) { + uint32_t T0, T1; + uint32_t Q0, Q1, Q2, Q3; + + memcpy(old, in, TF_BLOCK_SIZE); + + // load/byteswap/whiten input + Q3 = ctx->K[7] ^ le32toh(((uint32_t*)in)[3]); + Q2 = ctx->K[6] ^ le32toh(((uint32_t*)in)[2]); + Q1 = ctx->K[5] ^ le32toh(((uint32_t*)in)[1]); + Q0 = ctx->K[4] ^ le32toh(((uint32_t*)in)[0]); + + DEC_ROUND(Q0, Q1, Q2, Q3, 15); + DEC_ROUND(Q2, Q3, Q0, Q1, 14); + DEC_ROUND(Q0, Q1, Q2, Q3, 13); + DEC_ROUND(Q2, Q3, Q0, Q1, 12); + DEC_ROUND(Q0, Q1, Q2, Q3, 11); + DEC_ROUND(Q2, Q3, Q0, Q1, 10); + DEC_ROUND(Q0, Q1, Q2, Q3, 9); + DEC_ROUND(Q2, Q3, Q0, Q1, 8); + DEC_ROUND(Q0, Q1, Q2, Q3, 7); + DEC_ROUND(Q2, Q3, Q0, Q1, 6); + DEC_ROUND(Q0, Q1, Q2, Q3, 5); + DEC_ROUND(Q2, Q3, Q0, Q1, 4); + DEC_ROUND(Q0, Q1, Q2, Q3, 3); + DEC_ROUND(Q2, Q3, Q0, Q1, 2); + DEC_ROUND(Q0, Q1, Q2, Q3, 1); + DEC_ROUND(Q2, Q3, Q0, Q1, 0); + + // load/byteswap/whiten output/iv + ((uint32_t*)out)[3] = htole32(Q1 ^ ctx->K[3] ^ ((uint32_t*)ivec)[3]); + ((uint32_t*)out)[2] = htole32(Q0 ^ ctx->K[2] ^ ((uint32_t*)ivec)[2]); + ((uint32_t*)out)[1] = htole32(Q3 ^ ctx->K[1] ^ ((uint32_t*)ivec)[1]); + ((uint32_t*)out)[0] = htole32(Q2 ^ ctx->K[0] ^ ((uint32_t*)ivec)[0]); + + in += TF_BLOCK_SIZE; out+= TF_BLOCK_SIZE; + + memcpy(ivec, old, TF_BLOCK_SIZE); + } + + return n * TF_BLOCK_SIZE; +} + + +// by definition twofish can only accept key up to 256 bit +// we wont do any checking here and will assume user already +// know about it. twofish is undefined for key larger than 256 bit +int tf_init (const unsigned char *key, size_t key_size, tf_context_t **ctx) { + + int k; + uint32_t *S; + + *ctx = calloc(1, sizeof(tf_context_t)); + if(!(*ctx)) { + return -1; + } + + (*ctx)->N = key_size; + keySched(key, key_size, &S, (*ctx)->K, &k); + fullKey(S, k, (*ctx)->QF); + free(S); /* allocated in keySched(...) */ + + return 0; +} + + +int tf_deinit (tf_context_t *ctx) { + + if(ctx) free(ctx); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/transform_aes.c b/bundles/n2n_ntop_v3/src/transform_aes.c new file mode 100644 index 00000000..9a7406ac --- /dev/null +++ b/bundles/n2n_ntop_v3/src/transform_aes.c @@ -0,0 +1,246 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +// size of random value prepended to plaintext defaults to AES BLOCK_SIZE; +// gradually abandoning security, lower values could be chosen; +// however, minimum transmission size with cipher text stealing scheme is one +// block; as network packets should be longer anyway, only low level programmer +// might encounter an issue with lower values here +#define AES_PREAMBLE_SIZE (AES_BLOCK_SIZE) + + +// cts/cbc mode is being used with random value prepended to plaintext +// instead of iv so, actual iv is aes_null_iv +const uint8_t aes_null_iv[AES_IV_SIZE] = { 0 }; + +typedef struct transop_aes { + aes_context_t *ctx; +} transop_aes_t; + + +static int transop_deinit_aes (n2n_trans_op_t *arg) { + + transop_aes_t *priv = (transop_aes_t *)arg->priv; + + if(priv->ctx) + aes_deinit(priv->ctx); + + if(priv) + free(priv); + + return 0; +} + + +// the aes packet format consists of +// +// - a random AES_PREAMBLE_SIZE-sized value prepended to plaintext +// encrypted together with the... +// - ... payload data +// +// [VV|DDDDDDDDDDDDDDDDDDDDD] +// | <---- encrypted ----> | +// +static int transop_encode_aes (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + transop_aes_t *priv = (transop_aes_t *)arg->priv; + + // the assembly buffer is a source for encrypting data + // the whole contents of assembly are encrypted + uint8_t assembly[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + int padded_len; + uint8_t padding; + uint8_t buf[AES_BLOCK_SIZE]; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + AES_PREAMBLE_SIZE + AES_BLOCK_SIZE) <= out_len) { + traceEvent(TRACE_DEBUG, "transop_encode_aes %lu bytes plaintext", in_len); + + // full block sized random value (128 bit) + encode_uint64(assembly, &idx, n2n_rand()); + encode_uint64(assembly, &idx, n2n_rand()); + + // adjust for maybe differently chosen AES_PREAMBLE_SIZE + idx = AES_PREAMBLE_SIZE; + + // the plaintext data + encode_buf(assembly, &idx, inbuf, in_len); + + // round up to next whole AES block size + padded_len = (((idx - 1) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; + padding = (padded_len-idx); + + // pad the following bytes with zero, fixed length (AES_BLOCK_SIZE) seems to compile + // to slightly faster code than run-time dependant 'padding' + memset(assembly + idx, 0, AES_BLOCK_SIZE); + + aes_cbc_encrypt(outbuf, assembly, padded_len, aes_null_iv, priv->ctx); + + if(padding) { + // exchange last two cipher blocks + memcpy(buf, outbuf+padded_len - AES_BLOCK_SIZE, AES_BLOCK_SIZE); + memcpy(outbuf + padded_len - AES_BLOCK_SIZE, outbuf + padded_len - 2 * AES_BLOCK_SIZE, AES_BLOCK_SIZE); + memcpy(outbuf + padded_len - 2 * AES_BLOCK_SIZE, buf, AES_BLOCK_SIZE); + } + } else + traceEvent(TRACE_ERROR, "transop_encode_aes outbuf too small"); + } else + traceEvent(TRACE_ERROR, "transop_encode_aes inbuf too big to encrypt"); + + return idx; +} + + +// see transop_encode_aes for packet format +static int transop_decode_aes (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + transop_aes_t *priv = (transop_aes_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + uint8_t rest; + size_t penultimate_block; + uint8_t buf[AES_BLOCK_SIZE]; + int len = -1; + + if(((in_len - AES_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */ + && (in_len >= AES_PREAMBLE_SIZE) /* has at least random number */ + && (in_len >= AES_BLOCK_SIZE)) { /* minimum size requirement for cipher text stealing */ + traceEvent(TRACE_DEBUG, "transop_decode_aes %lu bytes ciphertext", in_len); + + rest = in_len % AES_BLOCK_SIZE; + if(rest) { /* cipher text stealing */ + penultimate_block = ((in_len / AES_BLOCK_SIZE) - 1) * AES_BLOCK_SIZE; + + // everything normal up to penultimate block + memcpy(assembly, inbuf, penultimate_block); + + // prepare new penultimate block in buf + aes_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx); + memcpy(buf, inbuf + in_len - rest, rest); + + // former penultimate block becomes new ultimate block + memcpy(assembly + penultimate_block + AES_BLOCK_SIZE, inbuf + penultimate_block, AES_BLOCK_SIZE); + + // write new penultimate block from buf + memcpy(assembly + penultimate_block, buf, AES_BLOCK_SIZE); + + // regular cbc decryption of the re-arranged ciphertext + aes_cbc_decrypt(assembly, assembly, in_len + AES_BLOCK_SIZE - rest, aes_null_iv, priv->ctx); + + // check for expected zero padding and give a warning otherwise + if(memcmp(assembly + in_len, aes_null_iv, AES_BLOCK_SIZE - rest)) { + traceEvent(TRACE_WARNING, "transop_decode_aes payload decryption failed with unexpected cipher text stealing padding"); + return -1; + } + } else { + // regular cbc decryption on multiple block-sized payload + aes_cbc_decrypt(assembly, inbuf, in_len, aes_null_iv, priv->ctx); + } + len = in_len - AES_PREAMBLE_SIZE; + memcpy(outbuf, assembly + AES_PREAMBLE_SIZE, len); + } else + traceEvent(TRACE_ERROR, "transop_decode_aes inbuf wrong size (%ul) to decrypt", in_len); + + return len; +} + + +static int setup_aes_key (transop_aes_t *priv, const uint8_t *password, ssize_t password_len) { + + unsigned char key_mat[32]; /* maximum aes key length, equals hash length */ + unsigned char *key; + size_t key_size; + + // let the user choose the degree of encryption: + // long input passwords will pick AES192 or AES256 with more robust but expensive encryption + + // the input password always gets hashed to make a more unpredictable use of the key space + // just think of usually reset MSB of ASCII coded password bytes + pearson_hash_256(key_mat, password, password_len); + + // the length-dependant scheme for key setup was discussed on github: + // https://github.com/ntop/n2n/issues/101 -- as no iv encryption required + // anymore, the key-size trigger values were roughly halved + if(password_len >= 33) { + key_size = AES256_KEY_BYTES; /* 256 bit */ + } else if(password_len >= 23) { + key_size = AES192_KEY_BYTES; /* 192 bit */ + } else { + key_size = AES128_KEY_BYTES; /* 128 bit */ + } + + // and use the last key-sized part of the hash as aes key + key = key_mat + sizeof(key_mat) - key_size; + + // setup the key and have corresponding context created + if(aes_init (key, key_size, &(priv->ctx))) { + traceEvent(TRACE_ERROR, "setup_aes_key %u-bit key setup unsuccessful", key_size * 8); + return -1; + } + traceEvent(TRACE_DEBUG, "setup_aes_key %u-bit key setup completed", key_size * 8); + + return 0; +} + + +static void transop_tick_aes (n2n_trans_op_t *arg, time_t now) { + + // no tick action +} + + +// AES initialization function +int n2n_transop_aes_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + + transop_aes_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_AES; + + ttt->tick = transop_tick_aes; + ttt->deinit = transop_deinit_aes; + ttt->fwd = transop_encode_aes; + ttt->rev = transop_decode_aes; + + priv = (transop_aes_t*)calloc(1, sizeof(transop_aes_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "n2n_transop_aes_init cannot allocate transop_aes_t memory"); + return -1; + } + ttt->priv = priv; + + // setup the cipher and key + return setup_aes_key(priv, encrypt_key, encrypt_key_len); +} diff --git a/bundles/n2n_ntop_v3/src/transform_cc20.c b/bundles/n2n_ntop_v3/src/transform_cc20.c new file mode 100644 index 00000000..fd8d3722 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/transform_cc20.c @@ -0,0 +1,170 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +// ChaCha20 plaintext preamble +#define CC20_PREAMBLE_SIZE (CC20_IV_SIZE) + + +typedef struct transop_cc20 { + cc20_context_t *ctx; +} transop_cc20_t; + + +static int transop_deinit_cc20 (n2n_trans_op_t *arg) { + + transop_cc20_t *priv = (transop_cc20_t *)arg->priv; + + if(priv->ctx) + cc20_deinit(priv->ctx); + + if(priv) + free(priv); + + return 0; +} + + +// the ChaCha20 packet format consists of +// +// - a 128-bit random iv +// - encrypted payload +// +// [IIII|DDDDDDDDDDDDDDDDDDDDD] +// |<---- encrypted ---->| +// +static int transop_encode_cc20 (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int len = -1; + transop_cc20_t *priv = (transop_cc20_t *)arg->priv; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + CC20_PREAMBLE_SIZE) <= out_len) { + size_t idx = 0; + + traceEvent(TRACE_DEBUG, "encode_cc20 %lu bytes", in_len); + + // full iv sized random value (128 bit) + encode_uint64(outbuf, &idx, n2n_rand()); + encode_uint64(outbuf, &idx, n2n_rand()); + + len = in_len; + cc20_crypt(outbuf + CC20_PREAMBLE_SIZE, + inbuf, + in_len, + outbuf, /* iv */ + priv->ctx); + + // size of datacarried in UDP + len += CC20_PREAMBLE_SIZE; + } else + traceEvent(TRACE_ERROR, "encode_cc20 outbuf too small."); + } else + traceEvent(TRACE_ERROR, "encode_cc20 inbuf too big to encrypt."); + + return len; +} + + +// see transop_encode_cc20 for packet format +static int transop_decode_cc20 (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int len = 0; + transop_cc20_t *priv = (transop_cc20_t *)arg->priv; + + if(((in_len - CC20_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */ + && (in_len >= CC20_PREAMBLE_SIZE)) { /* has at least iv */ + + traceEvent(TRACE_DEBUG, "decode_cc20 %lu bytes", in_len); + + len = (in_len - CC20_PREAMBLE_SIZE); + + cc20_crypt(outbuf, + inbuf + CC20_PREAMBLE_SIZE, + in_len, + inbuf, /* iv */ + priv->ctx); + } else + traceEvent(TRACE_ERROR, "decode_cc20 inbuf wrong size (%ul) to decrypt.", in_len); + + return len; +} + + +static int setup_cc20_key (transop_cc20_t *priv, const uint8_t *password, ssize_t password_len) { + + uint8_t key_mat[CC20_KEY_BYTES]; + + // the input key always gets hashed to make a more unpredictable and more complete use of the key space + pearson_hash_256(key_mat, password, password_len); + + if(cc20_init(key_mat, &(priv->ctx))) { + traceEvent(TRACE_ERROR, "setup_cc20_key setup unsuccessful"); + return -1; + } + + traceEvent(TRACE_DEBUG, "setup_cc20_key completed"); + + return 0; +} + + +static void transop_tick_cc20 (n2n_trans_op_t *arg, time_t now) { + + // no tick action +} + + +// ChaCha20 initialization function +int n2n_transop_cc20_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + + transop_cc20_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_CHACHA20; + + ttt->tick = transop_tick_cc20; + ttt->deinit = transop_deinit_cc20; + ttt->fwd = transop_encode_cc20; + ttt->rev = transop_decode_cc20; + + priv = (transop_cc20_t*)calloc(1, sizeof(transop_cc20_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "cannot allocate transop_cc20_t memory"); + return -1; + } + ttt->priv = priv; + + // setup the cipher and key + return setup_cc20_key(priv, encrypt_key, encrypt_key_len); +} diff --git a/bundles/n2n_ntop_v3/src/transform_null.c b/bundles/n2n_ntop_v3/src/transform_null.c new file mode 100644 index 00000000..6fd9d5e7 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/transform_null.c @@ -0,0 +1,91 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +static int transop_deinit_null (n2n_trans_op_t *arg ) { + + // nothing to deallocate, nothing to release + + return 0; +} + + +static int transop_encode_null (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int retval = -1; + + traceEvent(TRACE_DEBUG, "encode_null %lu", in_len); + if(out_len >= in_len) { + memcpy(outbuf, inbuf, in_len); + retval = in_len; + } else { + traceEvent(TRACE_DEBUG, "encode_null %lu too big for packet buffer", in_len); + } + + return retval; +} + + +static int transop_decode_null (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int retval = -1; + + traceEvent(TRACE_DEBUG, "decode_null %lu", in_len); + if(out_len >= in_len) { + memcpy(outbuf, inbuf, in_len); + retval = in_len; + } else { + traceEvent(TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len); + } + + return retval; +} + + +static void transop_tick_null (n2n_trans_op_t *arg, time_t now) { + + // no tick action +} + + +int n2n_transop_null_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + + memset(ttt, 0, sizeof(n2n_trans_op_t)); + + ttt->transform_id = N2N_TRANSFORM_ID_NULL; + ttt->no_encryption = 1; + ttt->deinit = transop_deinit_null; + ttt->tick = transop_tick_null; + ttt->fwd = transop_encode_null; + ttt->rev = transop_decode_null; + + return 0; +} diff --git a/bundles/n2n_ntop_v3/src/transform_speck.c b/bundles/n2n_ntop_v3/src/transform_speck.c new file mode 100644 index 00000000..22bac109 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/transform_speck.c @@ -0,0 +1,174 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +// Speck plaintext preamble +#define TRANSOP_SPECK_PREAMBLE_SIZE (N2N_SPECK_IVEC_SIZE) + + +typedef struct transop_speck { + speck_context_t *ctx; /* the round keys for payload encryption & decryption */ +} transop_speck_t; + + +static int transop_deinit_speck (n2n_trans_op_t *arg) { + + transop_speck_t *priv = (transop_speck_t *)arg->priv; + + if(priv->ctx) + speck_deinit(priv->ctx); + + if(priv) + free(priv); + + return 0; +} + + +// the Speck packet format consists of +// +// - a 128-bit random iv +// - encrypted payload +// +// [IIII|DDDDDDDDDDDDDDDDDDDDD] +// |<---- encrypted ---->| +// +static int transop_encode_speck (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int len = -1; + transop_speck_t *priv = (transop_speck_t *)arg->priv; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + TRANSOP_SPECK_PREAMBLE_SIZE) <= out_len) { + size_t idx = 0; + + traceEvent(TRACE_DEBUG, "encode_speck %lu bytes", in_len); + + // generate and encode the iv + encode_uint64(outbuf, &idx, n2n_rand()); + encode_uint64(outbuf, &idx, n2n_rand()); + + // encrypt the payload and write the ciphertext after the iv + // len is set to the length of the cipher plain text to be encrpyted + // which is (in this case) identical to original packet lentgh + len = in_len; + speck_ctr (outbuf + TRANSOP_SPECK_PREAMBLE_SIZE, /* output starts right after the iv */ + inbuf, /* input */ + in_len, /* len */ + outbuf, /* iv, already encoded in outbuf, speck does not change it */ + priv->ctx); /* ctx already setup with round keys */ + + traceEvent(TRACE_DEBUG, "encode_speck: encrypted %u bytes.\n", in_len); + + // size of data carried in UDP + len += TRANSOP_SPECK_PREAMBLE_SIZE; + } else + traceEvent(TRACE_ERROR, "encode_speck outbuf too small."); + } else + traceEvent(TRACE_ERROR, "encode_speck inbuf too big to encrypt."); + + return len; +} + + +// see transop_encode_speck for packet format +static int transop_decode_speck (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + int len = 0; + transop_speck_t *priv = (transop_speck_t *)arg->priv; + + if(((in_len - TRANSOP_SPECK_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in buffer */ + && (in_len >= TRANSOP_SPECK_PREAMBLE_SIZE)) { /* has at least iv */ + + traceEvent(TRACE_DEBUG, "decode_speck %lu bytes", in_len); + + len = (in_len - TRANSOP_SPECK_PREAMBLE_SIZE); + speck_ctr (outbuf, /* output */ + inbuf + TRANSOP_SPECK_PREAMBLE_SIZE, /* encrypted data starts right after preamble (iv) */ + len, /* len */ + inbuf, /* iv can be found at input's beginning */ + priv->ctx); /* ctx already setup with round keys */ + + traceEvent(TRACE_DEBUG, "decode_speck decrypted %u bytes.\n", len); + } else + traceEvent(TRACE_ERROR, "decode_speck inbuf wrong size (%ul) to decrypt.", in_len); + + return len; +} + + +static int setup_speck_key (transop_speck_t *priv, const uint8_t *key, ssize_t key_size) { + + uint8_t key_mat_buf[32]; + + // the input key always gets hashed to make a more unpredictable and more complete use of the key space + pearson_hash_256(key_mat_buf, key, key_size); + + // expand the key material to the context (= round keys), 256 bit keysize + speck_init(&(priv->ctx), key_mat_buf, 256); + + traceEvent(TRACE_DEBUG, "setup_speck_key completed\n"); + + return 0; +} + + +static void transop_tick_speck (n2n_trans_op_t *arg, time_t now) { + + // no tick action +} + + +// Speck initialization function +int n2n_transop_speck_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + + transop_speck_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_SPECK; + + ttt->tick = transop_tick_speck; + ttt->deinit = transop_deinit_speck; + ttt->fwd = transop_encode_speck; + ttt->rev = transop_decode_speck; + + priv = (transop_speck_t*)calloc(1, sizeof(transop_speck_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "n2n_transop_speck_init cannot allocate transop_speck_t memory"); + return -1; + } + ttt->priv = priv; + + // setup the cipher and key + return setup_speck_key(priv, encrypt_key, encrypt_key_len); +} diff --git a/bundles/n2n_ntop_v3/src/transform_tf.c b/bundles/n2n_ntop_v3/src/transform_tf.c new file mode 100644 index 00000000..144b6ec9 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/transform_tf.c @@ -0,0 +1,232 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +// size of random value prepended to plaintext defaults to TF_BLOCK_SIZE; +// gradually abandoning security, lower values could be chosen; +// however, minimum transmission size with cipher text stealing scheme is one +// block; as network packets should be longer anyway, only low level programmer +// might encounter an issue with lower values here +#define TF_PREAMBLE_SIZE (TF_BLOCK_SIZE) + + +// cbc mode is being used with random value prepended to plaintext +// instead of iv so, actual iv is tf_null_iv +const uint8_t tf_null_iv[TF_IV_SIZE] = { 0 }; + +typedef struct transop_tf { + tf_context_t *ctx; +} transop_tf_t; + + +static int transop_deinit_tf (n2n_trans_op_t *arg) { + + transop_tf_t *priv = (transop_tf_t *)arg->priv; + + if(priv->ctx) + tf_deinit(priv->ctx); + + if(priv) + free(priv); + + return 0; +} + + +// the Twofish packet format consists of +// +// - a random TF_PREAMBLE_SIZE-sized value prepended to plaintext +// encrypted together with the... +// - ... payload data +// +// [VV|DDDDDDDDDDDDDDDDDDDDD] +// | <---- encrypted ----> | +// +static int transop_encode_tf (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + transop_tf_t *priv = (transop_tf_t *)arg->priv; + + // the assembly buffer is a source for encrypting data + // the whole contents of assembly are encrypted + uint8_t assembly[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + int padded_len; + uint8_t padding; + uint8_t buf[TF_BLOCK_SIZE]; + + if(in_len <= N2N_PKT_BUF_SIZE) { + if((in_len + TF_PREAMBLE_SIZE + TF_BLOCK_SIZE) <= out_len) { + traceEvent(TRACE_DEBUG, "transop_encode_tf %lu bytes plaintext", in_len); + + // full block sized random value (128 bit) + encode_uint64(assembly, &idx, n2n_rand()); + encode_uint64(assembly, &idx, n2n_rand()); + + // adjust for maybe differently chosen TF_PREAMBLE_SIZE + idx = TF_PREAMBLE_SIZE; + + // the plaintext data + encode_buf(assembly, &idx, inbuf, in_len); + + // round up to next whole TF block size + padded_len = (((idx - 1) / TF_BLOCK_SIZE) + 1) * TF_BLOCK_SIZE; + padding = (padded_len-idx); + + // pad the following bytes with zero, fixed length (TF_BLOCK_SIZE) seems to compile + // to slightly faster code than run-time dependant 'padding' + memset(assembly + idx, 0, TF_BLOCK_SIZE); + tf_cbc_encrypt(outbuf, assembly, padded_len, tf_null_iv, priv->ctx); + + if(padding) { + // exchange last two cipher blocks + memcpy(buf, outbuf + padded_len - TF_BLOCK_SIZE, TF_BLOCK_SIZE); + memcpy(outbuf + padded_len - TF_BLOCK_SIZE, outbuf + padded_len - 2 * TF_BLOCK_SIZE, TF_BLOCK_SIZE); + memcpy(outbuf + padded_len - 2 * TF_BLOCK_SIZE, buf, TF_BLOCK_SIZE); + } + } else + traceEvent(TRACE_ERROR, "transop_encode_tf outbuf too small"); + } else + traceEvent(TRACE_ERROR, "transop_encode_tf inbuf too big to encrypt"); + + return idx; +} + + +// see transop_encode_tf for packet format +static int transop_decode_tf (n2n_trans_op_t *arg, + uint8_t *outbuf, + size_t out_len, + const uint8_t *inbuf, + size_t in_len, + const uint8_t *peer_mac) { + + + transop_tf_t *priv = (transop_tf_t *)arg->priv; + uint8_t assembly[N2N_PKT_BUF_SIZE]; + + uint8_t rest; + size_t penultimate_block; + uint8_t buf[TF_BLOCK_SIZE]; + int len = -1; + + if(((in_len - TF_PREAMBLE_SIZE) <= N2N_PKT_BUF_SIZE) /* cipher text fits in assembly */ + && (in_len >= TF_PREAMBLE_SIZE) /* has at least random number */ + && (in_len >= TF_BLOCK_SIZE)) { /* minimum size requirement for cipher text stealing */ + + traceEvent(TRACE_DEBUG, "transop_decode_tf %lu bytes ciphertext", in_len); + + rest = in_len % TF_BLOCK_SIZE; + if(rest) { /* cipher text stealing */ + penultimate_block = ((in_len / TF_BLOCK_SIZE) - 1) * TF_BLOCK_SIZE; + + // everything normal up to penultimate block + memcpy(assembly, inbuf, penultimate_block); + + // prepare new penultimate block in buf + tf_ecb_decrypt(buf, inbuf + penultimate_block, priv->ctx); + memcpy(buf, inbuf + in_len - rest, rest); + + // former penultimate block becomes new ultimate block + memcpy(assembly + penultimate_block + TF_BLOCK_SIZE, inbuf + penultimate_block, TF_BLOCK_SIZE); + + // write new penultimate block from buf + memcpy(assembly + penultimate_block, buf, TF_BLOCK_SIZE); + + // regular cbc decryption of the re-arranged ciphertext + tf_cbc_decrypt(assembly, assembly, in_len + TF_BLOCK_SIZE - rest, tf_null_iv, priv->ctx); + + // check for expected zero padding and give a warning otherwise + if(memcmp(assembly + in_len, tf_null_iv, TF_BLOCK_SIZE - rest)) { + traceEvent(TRACE_WARNING, "transop_decode_tf payload decryption failed with unexpected cipher text stealing padding"); + return -1; + } + } else { + // regular cbc decryption on multiple block-sized payload + tf_cbc_decrypt(assembly, inbuf, in_len, tf_null_iv, priv->ctx); + } + len = in_len - TF_PREAMBLE_SIZE; + memcpy(outbuf, assembly + TF_PREAMBLE_SIZE, len); + } else + traceEvent(TRACE_ERROR, "transop_decode_tf inbuf wrong size (%ul) to decrypt", in_len); + + return len; +} + + +static int setup_tf_key (transop_tf_t *priv, const uint8_t *password, ssize_t password_len) { + + unsigned char key[32]; /* tf key length, equals hash length */ + size_t key_size; + + // the input password always gets hashed to make a more unpredictable use of the key space + // just think of usually reset MSB of ASCII coded password bytes + pearson_hash_256(key, password, password_len); + + key_size = 32; /* 256 bit */ + + // setup the key and have corresponding context created + if(tf_init(key, key_size * 8, &(priv->ctx))) { + traceEvent(TRACE_ERROR, "setup_tf_key %u-bit key setup unsuccessful", key_size * 8); + return -1; + } + + traceEvent(TRACE_DEBUG, "setup_tf_key %u-bit key setup completed", key_size * 8); + + return 0; +} + + +static void transop_tick_tf (n2n_trans_op_t *arg, time_t now) { + + // no tick action +} + + +// Twofish initialization function +int n2n_transop_tf_init (const n2n_edge_conf_t *conf, n2n_trans_op_t *ttt) { + + transop_tf_t *priv; + const u_char *encrypt_key = (const u_char *)conf->encrypt_key; + size_t encrypt_key_len = strlen(conf->encrypt_key); + + memset(ttt, 0, sizeof(*ttt)); + ttt->transform_id = N2N_TRANSFORM_ID_TWOFISH; + + ttt->tick = transop_tick_tf; + ttt->deinit = transop_deinit_tf; + ttt->fwd = transop_encode_tf; + ttt->rev = transop_decode_tf; + + priv = (transop_tf_t*)calloc(1, sizeof(transop_tf_t)); + if(!priv) { + traceEvent(TRACE_ERROR, "n2n_transop_tf_cbc_init cannot allocate transop_tf_t memory"); + return -1; + } + ttt->priv = priv; + + // setup the cipher and key + return setup_tf_key(priv, encrypt_key, encrypt_key_len); +} diff --git a/bundles/n2n_ntop_v3/src/tuntap_freebsd.c b/bundles/n2n_ntop_v3/src/tuntap_freebsd.c new file mode 100644 index 00000000..02b99b13 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/tuntap_freebsd.c @@ -0,0 +1,136 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +#ifdef __FreeBSD__ + + +#define N2N_FREEBSD_TAPDEVICE_SIZE 32 + + +void tuntap_close (tuntap_dev *device); + + +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + + int i; + char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; + + for(i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return -1; + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if(device_mac && device_mac[0] != '\0') { + // FIXME - this is not tested, might be wrong syntax for OS X + + // set the hw address before bringing the if up + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", i, device_ip, device_mask); + + // read MAC address + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + // traceEvent(TRACE_INFO, "%s", buf); + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return -1; + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + + // read_mac(dev, device->mac_addr); + + return device->fd; +} + + +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return read(tuntap->fd, buf, len); +} + + +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return write(tuntap->fd, buf, len); +} + + +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); +} + + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action +} + + +#endif /* #ifdef __FreeBSD__ */ diff --git a/bundles/n2n_ntop_v3/src/tuntap_linux.c b/bundles/n2n_ntop_v3/src/tuntap_linux.c new file mode 100644 index 00000000..cc23facc --- /dev/null +++ b/bundles/n2n_ntop_v3/src/tuntap_linux.c @@ -0,0 +1,281 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#ifdef __linux__ + + +#include "n2n.h" + + +static int setup_ifname (int fd, const char *ifname, const char *ipaddr, + const char *netmask, uint8_t *mac, int mtu) { + + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); + + if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + ifr.ifr_addr.sa_family = AF_INET; + + // interface address + inet_pton(AF_INET, ipaddr, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFADDR) failed [%d]: %s", errno, strerror(errno)); + return -2; + } + + // netmask + if(netmask && (((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr != 0)) { + inet_pton(AF_INET, netmask, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFNETMASK, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFNETMASK, %s) failed [%d]: %s", netmask, errno, strerror(errno)); + return -3; + } + } + + // MTU + ifr.ifr_mtu = mtu; + if(ioctl(fd, SIOCSIFMTU, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFMTU) failed [%d]: %s", errno, strerror(errno)); + return -4; + } + + // set up and running + if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCGIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return -5; + } + + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + + if(ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return -6; + } + + return 0; +} + + +/** @brief Open and configure the TAP device for packet read/write. + * + * This routine creates the interface via the tuntap driver and then + * configures it. + * + * @param device - [inout] a device info holder object + * @param dev - user-defined name for the new iface, + * if NULL system will assign a name + * @param device_ip - address of iface + * @param device_mask - netmask for device_ip + * @param mtu - MTU for device_ip + * + * @return - negative value on error + * - non-negative file-descriptor on success + */ +int tuntap_open (tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + + char *tuntap_device = "/dev/net/tun"; + int ioctl_fd; + struct ifreq ifr; + int rc; + int nl_fd; + char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ + struct iovec iov; + struct sockaddr_nl sa; + int up_and_running = 0; + struct msghdr msg; + + device->fd = open(tuntap_device, O_RDWR); + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "tuntap open() error: %s[%d]. Is the tun kernel module loaded?\n", strerror(errno), errno); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + // want a TAP device for layer 2 frames + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + + strncpy(ifr.ifr_name, dev, IFNAMSIZ-1); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); + + if(rc < 0) { + traceEvent(TRACE_ERROR, "tuntap ioctl(TUNSETIFF, IFF_TAP) error: %s[%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + + // store the device name for later reuse + strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); + + if(device_mac && device_mac[0]) { + // use the user-provided MAC + str2mac(device->mac_addr, device_mac); + } else { + // set an explicit random MAC to know the exact MAC in use, manually + // reading the MAC address is not safe as it may change internally + // also after the TAP interface UP status has been notified + + memrnd(device->mac_addr, N2N_MAC_SIZE); + + // clear multicast bit + device->mac_addr[0] &= ~0x01; + + // set locally-assigned bit + device->mac_addr[0] |= 0x02; + } + + // initialize netlink socket + if((nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + iov.iov_base = nl_buf; + iov.iov_len = sizeof(nl_buf); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_LINK; + sa.nl_pid = getpid(); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + // subscribe to interface events + if(bind(nl_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + if((ioctl_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + close(nl_fd); + return -1; + } + + if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device->mac_addr, mtu) < 0) { + close(nl_fd); + close(ioctl_fd); + close(device->fd); + return -1; + } + + close(ioctl_fd); + + // wait for the up and running notification + traceEvent(TRACE_INFO, "Waiting for TAP interface to be up and running..."); + + while(!up_and_running) { + ssize_t len = recvmsg(nl_fd, &msg, 0); + struct nlmsghdr *nh; + + for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { + if(nh->nlmsg_type == NLMSG_ERROR) { + traceEvent(TRACE_DEBUG, "nh->nlmsg_type == NLMSG_ERROR"); + break; + } + + if(nh->nlmsg_type == NLMSG_DONE) + break; + + if(nh->nlmsg_type == NETLINK_GENERIC) { + struct ifinfomsg *ifi = NLMSG_DATA(nh); + + // NOTE: skipping interface name check, assuming it's our TAP + if((ifi->ifi_flags & IFF_UP) && (ifi->ifi_flags & IFF_RUNNING)) { + up_and_running = 1; + traceEvent(TRACE_INFO, "Interface is up and running"); + break; + } + } + } + } + + close(nl_fd); + + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->if_idx = if_nametoindex(dev); + + return device->fd; +} + + +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return read(tuntap->fd, buf, len); +} + + +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return write(tuntap->fd, buf, len); +} + + +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); +} + + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + struct ifreq ifr; + int fd; + + if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + return; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, tuntap->dev_name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + + if(ioctl(fd, SIOCGIFADDR, &ifr) != -1) + tuntap->ip_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + + close(fd); +} + + +#endif /* #ifdef __linux__ */ diff --git a/bundles/n2n_ntop_v3/src/tuntap_netbsd.c b/bundles/n2n_ntop_v3/src/tuntap_netbsd.c new file mode 100644 index 00000000..088f4a8f --- /dev/null +++ b/bundles/n2n_ntop_v3/src/tuntap_netbsd.c @@ -0,0 +1,148 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +#ifdef __NetBSD__ + + +#include +#include +#include + + +#define N2N_NETBSD_TAPDEVICE_SIZE 32 + + +void tun_close (tuntap_dev *device); + + +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + + char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; + struct ifreq req; + + if(dev) { + snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); + device->fd = open(tap_device, O_RDWR); + snprintf(tap_device, sizeof(tap_device), "%s", dev); + } else { + device->fd = open("/dev/tap", O_RDWR); + if(device->fd >= 0) { + if(ioctl(device->fd, TAPGIFNAME, &req) == -1) { + traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); + close(device->fd); + return -1; + } else { + snprintf(tap_device, sizeof(tap_device), req.ifr_name); + } + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); + return -1; + } else { + char cmd[256]; + FILE *fd; + + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + + device->ip_addr = inet_addr(device_ip); + + if(device_mac && device_mac[0] != '\0') { + // set the hw address before bringing the if up + snprintf(cmd, sizeof(cmd), "ifconfig %s link %s active", tap_device, device_mac); + system(cmd); + } + + snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s mtu %d up", tap_device, device_ip, device_mask, mtu); + system(cmd); + + traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", tap_device, device_ip, device_mask); + + // read MAC address + snprintf(cmd, sizeof(cmd), "ifconfig %s |grep address|cut -c 11-28", tap_device); + // traceEvent(TRACE_INFO, "%s", cmd); + + fd = popen(cmd, "r"); + if(fd < 0) { + tun_close(device); + return -1; + } else { + int a, b, c, d, e, f; + char buf[256]; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address [%s]", tap_device, cmd); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + // read_mac(dev, device->mac_addr); + + return(device->fd); +} + + +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(read(tuntap->fd, buf, len)); +} + + +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(write(tuntap->fd, buf, len)); +} + + +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); +} + + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action +} + + +#endif /* #ifdef __NetBSD__ */ diff --git a/bundles/n2n_ntop_v3/src/tuntap_osx.c b/bundles/n2n_ntop_v3/src/tuntap_osx.c new file mode 100644 index 00000000..4ba51af9 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/tuntap_osx.c @@ -0,0 +1,134 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + + +#include "n2n.h" + + +#ifdef __APPLE__ + + +#define N2N_OSX_TAPDEVICE_SIZE 32 + + +void tun_close (tuntap_dev *device); + + +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { + + int i; + char tap_device[N2N_OSX_TAPDEVICE_SIZE]; + + for(i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } + } + + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open any tap devices /dev/tap0 through /dev/tap254. Is this user properly authorized to access those descriptors?"); + traceEvent(TRACE_ERROR, "Please read https://github.com/ntop/n2n/blob/dev/doc/Building.md"); + return -1; + } else { + char buf[256]; + FILE *fd; + + device->ip_addr = inet_addr(device_ip); + + if(device_mac && device_mac[0] != '\0') { + // FIXME - this is not tested. might be wrong syntax for OS X + // set the hw address before bringing the if up + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", i, device_ip, device_mask); + + // read MAC address + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + // traceEvent(TRACE_INFO, "%s", buf); + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return -1; + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + // read_mac(dev, device->mac_addr); + + return(device->fd); +} + + +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(read(tuntap->fd, buf, len)); +} + + +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(write(tuntap->fd, buf, len)); +} + + +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); +} + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action +} + + +#endif /* __APPLE__ */ diff --git a/bundles/n2n_ntop_v3/src/wire.c b/bundles/n2n_ntop_v3/src/wire.c new file mode 100644 index 00000000..e7e2c251 --- /dev/null +++ b/bundles/n2n_ntop_v3/src/wire.c @@ -0,0 +1,727 @@ +/** + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +/** Routines for encoding and decoding n2n packets on the wire. + * + * encode_X(base,idx,v) prototypes are inspired by the erlang internal + * encoding model. Passing the start of a buffer in base and a pointer to an + * integer (initially set to zero). Each encode routine increases idx by the + * amount written and returns the amount written. In this way complex sequences + * of encodings can be represented cleanly. See encode_register() for an + * example. + */ + +#include "n2n.h" + + +int encode_uint8 (uint8_t * base, + size_t * idx, + const uint8_t v) { + + *(base + (*idx)) = (v & 0xff); + ++(*idx); + + return 1; +} + +int decode_uint8 (uint8_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + if(*rem < 1) { + return 0; + } + + *out = ( base[*idx] & 0xff ); + ++(*idx); + --(*rem); + + return 1; +} + +int encode_uint16 (uint8_t * base, + size_t * idx, + const uint16_t v) { + + *(base + (*idx)) = ( v >> 8) & 0xff; + *(base + (1 + *idx)) = ( v & 0xff ); + *idx += 2; + + return 2; +} + +int decode_uint16 (uint16_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + if(*rem < 2) { + return 0; + } + + *out = ( base[*idx] & 0xff ) << 8; + *out |= ( base[1 + *idx] & 0xff ); + *idx += 2; + *rem -= 2; + + return 2; +} + +int encode_uint32 (uint8_t * base, + size_t * idx, + const uint32_t v) { + + *(base + (0 + *idx)) = ( v >> 24) & 0xff; + *(base + (1 + *idx)) = ( v >> 16) & 0xff; + *(base + (2 + *idx)) = ( v >> 8) & 0xff; + *(base + (3 + *idx)) = ( v & 0xff ); + *idx += 4; + + return 4; +} + +int decode_uint32 (uint32_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + if(*rem < 4) { + return 0; + } + + *out = ( base[0 + *idx] & 0xff ) << 24; + *out |= ( base[1 + *idx] & 0xff ) << 16; + *out |= ( base[2 + *idx] & 0xff ) << 8; + *out |= ( base[3 + *idx] & 0xff ); + *idx += 4; + *rem -= 4; + + return 4; +} + +int encode_uint64 (uint8_t * base, + size_t * idx, + const uint64_t v) { + + *(uint64_t*)(base + *idx) = htobe64(v); + *idx += 8; + + return 8; +} + +int decode_uint64 (uint64_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + if(*rem < 8) { + return 0; + } + + *out = be64toh(*(uint64_t*)base + *idx); + *idx += 8; + *rem -= 8; + + return 8; +} + +int encode_buf (uint8_t * base, + size_t * idx, + const void * p, + size_t s) { + + memcpy((base + (*idx)), p, s); + *idx += s; + + return s; +} + +/* Copy from base to out of size bufsize */ +int decode_buf (uint8_t * out, + size_t bufsize, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + if(*rem < bufsize) { + return 0; + } + + memcpy(out, (base + *idx), bufsize); + *idx += bufsize; + *rem -= bufsize; + + return bufsize; +} + + +int encode_mac (uint8_t * base, /* n2n_mac_t is typedefed array type which is always passed by reference */ + size_t * idx, + const n2n_mac_t m) { + + return encode_buf(base, idx, m, N2N_MAC_SIZE); +} + +int decode_mac (n2n_mac_t out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + return decode_buf(out, N2N_MAC_SIZE, base, rem, idx); +} + +int encode_cookie (uint8_t * base, + size_t * idx, + const n2n_cookie_t c) { + + return encode_uint32(base, idx, c); +} + +int decode_cookie (n2n_cookie_t * out, /* cookies are typedef'd as uint32_t which needs to correspond to this code */ + const uint8_t * base, + size_t * rem, + size_t * idx) { + + return decode_uint32(out, base, rem, idx); +} + + +int encode_common (uint8_t * base, + size_t * idx, + const n2n_common_t * common) { + + uint16_t flags = 0; + + encode_uint8(base, idx, N2N_PKT_VERSION); + encode_uint8(base, idx, common->ttl); + + flags = common->pc & N2N_FLAGS_TYPE_MASK; + flags |= common->flags & N2N_FLAGS_BITS_MASK; + + encode_uint16(base, idx, flags); + encode_buf(base, idx, common->community, N2N_COMMUNITY_SIZE); + + return -1; +} + +int decode_common (n2n_common_t * out, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + size_t idx0 = *idx; + uint8_t dummy = 0; + + decode_uint8(&dummy, base, rem, idx); + + if(N2N_PKT_VERSION != dummy) { + return -1; + } + + decode_uint8(&(out->ttl), base, rem, idx); + decode_uint16(&(out->flags), base, rem, idx); + out->pc = (out->flags & N2N_FLAGS_TYPE_MASK); + out->flags &= N2N_FLAGS_BITS_MASK; + + decode_buf(out->community, N2N_COMMUNITY_SIZE, base, rem, idx); + + return (*idx - idx0); +} + + +int encode_sock (uint8_t * base, + size_t * idx, + const n2n_sock_t * sock) { + + int retval = 0; + uint16_t f; + + switch(sock->family) { + case AF_INET: { + f = 0; + retval += encode_uint16(base, idx, f); + retval += encode_uint16(base, idx, sock->port); + retval += encode_buf(base, idx, sock->addr.v4, IPV4_SIZE); + break; + } + + case AF_INET6: { + f = 0x8000; + retval += encode_uint16(base, idx, f); + retval += encode_uint16(base, idx, sock->port); + retval += encode_buf(base, idx, sock->addr.v6, IPV6_SIZE); + break; + } + + default: + retval = -1; + } + + return retval; +} + + +int decode_sock (n2n_sock_t * sock, + const uint8_t * base, + size_t * rem, + size_t * idx) { + + size_t * idx0 = idx; + uint16_t f = 0; + + decode_uint16(&f, base, rem, idx); + + if(f & 0x8000) { + + /* IPv6 */ + sock->family = AF_INET6; + decode_uint16(&(sock->port), base, rem, idx); + decode_buf(sock->addr.v6, IPV6_SIZE, base, rem, idx); + } else { + /* IPv4 */ + sock->family = AF_INET; + decode_uint16(&(sock->port), base, rem, idx); + memset(sock->addr.v6, 0, IPV6_SIZE); /* so memcmp() works for equality. */ + decode_buf(sock->addr.v4, IPV4_SIZE, base, rem, idx); + } + + return (idx - idx0); +} + + +int encode_REGISTER (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_REGISTER_t *reg) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_cookie(base, idx, reg->cookie); + retval += encode_mac(base, idx, reg->srcMac); + retval += encode_mac(base, idx, reg->dstMac); + if(common->flags & N2N_FLAGS_SOCKET) { + retval += encode_sock(base, idx, &(reg->sock)); + } + retval += encode_uint32(base, idx, reg->dev_addr.net_addr); + retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen); + retval += encode_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE); + + return retval; +} + + +int decode_REGISTER (n2n_REGISTER_t *reg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(reg, 0, sizeof(n2n_REGISTER_t)); + + retval += decode_cookie(®->cookie, base, rem, idx); + retval += decode_mac(reg->srcMac, base, rem, idx); + retval += decode_mac(reg->dstMac, base, rem, idx); + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += decode_sock(&(reg->sock), base, rem, idx); + } + retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx); + retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx); + retval += decode_buf(reg->dev_desc, N2N_DESC_SIZE, base, rem, idx); + + return retval; +} + + +int encode_REGISTER_SUPER (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_REGISTER_SUPER_t *reg) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_cookie(base, idx, reg->cookie); + retval += encode_mac(base, idx, reg->edgeMac); + if(common->flags & N2N_FLAGS_SOCKET) { + retval += encode_sock(base, idx, &(reg->sock)); + } + retval += encode_uint32(base, idx, reg->dev_addr.net_addr); + retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen); + retval += encode_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE); + retval += encode_uint16(base, idx, reg->auth.scheme); + retval += encode_uint16(base, idx, reg->auth.token_size); + retval += encode_buf(base, idx, reg->auth.token, reg->auth.token_size); + retval += encode_uint32(base, idx, reg->key_time); + + return retval; +} + + +int decode_REGISTER_SUPER (n2n_REGISTER_SUPER_t *reg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(reg, 0, sizeof(n2n_REGISTER_SUPER_t)); + + retval += decode_cookie(®->cookie, base, rem, idx); + retval += decode_mac(reg->edgeMac, base, rem, idx); + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += decode_sock(&(reg->sock), base, rem, idx); + } + retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx); + retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx); + retval += decode_buf(reg->dev_desc, N2N_DESC_SIZE, base, rem, idx); + retval += decode_uint16(&(reg->auth.scheme), base, rem, idx); + retval += decode_uint16(&(reg->auth.token_size), base, rem, idx); + retval += decode_buf(reg->auth.token, reg->auth.token_size, base, rem, idx); + retval += decode_uint32(&(reg->key_time), base, rem, idx); + + return retval; +} + + +int encode_UNREGISTER_SUPER (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_UNREGISTER_SUPER_t *unreg) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_uint16(base, idx, unreg->auth.scheme); + retval += encode_uint16(base, idx, unreg->auth.token_size); + retval += encode_buf(base, idx, unreg->auth.token, unreg->auth.token_size); + retval += encode_mac(base, idx, unreg->srcMac); + + return retval; +} + + +int decode_UNREGISTER_SUPER (n2n_UNREGISTER_SUPER_t *unreg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(unreg, 0, sizeof(n2n_UNREGISTER_SUPER_t)); + + retval += decode_uint16(&(unreg->auth.scheme), base, rem, idx); + retval += decode_uint16(&(unreg->auth.token_size), base, rem, idx); + retval += decode_buf(unreg->auth.token, unreg->auth.token_size, base, rem, idx); + retval += decode_mac(unreg->srcMac, base, rem, idx); + + return retval; +} + + +int encode_REGISTER_ACK (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_REGISTER_ACK_t *reg) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_cookie(base, idx, reg->cookie); + retval += encode_mac(base, idx, reg->dstMac); + retval += encode_mac(base, idx, reg->srcMac); + + /* The socket in REGISTER_ACK is the socket from which the REGISTER + * arrived. This is sent back to the sender so it knows what its public + * socket is. */ + if(common->flags & N2N_FLAGS_SOCKET) { + retval += encode_sock(base, idx, &(reg->sock)); + } + + return retval; +} + + +int decode_REGISTER_ACK (n2n_REGISTER_ACK_t *reg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(reg, 0, sizeof(n2n_REGISTER_ACK_t)); + + retval += decode_cookie(®->cookie, base, rem, idx); + retval += decode_mac(reg->dstMac, base, rem, idx); + retval += decode_mac(reg->srcMac, base, rem, idx); + + /* The socket in REGISTER_ACK is the socket from which the REGISTER + * arrived. This is sent back to the sender so it knows what its public + * socket is. */ + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += decode_sock(&(reg->sock), base, rem, idx); + } + + return retval; +} + + +int encode_REGISTER_SUPER_ACK (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_REGISTER_SUPER_ACK_t *reg, + uint8_t *tmpbuf) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_cookie(base, idx, reg->cookie); + retval += encode_mac(base, idx, reg->srcMac); + retval += encode_uint32(base, idx, reg->dev_addr.net_addr); + retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen); + retval += encode_uint16(base, idx, reg->lifetime); + + retval += encode_sock(base, idx, &(reg->sock)); + + retval += encode_uint16(base, idx, reg->auth.scheme); + retval += encode_uint16(base, idx, reg->auth.token_size); + retval += encode_buf(base, idx, reg->auth.token, reg->auth.token_size); + + retval += encode_uint8(base, idx, reg->num_sn); + retval += encode_buf(base, idx, tmpbuf, (reg->num_sn*REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE)); + + retval += encode_uint32(base, idx, reg->key_time); + + return retval; +} + + +int decode_REGISTER_SUPER_ACK (n2n_REGISTER_SUPER_ACK_t *reg, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx, + uint8_t *tmpbuf) { + + size_t retval = 0; + memset(reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t)); + + retval += decode_cookie(®->cookie, base, rem, idx); + retval += decode_mac(reg->srcMac, base, rem, idx); + retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx); + retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx); + retval += decode_uint16(&(reg->lifetime), base, rem, idx); + + /* Socket is mandatory in this message type */ + retval += decode_sock(&(reg->sock), base, rem, idx); + + retval += decode_uint16(&(reg->auth.scheme), base, rem, idx); + retval += decode_uint16(&(reg->auth.token_size), base, rem, idx); + retval += decode_buf(reg->auth.token, reg->auth.token_size, base, rem, idx); + + /* Following the edge socket are an array of backup supernodes. */ + retval += decode_uint8(&(reg->num_sn), base, rem, idx); + retval += decode_buf(tmpbuf, (reg->num_sn * REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE), base, rem, idx); + + retval += decode_uint32(&(reg->key_time), base, rem, idx); + + return retval; +} + + +int encode_REGISTER_SUPER_NAK (uint8_t *base, + size_t *idx, + const n2n_common_t *common, + const n2n_REGISTER_SUPER_NAK_t *nak) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_cookie(base, idx, nak->cookie); + retval += encode_mac(base, idx, nak->srcMac); + + retval += encode_uint16(base, idx, nak->auth.scheme); + retval += encode_uint16(base, idx, nak->auth.token_size); + retval += encode_buf(base, idx, nak->auth.token, nak->auth.token_size); + + return retval; +} + + +int decode_REGISTER_SUPER_NAK (n2n_REGISTER_SUPER_NAK_t *nak, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t)); + + retval += decode_cookie(&nak->cookie, base, rem, idx); + retval += decode_mac(nak->srcMac, base, rem, idx); + + retval += decode_uint16(&(nak->auth.scheme), base, rem, idx); + retval += decode_uint16(&(nak->auth.token_size), base, rem, idx); + retval += decode_buf(nak->auth.token, nak->auth.token_size, base, rem, idx); + + return retval; +} + + +int fill_sockaddr (struct sockaddr * addr, + size_t addrlen, + const n2n_sock_t * sock) { + + int retval = -1; + + if(AF_INET == sock->family) { + if(addrlen >= sizeof(struct sockaddr_in)) { + struct sockaddr_in * si = (struct sockaddr_in *)addr; + si->sin_family = sock->family; + si->sin_port = htons(sock->port); + memcpy(&(si->sin_addr.s_addr), sock->addr.v4, IPV4_SIZE); + retval = 0; + } + } + + return retval; +} + + +int encode_PACKET (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_PACKET_t * pkt) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_mac(base, idx, pkt->srcMac); + retval += encode_mac(base, idx, pkt->dstMac); + if(common->flags & N2N_FLAGS_SOCKET) { + retval += encode_sock(base, idx, &(pkt->sock)); + } + retval += encode_uint8(base, idx, pkt->compression); + retval += encode_uint8(base, idx, pkt->transform); + + return retval; +} + + +int decode_PACKET (n2n_PACKET_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx) { + + size_t retval = 0; + memset(pkt, 0, sizeof(n2n_PACKET_t)); + + retval += decode_mac(pkt->srcMac, base, rem, idx); + retval += decode_mac(pkt->dstMac, base, rem, idx); + + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += decode_sock(&(pkt->sock), base, rem, idx); + } + + retval += decode_uint8(&(pkt->compression), base, rem, idx); + retval += decode_uint8(&(pkt->transform), base, rem, idx); + + return retval; +} + + +int encode_PEER_INFO (uint8_t *base, + size_t *idx, + const n2n_common_t *cmn, + const n2n_PEER_INFO_t *pkt) { + + int retval = 0; + + retval += encode_common(base, idx, cmn); + retval += encode_uint16(base, idx, pkt->aflags); + retval += encode_mac(base, idx, pkt->srcMac); + retval += encode_mac(base, idx, pkt->mac); + retval += encode_sock(base, idx, &pkt->sock); + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += encode_sock(base, idx, &pkt->preferred_sock); + } + retval += encode_uint32(base, idx, (uint32_t)pkt->load); + retval += encode_uint32(base, idx, (uint32_t)pkt->uptime); + retval += encode_buf(base, idx, pkt->version, sizeof(n2n_version_t)); + + return retval; +} + + +int decode_PEER_INFO (n2n_PEER_INFO_t *pkt, + const n2n_common_t *cmn, /* info on how to interpret it */ + const uint8_t *base, + size_t *rem, + size_t *idx) { + + size_t retval = 0; + memset(pkt, 0, sizeof(n2n_PEER_INFO_t)); + + retval += decode_uint16(&(pkt->aflags), base, rem, idx); + retval += decode_mac(pkt->srcMac, base, rem, idx); + retval += decode_mac(pkt->mac, base, rem, idx); + retval += decode_sock(&pkt->sock, base, rem, idx); + if(cmn->flags & N2N_FLAGS_SOCKET) { + retval += decode_sock(&pkt->preferred_sock, base, rem, idx); + } + retval += decode_uint32(&pkt->load, base, rem, idx); + retval += decode_uint32((uint32_t*)&pkt->uptime, base, rem, idx); + retval += decode_buf((uint8_t*)pkt->version, sizeof(n2n_version_t), base, rem, idx); + + return retval; +} + + +int encode_QUERY_PEER (uint8_t * base, + size_t * idx, + const n2n_common_t * common, + const n2n_QUERY_PEER_t * pkt) { + + int retval = 0; + + retval += encode_common(base, idx, common); + retval += encode_mac(base, idx, pkt->srcMac); + retval += encode_mac(base, idx, pkt->targetMac); + retval += encode_uint16(base, idx, pkt->aflags); + + return retval; +} + +int decode_QUERY_PEER (n2n_QUERY_PEER_t * pkt, + const n2n_common_t * cmn, /* info on how to interpret it */ + const uint8_t * base, + size_t * rem, + size_t * idx) { + + size_t retval = 0; + memset(pkt, 0, sizeof(n2n_QUERY_PEER_t)); + + retval += decode_mac(pkt->srcMac, base, rem, idx); + retval += decode_mac(pkt->targetMac, base, rem, idx); + retval += decode_uint16(&(pkt->aflags), base, rem, idx); + + return retval; +} diff --git a/bundles/n2n_ntop_v3/supernode.1 b/bundles/n2n_ntop_v3/supernode.1 new file mode 100644 index 00000000..742b826c --- /dev/null +++ b/bundles/n2n_ntop_v3/supernode.1 @@ -0,0 +1,133 @@ +.TH supernode 1 "Jul 16, 2021" "version 3" "USER COMMANDS" +.SH NAME +supernode \- n2n supernode daemon +.SH SYNOPSIS +.B supernode + +.br +.B supernode +[OPTION]... +.SH DESCRIPTION +N2N is a peer-to-peer VPN system. Supernode is a node introduction registry, +broadcast conduit and packet relay node for the n2n system. On startup supernode +begins listening on the specified UDP port for node registrations, and other +packets to route. The supernode can service any number of communities and routes +packets only between members of the same community. The supernode does not hold +the community encryption key and so cannot snoop or inject packets into the +community. +.PP +Supernode can service a number of n2n communities concurrently. Traffic does not +cross between communities. +.PP +All logging goes to stdout. +.PP +The config file is similar to the command line, with one option per line. +Lines starting with a "#" are ignored. +An equal sign ('=') should be used between key and value. Example: -p=7777 +.SH OPTIONS FOR THE UNDERLYING NETWORK CONNECTION +.TP +\fB\-p \fR<\fIlocal_port\fR>, \fB\-\-local-port\fR=<\fIlocal_port\fR> +listen on this fixed local UDP port, defaults to 7654 +.TP +\fB\-F \fR<\fIfed_name\fR> +name of the supernode's federation, defaults to '*Federation' (see also N2N_FEDERATION in ENVIRONMENT) +.TP +\fB\-l \fR<\fIhost:port\fR> +ip address or name, and port of known supernode +.TP +\fB\-m \fR<\fImac_address\fR> +fixed MAC address for the supernode, e.g. + '-m 10:20:30:40:50:60', random otherwise +.TP +\fB\-M\fR +disable MAC and IP address spoofing protection for all +non-username-password-authenticating communities +.TP +\fB\-V \fR<\fIversion_string\fR> +modify the supernode version string which is distributed to the +edges and shown at their management port output, up to 19 characters +.TP +.SH TAP DEVICE AND OVERLAY NETWORK CONFIGURATION +.TP +\fB\-c \fR<\fIpath\fR>, \fB\-\-communities\fR=<\fIpath\fR> +file containing the allowed communities and any User / Password based authentication +details (See ALLOWED COMMUNITIES FILE section) +.TP +\fB\-a \fR<\fInet-net/n\fR>, \fB\-\-autoip\fR= +subnet range for auto ip address service, +.br +e.g. '-a 192.168.0.0-192.168.255.0/24', +.br +defaults to '10.128.255.0-10.255.255.0/24' +.SH LOCAL OPTIONS +.TP +\fB\-f\fR, \fB\-\-foreground\fR +disable daemon mode (UNIX) and run in foreground. +.TP +\fB\-t \fR<\fIport\fR>, \fB\-\-mgmt-port\fR=<\fIport\fR> +management UDP port, for multiple supernodes on a machine, defaults to 5645 +.TP +\fB\-\-management-password \fR<\fIpassword\fR> +sets the password for access to JSON API at the management port, defaults to 'n2n'. The password +has to be provided for relevant access to JSON API at the management port. +.TP +\fB\-v\fR, \fB\-\-verbose\fR +use verbose logging +.TP +\fB\-u \fR<\fIUID\fR> +numeric user ID to use when privileges are dropped +.TP +\fB\-g \fR<\fIGID\fR> +numeric group ID to use when privileges are dropped +.TP +\fB-h\fR +shows a quick reference including all available options +.TP +\fB\-\-help\fR +shows detailed parameter description + +.SH ALLOWED COMMUNITIES FILE +This file is a plain text file. +Comments are introduced with a hash at the beginning of the line. +A line that begins with an asterisk is a user authentication definition and adds an allowed user to the most recently defined community. +Allowed communities can be specified with a regular expression. +.PP +Example community file: +.PP +.nf +.RS +# List of allowed communities +mynetwork +netleo +* logan nHWum+r42k1qDXdIeH-WFKeylK5UyLStRzxofRNAgpG +* sister HwHpPrdMft+38tFDDiunUds6927t0+zhCMMkQdJafcC +.RE +.fi +.PP +More details on creating the allowed communities file are found in the Communities.md and Authentication.md documentation included with this package. +.SH ENVIRONMENT +.TP +.B N2N_FEDERATION +set the federation name so it is not visible at the command line +.SH EXAMPLES +.TP +.B supernode -p 7654 -v +Start supernode listening on UDP port 7654 with verbose output. +.TP +.B echo | nc -w1 -u 127.0.0.1 5645 +Shows the management status of a running supernode. +.PP +.SH RESTART +When supernode restarts it loses all registration information from associated +edge nodes. It can take up to five minutes for the edge nodes to re-register and +normal traffic flow to resume. +.SH EXIT STATUS +supernode is a daemon and any exit is an error +.SH AUTHOR +Luca Deri ( deri (at) ntop.org ), Richard Andrews ( andrews (at) ntop.org ), Don Bindner +.SH SEE ALSO +ifconfig(8) edge(8) +.br +the documentation contained in the source code +.br +the extensive documentation found in n2n's \fBdoc/\fR folder diff --git a/bundles/n2n_ntop_v3/tests/tests-compress.expected b/bundles/n2n_ntop_v3/tests/tests-compress.expected new file mode 100644 index 00000000..6360547d --- /dev/null +++ b/bundles/n2n_ntop_v3/tests/tests-compress.expected @@ -0,0 +1,44 @@ +original: input size = 0x200 +000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +010: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +020: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +030: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +040: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +050: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +060: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +070: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +080: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +090: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +100: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +110: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +120: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +130: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +140: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +150: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +160: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +170: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +180: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +190: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | + +lzo1x: output size = 0x2f +000: 0d 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e | | +010: 0f 20 00 bc 3c 00 00 02 0c 0d 0e 0f 00 01 02 03 | < | +020: 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 11 00 00 | | + +zstd: output size = 0x21 +000: 28 b5 2f fd 60 00 01 bd 00 00 80 00 01 02 03 04 |( / ` | +010: 05 06 07 08 09 0a 0b 0c 0d 0e 0f 01 00 da 47 9d | G | +020: 4b |K| + diff --git a/bundles/n2n_ntop_v3/tests/tests-elliptic.expected b/bundles/n2n_ntop_v3/tests/tests-elliptic.expected new file mode 100644 index 00000000..c60ce1b5 --- /dev/null +++ b/bundles/n2n_ntop_v3/tests/tests-elliptic.expected @@ -0,0 +1,11 @@ +environment: input +000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | | +010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 | | +environment: key +000: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU| +010: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU| + +curve25519: output +000: 7f 42 1b f9 34 5a 59 84 4a 30 bc 53 64 74 fa 7c | B 4ZY J0 Sdt || +010: 15 81 77 a4 4d 34 6d 2f 8b c1 8c 05 d6 a9 44 54 | w M4m/ DT| + diff --git a/bundles/n2n_ntop_v3/tests/tests-hashing.expected b/bundles/n2n_ntop_v3/tests/tests-hashing.expected new file mode 100644 index 00000000..1f29fa95 --- /dev/null +++ b/bundles/n2n_ntop_v3/tests/tests-hashing.expected @@ -0,0 +1,36 @@ +environment: input size = 0x200 +000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +010: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +020: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +030: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +040: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +050: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +060: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +070: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +080: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +090: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +100: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +110: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +120: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +130: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +140: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +150: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +160: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +170: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +180: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +190: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | + +pearson: output = 0xb2d98fa82ea108be + diff --git a/bundles/n2n_ntop_v3/tests/tests-transform.expected b/bundles/n2n_ntop_v3/tests/tests-transform.expected new file mode 100644 index 00000000..14276cf2 --- /dev/null +++ b/bundles/n2n_ntop_v3/tests/tests-transform.expected @@ -0,0 +1,225 @@ +environment: community_name = "abc123def456" +environment: encrypt_key = "SoMEVer!S$cUREPassWORD" +environment: input size = 0x200 +000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +010: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +020: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +030: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +040: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +050: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +060: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +070: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +080: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +090: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +0f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +100: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +110: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +120: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +130: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +140: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +150: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +160: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +170: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +180: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +190: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1a0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1b0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1c0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1d0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1e0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | +1f0: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | | + +null: output size = 0x226 +000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | | +020: 02 03 04 05 00 00 00 01 02 03 04 05 06 07 08 09 | | +030: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +040: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +050: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +060: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +070: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +080: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +090: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0a0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0b0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0c0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0d0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0e0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +0f0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +100: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +110: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +120: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +130: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +140: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +150: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +160: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +170: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +180: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +190: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1a0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1b0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1c0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1d0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1e0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +1f0: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +200: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +210: 0a 0b 0c 0d 0e 0f 00 01 02 03 04 05 06 07 08 09 | | +220: 0a 0b 0c 0d 0e 0f | | + +tf: output size = 0x236 +000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | | +020: 02 03 04 05 00 00 69 54 ba b7 b9 00 7e 1f 4e 43 | iT ~ NC| +030: 6b 6e c0 b7 5a bb e1 6a 7d 8b f6 41 9e fb 7e c1 |kn Z j} A ~ | +040: a8 6c 67 6b c7 27 17 32 9b 89 f2 5d 1d 67 49 de | lgk ' 2 ] gI | +050: ab 5c d4 b7 a1 97 99 76 7d 90 8d 2c 7c 0d 65 66 | \ v} ,| ef| +060: d5 7f 1a 3b bf 0c 52 b3 42 0d c8 c8 0d 62 8e 4b | ; R B b K| +070: 98 7b bc 0d 9c db bf 61 dc 9d 9f 44 a4 fc 8d 1a | { a D | +080: 70 f0 14 87 89 0e 4a b8 7e 66 72 7a 04 6e 9b 17 |p J ~frz n | +090: e1 2c 06 ce 52 04 2a a0 0f 7f 76 f4 5c c5 e2 09 | , R * v \ | +0a0: f6 35 ff ad 87 ab 72 5a 6f bc 61 78 f6 3c 48 e2 | 5 rZo ax | +1a0: a7 fc d2 83 5b 61 b1 e0 fd 28 d1 ec 65 a2 cf 6c | [a ( e l| +1b0: ef 3b ad cc 75 e3 f9 71 0f 90 71 a6 bc 1a d5 17 | ; u q q | +1c0: 65 64 3e 0c d2 c8 de bd 1f d5 af 84 fc fe aa bd |ed> | +1d0: c5 88 13 af 09 ee 8c c0 38 49 79 09 a7 7a 01 48 | 8Iy z H| +1e0: 2e 3e 9a 38 1b c6 b8 c0 a9 4e 61 0f 19 2a 95 84 |.> 8 Na * | +1f0: 3b 53 1c db 9a ec af 8f 2d af 73 d5 cc 71 bd 42 |;S - s q B| +200: 4f e2 70 ca 45 b6 44 18 54 fe 6b 23 31 ba f4 b1 |O p E D T k#1 | +210: 02 a1 26 4f f1 a9 c0 78 e6 3b 11 9e d6 3c 61 e5 | &O x ;
e 9 | +150: c2 4c 3d 3e 73 a7 15 fc 28 6c a6 e5 8b 16 bd c9 | L=>s (l | +160: e2 c9 5e d9 64 8e bc f5 92 a4 e5 74 04 cb 9c 90 | ^ d t | +170: 0c 10 28 5f 30 10 61 b7 44 50 b1 f9 3e 21 a1 41 | (_0 a DP >! A| +180: c2 e2 a5 e9 f7 33 16 52 32 61 d1 a3 c5 0b 61 d4 | 3 R2a a | +190: 53 0f 65 a8 d9 e1 fb e1 9b 1b 61 16 d1 75 0a 4b |S e a u K| +1a0: 9a 9f d1 f3 4e f6 ca b2 a2 24 50 8b 10 4d 45 54 | N $P MET| +1b0: 3d e1 c2 8f 07 52 67 52 7e d1 7f 99 3c 4e de eb |= RgR~ g|[2 6. | +080: 74 50 9f a3 de 38 4e c7 ca 6b 35 7c 1b 4e 39 ea |tP 8N k5| N9 | +090: 5f e2 8a 80 d9 58 6e 14 32 bf 8e e9 a2 b0 19 8a |_ Xn 2 | +0a0: e1 1d da fa 3f 4a b7 1c 03 e0 e3 17 85 54 84 c8 | ?J T | +0b0: 3e 90 8e 85 5b e7 12 3d 73 9e b9 ef 7e 48 c0 55 |> [ =s ~H U| +0c0: 59 28 29 f4 d1 12 62 b3 b3 db 65 0a 6c 8c 44 be |Y() b e l D | +0d0: e2 76 49 e6 b6 4a 9e 7e 9c 49 c9 10 d3 dc 85 33 | vI J ~ I 3| +0e0: fe eb a5 dc 5e 18 cf dc 9a 99 da bc 5c 9f c1 ff | ^ \ | +0f0: 9c 92 3b a9 9d d6 5d 03 f4 f3 5e a9 52 21 d2 d0 | ; ] ^ R! | +100: 8b 4e 8a b6 06 af 4e 34 98 e2 bc 9b c2 f1 9d 72 | N N4 r| +110: f8 0f f3 d5 83 34 7d 47 fe bf 6c 1d c2 d3 89 a4 | 4}G l | +120: ff 5b 76 3c cb 9b 4d 09 a6 3a a2 2f 0b 8d 7a 34 | [v< M : / z4| +130: 12 d5 73 c4 bc ba 13 76 e7 69 50 6d 50 ab 76 b5 | s v iPmP v | +140: a6 fb b4 fb c7 98 3d ac ce e1 e1 98 97 9f 24 98 | = $ | +150: 90 82 61 00 38 57 b0 36 7d 55 a7 70 9c ee 51 26 | a 8W 6}U p Q&| +160: 47 02 4f b5 fe cc 2c e0 07 c6 7b 04 6d a1 89 dc |G O , { m | +170: e8 98 71 fd 27 54 d1 f1 2d 0b 3e 64 ef 02 74 71 | q 'T - >d tq| +180: db f5 b1 84 87 6d c9 37 c5 c3 3a de ea 1b 53 d3 | m 7 : S | +190: f1 ed 8f 24 2d 74 a3 77 23 20 9b 75 c3 f2 ef 4a | $-t w# u J| +1a0: 75 ec d3 86 59 11 c5 fc b0 ed 79 b0 8e a8 03 c8 |u Y y | +1b0: 3e 05 db b0 65 62 53 e5 ef e7 95 88 ce 62 89 7a |> ebS b z| +1c0: 9d 3c bc ea a4 3a f6 df 1d 10 8a a3 80 7c 3b 80 | < : |; | +1d0: be 0a 27 76 2b bc 7d 02 98 bf b7 5e 4a 4c 53 df | 'v+ } ^JLS | +1e0: 57 ff 67 7e 33 6a 00 4c ff d6 c0 ff 3f 1c 24 f7 |W g~3j L ? $ | +1f0: fb fd 3b d2 4f 18 e3 9d 62 5b 9b 15 68 13 44 d8 | ; O b[ h D | +200: 71 79 9d b1 ab 2f bd f3 44 6b 77 96 b8 44 bc 90 |qy / Dkw D | +210: 1f 74 db d2 73 7d 5d 44 f7 a6 92 4e fa 24 e3 92 | t s}]D N $ | +220: c8 34 c7 1d 16 8b f5 80 d9 15 48 24 12 16 14 76 | 4 H$ v| +230: 15 5f d0 dc 1e 9c | _ | + +speck: output size = 0x236 +000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | | +020: 02 03 04 05 00 00 69 c2 17 4a ab 55 f3 8d 44 17 | i J U D | +030: 2c 31 09 b5 b0 2f 0c 87 f2 05 13 59 34 49 72 45 |,1 / Y4IrE| +040: 2c 79 51 cf 39 f5 ce 0e b9 fc c8 41 31 08 e9 a5 |,yQ 9 A1 | +050: 54 3c aa 77 aa 29 10 41 4a 16 4b e9 89 8f 92 7b |T< w ) AJ K {| +060: 29 b3 0b 4b 84 92 2a 3a fe bd c0 50 75 fc a4 7e |) K *: Pu ~| +070: 4e 20 2e 3b 53 eb d1 37 43 35 b6 5e 55 a6 5e 0e |N .;S 7C5 ^U ^ | +080: e3 05 db 07 5f a8 74 4d 9f 41 ed 5f 44 93 98 9b | _ tM A _D | +090: fb 48 3c 9c 36 8b a6 71 ed ee f4 e6 10 21 b1 b5 | H< 6 q ! | +0a0: f4 b7 28 db d5 5d 43 3d 4b 8d 1a 33 cf c5 54 09 | ( ]C=K 3 T | +0b0: b6 9d f5 f2 27 2f e7 be dd 4c 3c 5c c8 71 ca 71 | '/ L<\ q q| +0c0: 8c 47 37 21 6c ad 3f d6 9a 99 ab 18 fc d8 1b c7 | G7!l ? | +0d0: 72 c2 7d fb 57 8c 97 4f 77 4c 6c 94 4a ab f4 94 |r } W OwLl J | +0e0: d8 e3 02 e2 b9 bf 12 47 fb 53 aa b8 4a 93 38 c6 | G S J 8 | +0f0: bb 8b 27 8b d6 db f3 e4 e3 43 7e 7f 83 cf c9 df | ' C~ | +100: e5 71 b9 80 9c ad 38 e5 10 aa 99 ad e1 0d 34 6f | q 8 4o| +110: de 7e ff 29 cc fe b5 89 49 a9 a1 b5 9e 9f be 5e | ~ ) I ^| +120: e6 d2 74 2c 57 91 86 40 02 a0 7b 6b 42 6e b0 63 | t,W @ {kBn c| +130: 0e 04 19 7c f0 e5 ff 3d db de e3 c5 fc 70 18 7d | | = p }| +140: 06 33 7e 6a bb 46 3b 94 28 85 87 51 9f 6e 95 22 | 3~j F; ( Q n "| +150: 99 b4 34 bd 29 94 3a a8 a4 ff 5b 19 53 69 cb e5 | 4 ) : [ Si | +160: a6 0c 41 c5 22 89 82 a7 a5 f3 f3 49 ed 5d ce f3 | A " I ] | +170: a7 ee 77 dd a9 aa 26 5b 85 ec b1 6e f4 33 a0 b8 | w &[ n 3 | +180: 93 2a 80 6f 3f 5f 0a ff 1b 72 14 5d 4f 1a cc 74 | * o?_ r ]O t| +190: 69 01 da 81 7d 89 4b 0f 68 fe c6 c5 ae 39 86 1d |i } K h 9 | +1a0: ab e3 c7 35 2e 5d a8 3d 56 3e 26 52 74 72 5b f2 | 5.] =V>&Rtr[ | +1b0: 41 1a 7a 04 d9 d0 65 fe 92 c4 b9 be 75 e5 9e e1 |A z e u | +1c0: 8e 52 f4 27 98 44 61 26 7f 6b 96 0c c4 6a a6 6b | R ' Da& k j k| +1d0: 36 66 81 a1 f6 dd ab 2a a7 63 e5 7f 63 67 79 08 |6f * c cgy | +1e0: ba 7b bb 11 12 9c 14 b2 a4 2b 56 66 14 c1 54 c6 | { +Vf T | +1f0: 96 f0 e4 68 8a 5c 11 b6 27 af 61 ef ab 47 9e 7f | h \ ' a G | +200: 76 0e 39 c3 fb 88 94 29 7c 9e 96 9b e5 e1 6b ae |v 9 )| k | +210: 87 03 a4 86 a2 1f 91 cf 90 1c 11 08 57 bc c7 90 | W | +220: 0b c1 51 2e 28 a6 58 96 e2 e7 f2 20 c6 ac 06 05 | Q.( X | +230: 39 75 4a 56 cf f8 |9uJV | + diff --git a/bundles/n2n_ntop_v3/tests/tests-wire.expected b/bundles/n2n_ntop_v3/tests/tests-wire.expected new file mode 100644 index 00000000..e4ba9de5 --- /dev/null +++ b/bundles/n2n_ntop_v3/tests/tests-wire.expected @@ -0,0 +1,51 @@ +environment: common.ttl = 2 +environment: common.flags = 0 +environment: common.community = "abc123def456z" + +REGISTER: common.pc = 1 +REGISTER: reg.cookie = 0 +REGISTER: reg.srcMac[] = 0:1:2:3:4:5 +REGISTER: reg.dstMac[] = 10:11:12:13:14:15 +REGISTER: reg.dev_addr.net_addr = 0x20212223 +REGISTER: reg.dev_addr.net_bitlen = 25 +REGISTER: reg.dev_desc = "Dummy_Dev_Desc" + +REGISTER: output retval = 0x24 +REGISTER: output idx = 0x3d +000: 03 02 00 01 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 7a 00 00 00 00 00 00 00 00 00 00 00 00 01 02 03 |z | +020: 04 05 10 11 12 13 14 15 20 21 22 23 19 44 75 6d | !"# Dum| +030: 6d 79 5f 44 65 76 5f 44 65 73 63 00 00 |my_Dev_Desc | + +REGISTER_SUPER: common.pc = 5 +REGISTER_SUPER: reg.cookie = 0 +REGISTER_SUPER: reg.edgeMac[] = 20:21:22:23:24:25 +REGISTER_SUPER: reg.dev_addr.net_addr = 0x20212223 +REGISTER_SUPER: reg.dev_addr.net_bitlen = 25 +REGISTER_SUPER: reg.dev_desc = "Dummy_Dev_Desc" +REGISTER_SUPER: reg.auth.scheme = 1 +REGISTER_SUPER: reg.auth.token_size = 16 +REGISTER_SUPER: reg.auth.token[0] = 0xfe +REGISTER_SUPER: reg.key_time = 600 + +REGISTER_SUPER: output retval = 0x36 +REGISTER_SUPER: output idx = 0x4f +000: 03 02 00 05 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 7a 00 00 00 00 00 00 00 00 00 00 00 20 21 22 23 |z !"#| +020: 24 25 20 21 22 23 19 44 75 6d 6d 79 5f 44 65 76 |$% !"# Dummy_Dev| +030: 5f 44 65 73 63 00 00 00 01 00 10 fe 00 00 00 fd |_Desc | +040: 00 00 00 fc 00 00 00 00 00 00 fb 00 00 02 58 | X| + +UNREGISTER_SUPER: common.pc = 6 +UNREGISTER_SUPER: unreg.auth.scheme = 1 +UNREGISTER_SUPER: unreg.auth.token_size = 16 +UNREGISTER_SUPER: unreg.auth.token[0] = 0xfe +UNREGISTER_SUPER: unreg.srcMac[] = 30:31:32:33:34:35 + +UNREGISTER_SUPER: output retval = 0x19 +UNREGISTER_SUPER: output idx = 0x32 +000: 03 02 00 06 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456| +010: 7a 00 00 00 00 00 00 00 00 01 00 10 fe 00 00 00 |z | +020: fd 00 00 00 fc 00 00 00 00 00 00 fb 30 31 32 33 | 0123| +030: 34 35 |45| + diff --git a/bundles/n2n_ntop_v3/tools/Makefile.in b/bundles/n2n_ntop_v3/tools/Makefile.in new file mode 100644 index 00000000..d7bb734a --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/Makefile.in @@ -0,0 +1,42 @@ +# +# This is not a standalone makefile, it must be called from the toplevel +# makefile to inherit the correct environment + +DEBUG?=-g3 + +HEADERS=$(wildcard include/*.h) +CFLAGS+=-I../include +ifeq ($(CONFIG_TARGET),mingw) +CFLAGS+=-I../win32 +endif +CFLAGS+=$(DEBUG) +LDFLAGS+=-L.. + +N2N_LIB=../libn2n.a + +TOOLS=n2n-benchmark n2n-keygen +TOOLS+=@ADDITIONAL_TOOLS@ + +TESTS=tests-compress tests-elliptic tests-hashing tests-transform +TESTS+=tests-wire + +.PHONY: all clean install +all: $(TOOLS) $(TESTS) + +n2n-benchmark.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile +n2n-keygen.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile + +n2n-decode: n2n-decode.c $(N2N_LIB) $(HEADERS) ../Makefile Makefile + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDLIBS) -lpcap -o $@ + +# See comments in the topdir Makefile about how to generate coverage +# data. +gcov: + gcov $(TOOLS) $(TESTS) + +clean: + rm -rf $(TOOLS) *.o *.dSYM *~ + rm -f $(TESTS) *.gcno *.gcda + +install: $(TOOLS) + $(INSTALL_PROG) $(TOOLS) $(SBINDIR)/ diff --git a/bundles/n2n_ntop_v3/tools/n2n-benchmark.c b/bundles/n2n_ntop_v3/tools/n2n-benchmark.c new file mode 100644 index 00000000..13bf7c07 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/n2n-benchmark.c @@ -0,0 +1,428 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#ifndef _MSC_VER +/* MinGW has undefined function gettimeofday() warnings without this header + * but Visual C++ doesnt even have the header */ +#include +#endif + +#include "n2n.h" + +#define DURATION 2.5 // test duration per algorithm +#define PACKETS_BEFORE_GETTIME 2047 // do not check time after every packet but after (2 ^ n - 1) + +/* heap allocation for compression as per lzo example doc */ +#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] +static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); + + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; + +/* Prototypes */ +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ); +static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf); +static void init_compression_for_benchmark(void); +static void deinit_compression_for_benchmark(void); +static void run_compression_benchmark(void); +static void run_hashing_benchmark(void); +static void run_ecc_benchmark(void); + + +int main(int argc, char * argv[]) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + n2n_trans_op_t transop_null, transop_tf; + n2n_trans_op_t transop_aes; + n2n_trans_op_t transop_cc20; + + n2n_trans_op_t transop_speck; + n2n_edge_conf_t conf; + + print_n2n_version(); + + /* Init configuration */ + edge_init_conf_defaults(&conf); + strncpy((char*)conf.community_name, "abc123def456", sizeof(conf.community_name)); + conf.encrypt_key = "SoMEVer!S$cUREPassWORD"; + + pearson_hash_init(); + + /* Init transopts */ + n2n_transop_null_init(&conf, &transop_null); + n2n_transop_tf_init(&conf, &transop_tf); + n2n_transop_aes_init(&conf, &transop_aes); + n2n_transop_cc20_init(&conf, &transop_cc20); + n2n_transop_speck_init(&conf, &transop_speck); + + /* Run the tests */ + run_transop_benchmark("null", &transop_null, &conf, pktbuf); + run_transop_benchmark("tf", &transop_tf, &conf, pktbuf); + run_transop_benchmark("aes", &transop_aes, &conf, pktbuf); + run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf); + run_transop_benchmark("speck", &transop_speck, &conf, pktbuf); + + run_ecc_benchmark(); + + /* Also for compression (init moved here for ciphers get run before in case of lzo init error) */ + init_compression_for_benchmark(); + run_compression_benchmark(); + + run_hashing_benchmark(); + + + /* Cleanup */ + transop_null.deinit(&transop_null); + transop_tf.deinit(&transop_tf); + transop_aes.deinit(&transop_aes); + transop_cc20.deinit(&transop_cc20); + transop_speck.deinit(&transop_speck); + + deinit_compression_for_benchmark(); + + return 0; +} + +// --- compression benchmark -------------------------------------------------------------- + +static void init_compression_for_benchmark(void) { + + if(lzo_init() != LZO_E_OK) { + traceEvent(TRACE_ERROR, "LZO compression init error"); + exit(1); + } + +#ifdef N2N_HAVE_ZSTD + // zstd does not require initialization. if it were required, this would be a good place +#endif +} + + +static void deinit_compression_for_benchmark(void) { + + // lzo1x does not require de-initialization. if it were required, this would be a good place + +#ifdef N2N_HAVE_ZSTD + // zstd does not require de-initialization. if it were required, this would be a good place +#endif +} + + +static void run_compression_benchmark() { + const float target_sec = DURATION; + struct timeval t1; + struct timeval t2; + ssize_t target_usec = target_sec * 1e6; + ssize_t tdiff; // microseconds + size_t num_packets; + float mpps; + uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression + lzo_uint compression_len = N2N_PKT_BUF_SIZE; + uint8_t deflation_buffer[N2N_PKT_BUF_SIZE]; + int64_t deflated_len; + + // compression + printf("{%s}\t%s\t%.1f sec\t(%u bytes)", + "lzo1x", "compr", target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + tdiff = 0; + num_packets = 0; + gettimeofday( &t1, NULL ); + + while(tdiff < target_usec) { + compression_len = N2N_PKT_BUF_SIZE; + if(lzo1x_1_compress(PKT_CONTENT, sizeof(PKT_CONTENT), compression_buffer, &compression_len, wrkmem) != LZO_E_OK) { + printf("\n\t compression error\n"); + exit(1); + } + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + + // decompression + printf("\t%s\t%.1f sec\t(%u bytes)", + "decompr", target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + tdiff = 0; + num_packets = 0; + gettimeofday( &t1, NULL ); + + while(tdiff < target_usec) { + deflated_len = N2N_PKT_BUF_SIZE; + lzo1x_decompress (compression_buffer, compression_len, deflation_buffer, (lzo_uint*)&deflated_len, NULL); + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + if(memcmp(deflation_buffer, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) + printf("\n\tdecompression error\n"); + printf ("\n"); + +#ifdef N2N_HAVE_ZSTD + // compression + printf("{%s}\t%s\t%.1f sec\t(%u bytes)", + "zstd", "compr", target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + tdiff = 0; + num_packets = 0; + gettimeofday( &t1, NULL ); + while(tdiff < target_usec) { + compression_len = N2N_PKT_BUF_SIZE; + compression_len = ZSTD_compress(compression_buffer, compression_len, PKT_CONTENT, sizeof(PKT_CONTENT), ZSTD_COMPRESSION_LEVEL) ; + if(ZSTD_isError(compression_len)) { + printf("\n\t compression error\n"); + exit(1); + } + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + + // decompression + printf("\t%s\t%.1f sec\t(%u bytes)", + "decompr", target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + tdiff = 0; + num_packets = 0; + gettimeofday( &t1, NULL ); + while(tdiff < target_usec) { + deflated_len = N2N_PKT_BUF_SIZE; + deflated_len = (int32_t)ZSTD_decompress (deflation_buffer, deflated_len, compression_buffer, compression_len); + if(ZSTD_isError(deflated_len)) { + printf("\n\tdecompression error '%s'\n", + ZSTD_getErrorName(deflated_len)); + exit(1); + } + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)compression_len, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + if(memcmp(deflation_buffer, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) + printf("\n\tdecompression error\n"); + printf ("\n"); +#endif +} + +// --- hashing benchmark ------------------------------------------------------------------ + +static void run_hashing_benchmark(void) { + const float target_sec = DURATION; + struct timeval t1; + struct timeval t2; + ssize_t nw; + ssize_t target_usec = target_sec * 1e6; + ssize_t tdiff = 0; // microseconds + size_t num_packets = 0; + + uint64_t hash; + + printf("(%s)\t%s\t%.1f sec\t(%u bytes)", + "prs64", "hash", target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + + gettimeofday( &t1, NULL ); + nw = 8; + + while(tdiff < target_usec) { + hash = pearson_hash_64(PKT_CONTENT, sizeof(PKT_CONTENT)); + hash++; // clever compiler finds out that we do no use the variable + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + + float mpps = num_packets / (tdiff / 1e6) / 1e6; + + printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + printf("\n"); +} + +// --- ecc benchmark ---------------------------------------------------------------------- + +static void run_ecc_benchmark(void) { + const float target_sec = DURATION; + struct timeval t1; + struct timeval t2; + ssize_t nw; + ssize_t target_usec = target_sec * 1e6; + ssize_t tdiff = 0; // microseconds + size_t num_packets = 0; + + unsigned char b[32]; + unsigned char k[32]; + + memset(b, 0x00, 31); + b[31] = 9; + + memset(k, 0x55, 32); + + printf("[%s]\t%s\t%.1f sec\t(%u bytes) ", + "curve", "25519", target_sec, 32); + fflush(stdout); + + gettimeofday( &t1, NULL ); + nw = 32; + + while(tdiff < target_usec) { + curve25519(b, k, b); + num_packets++; + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + + float mpps = num_packets / (tdiff / 1e6) / 1e6; + + printf(" ---> (%u bytes)\t%12u ops\t%8.1f Kops/s\n", + (unsigned int)nw, (unsigned int)num_packets, mpps * 1e3); + printf("\n"); +} + +// --- cipher benchmark ------------------------------------------------------------------- + +static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) { + n2n_common_t cmn; + n2n_PACKET_t pkt; + n2n_mac_t mac_buf; + uint8_t decodebuf[N2N_PKT_BUF_SIZE]; + const float target_sec = DURATION; + struct timeval t1; + struct timeval t2; + size_t idx; + size_t rem; + size_t nw; + ssize_t target_usec = target_sec * 1e6; + ssize_t tdiff; // microseconds + size_t num_packets; + float mpps; + + // encryption + printf("[%s]\t%s\t%.1f sec\t(%u bytes)", + op_name, "encrypt" , target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + memset(mac_buf, 0, sizeof(mac_buf)); + num_packets = 0; + tdiff = 0; + gettimeofday( &t1, NULL ); + while(tdiff < target_usec) { + nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, conf->community_name); + nw += op_fn->fwd(op_fn, + pktbuf+nw, N2N_PKT_BUF_SIZE-nw, + PKT_CONTENT, sizeof(PKT_CONTENT), mac_buf); + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + + // decrpytion + printf("\t%s\t%.1f sec\t(%u bytes)", + "decrypt" , target_sec, (unsigned int)sizeof(PKT_CONTENT)); + fflush(stdout); + num_packets = 0; + tdiff = 0; + gettimeofday( &t1, NULL ); + while(tdiff < target_usec) { + idx=0; + rem=nw; + decode_common( &cmn, pktbuf, &rem, &idx); + decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx ); + op_fn->rev(op_fn, decodebuf, N2N_PKT_BUF_SIZE, pktbuf+idx, rem, 0); + num_packets++; + if (!(num_packets & PACKETS_BEFORE_GETTIME)) { + gettimeofday( &t2, NULL ); + tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec); + } + } + mpps = num_packets / (tdiff / 1e6) / 1e6; + printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n", + (unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT)); + if(memcmp(decodebuf, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) + printf("\tpayload decryption failed!\n"); + printf("\n"); +} + + +static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) +{ + n2n_mac_t destMac={0,1,2,3,4,5}; + n2n_common_t cmn; + n2n_PACKET_t pkt; + size_t idx; + + + memset( &cmn, 0, sizeof(cmn) ); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy( cmn.community, c, N2N_COMMUNITY_SIZE ); + + memset( &pkt, 0, sizeof(pkt) ); + memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE); + memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE); + + pkt.sock.family=0; /* do not encode sock */ + + idx=0; + encode_PACKET( pktbuf, &idx, &cmn, &pkt ); + traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx ); + + return idx; +} diff --git a/bundles/n2n_ntop_v3/tools/n2n-decode.c b/bundles/n2n_ntop_v3/tools/n2n-decode.c new file mode 100644 index 00000000..e0c9a9ad --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/n2n-decode.c @@ -0,0 +1,371 @@ +/** + * (C) 2019-21 - ntop.org and contributors + * + * 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 3 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 see see + * + */ + +#include +#include "n2n.h" + +#define SNAPLEN 1500 +#define TIMEOUT 200 + +/* *************************************************** */ + +static int aes_mode = 0; +static int running = 1; +static char *ifname = NULL; +static n2n_edge_conf_t conf; +static n2n_trans_op_t transop; +static pcap_t *handle; +static pcap_dumper_t *dumper; + +/* *************************************************** */ + +static void help() { + fprintf(stderr, "n2n-decode -i ifname -k key -c community [-B bpf] [-w fname] [-v]" +#ifdef N2N_HAVE_AES + " [-A]" +#endif + "\n"); + fprintf(stderr, "-i | Specify the capture interface name.\n"); + fprintf(stderr, "-c | Specify the community.\n"); + fprintf(stderr, "-k | Specify the encryption key.\n"); +#ifdef N2N_HAVE_AES + fprintf(stderr, "-A | Use AES decryption (default=use twofish).\n"); +#endif + fprintf(stderr, "-B | Use set a BPF filter for the capture.\n"); + fprintf(stderr, "-w | Write decoded PCAP to file.\n"); + fprintf(stderr, "-v | Increase verbosity level.\n"); + + exit(0); +} + +/* *************************************************** */ + +#ifdef WIN32 +BOOL WINAPI term_handler(DWORD sig) +#else +static void term_handler(int sig) +#endif +{ + static int called = 0; + + if(called) { + traceEvent(TRACE_NORMAL, "Ok I am leaving now"); + _exit(0); + } else { + traceEvent(TRACE_NORMAL, "Shutting down..."); + called = 1; + } + + running = 0; +#ifdef WIN32 + return(TRUE); +#endif +} + +/* *************************************************** */ + +static void write_packet(const u_char *packet, struct pcap_pkthdr *hdr) { + pcap_dump((unsigned char*)dumper, hdr, packet); + pcap_dump_flush(dumper); +} + +/* *************************************************** */ + +static int decode_encrypted_packet(const u_char *packet, struct pcap_pkthdr *header, + n2n_PACKET_t *pkt, int encrypted_offset) { + uint8_t decoded_packet[encrypted_offset + N2N_PKT_BUF_SIZE]; + int decoded_eth_size; + int transop_shift; + + switch(pkt->transform) { + case N2N_TRANSFORM_ID_NULL: + /* Not encrypted, dump it */ + write_packet(packet, header); + break; + case N2N_TRANSFORM_ID_TWOFISH: + if(aes_mode) { + traceEvent(TRACE_INFO, "Skipping twofish encrypted packet"); + return(-1); + } + break; + case N2N_TRANSFORM_ID_AES: + if(!aes_mode) { + traceEvent(TRACE_INFO, "Skipping AES encrypted packet"); + return(-1); + } + break; + default: + traceEvent(TRACE_INFO, "Skipping unknown transform packet: %d", pkt->transform); + return(-2); + } + + decoded_eth_size = transop.rev(&transop, decoded_packet+encrypted_offset, N2N_PKT_BUF_SIZE, packet + encrypted_offset, + header->caplen - encrypted_offset, pkt->srcMac); + + transop_shift = (header->caplen - encrypted_offset) - decoded_eth_size; + + if(transop_shift >= 0) { + int transform_id_offset = encrypted_offset - 2; + + /* Copy the initial part of the packet */ + memcpy(decoded_packet, packet, encrypted_offset); + + /* Change the packet transform to NULL as there is now plaintext data */ + *((u_int16_t*)(decoded_packet + transform_id_offset)) = htons(N2N_TRANSFORM_ID_NULL); + + // TODO fix IP and UDP chechsums + write_packet(decoded_packet, header); + return(0); + } + + traceEvent(TRACE_INFO, "Something was wrong in the decoding"); + return(-3); +} + +/* *************************************************** */ + +#define ETH_SIZE 14 +#define UDP_SIZE 8 +#define MIN_IP_SIZE 20 +#define MIN_LEN (ETH_SIZE + UDP_SIZE + MIN_IP_SIZE + sizeof(n2n_common_t)) + +static int run_packet_loop() { + struct pcap_pkthdr header; + const u_char *packet; + + traceEvent(TRACE_NORMAL, "Capturing packets on %s...", ifname); + + while(running) { + n2n_common_t common; + n2n_PACKET_t pkt; + uint ipsize, common_offset; + size_t idx, rem; + + memset(&common, 0, sizeof(common)); + memset(&pkt, 0, sizeof(pkt)); + + packet = pcap_next(handle, &header); + + if(!packet) + continue; + + if(header.caplen < MIN_LEN) { + traceEvent(TRACE_INFO, "Skipping packet too small: size=%d", header.caplen); + continue; + } + + if(ntohs(*(uint16_t*)(packet + 12)) != 0x0800) { + traceEvent(TRACE_INFO, "Skipping non IPv4 packet"); + continue; + } + + if(packet[ETH_SIZE + 9] != IPPROTO_UDP) { + traceEvent(TRACE_INFO, "Skipping non UDP packet"); + continue; + } + + ipsize = (packet[ETH_SIZE] & 0x0F) * 4; + common_offset = ETH_SIZE + ipsize + UDP_SIZE; + + idx = common_offset; + rem = header.caplen - idx; + + if(decode_common(&common, packet, &rem, &idx) == -1) { + traceEvent(TRACE_INFO, "Skipping packet, decode common failed"); + continue; + } + + if(strncmp((char*)conf.community_name, (char*)common.community, N2N_COMMUNITY_SIZE) != 0) { + traceEvent(TRACE_INFO, "Skipping packet with non-matching community"); + continue; + } + + switch(common.pc) { + case n2n_ping: + case n2n_register: + case n2n_deregister: + case n2n_register_ack: + case n2n_register_super: + case n2n_register_super_ack: + case n2n_register_super_nak: + case n2n_federation: + case n2n_peer_info: + case n2n_query_peer: + write_packet(packet, &header); + break; + case n2n_packet: + decode_PACKET(&pkt, &common, packet, &rem, &idx); + decode_encrypted_packet(packet, &header, &pkt, idx); + break; + default: + traceEvent(TRACE_INFO, "Skipping packet with unknown type: %d", common.pc); + continue; + } + } + + return(0); +} + +/* *************************************************** */ + +int main(int argc, char* argv[]) { + u_char c; + struct bpf_program fcode; + char *bpf_filter = NULL, *out_fname = NULL; + char errbuf[PCAP_ERRBUF_SIZE]; + int rv = 0; + FILE *outf = stdout; + + /* Trace to stderr to leave stdout for the PCAP dump if "-w -" is used */ + setTraceFile(stderr); + + /* Init configuration */ + edge_init_conf_defaults(&conf); + + while((c = getopt(argc, argv, + "k:i:B:w:c:v" +#ifdef N2N_HAVE_AES + "A" +#endif + )) != '?') { + if(c == 255) break; + + switch(c) { + case 'c': + strncpy((char*)conf.community_name, optarg, sizeof(conf.community_name)-1); + break; + case 'i': + ifname = strdup(optarg); + break; + case 'k': + conf.encrypt_key = strdup(optarg); + break; + case 'B': + bpf_filter = strdup(optarg); + break; +#ifdef N2N_HAVE_AES + case 'A': + aes_mode = 1; + break; +#endif + case 'w': + if(strcmp(optarg, "-") != 0) + out_fname = strdup(optarg); + break; + case 'v': /* verbose */ + setTraceLevel(getTraceLevel() + 1); + break; + default: + help(); + } + } + + if((ifname == NULL) || (conf.encrypt_key == NULL) || (conf.community_name[0] == '\0')) + help(); + +#ifdef N2N_HAVE_AES + if(aes_mode) + n2n_transop_aes_init(&conf, &transop); + else +#endif + n2n_transop_tf_init(&conf, &transop); + + if((handle = pcap_create(ifname, errbuf)) == NULL) { + traceEvent(TRACE_ERROR, "Cannot open device %s: %s", ifname, errbuf); + return(1); + } + + if((pcap_set_timeout(handle, TIMEOUT) != 0) || + (pcap_set_snaplen(handle, SNAPLEN) != 0)) { + traceEvent(TRACE_ERROR, "Error while setting timeout/snaplen"); + return(1); + } + +#ifdef HAVE_PCAP_IMMEDIATE_MODE + /* The timeout is not honored unless immediate mode is set. + * See https://github.com/mfontanini/libtins/issues/180 */ + if(pcap_set_immediate_mode(handle, 1) != 0) { + traceEvent(TRACE_ERROR, "Could not set PCAP immediate mode"); + return(1); + } +#endif + + if(pcap_activate(handle) != 0) { + traceEvent(TRACE_ERROR, "pcap_activate failed: %s", pcap_geterr(handle)); + } + + if(pcap_datalink(handle) != DLT_EN10MB) { + traceEvent(TRACE_ERROR, "Device %s doesn't provide Ethernet headers - not supported", ifname); + return(2); + } + + if(bpf_filter) { + bpf_u_int32 net, mask; + + if(pcap_lookupnet(ifname, &net, &mask, errbuf) == -1) { + traceEvent(TRACE_WARNING, "Couldn't get netmask for device %s: %s", ifname, errbuf); + net = 0; + mask = 0; + } + + if((pcap_compile(handle, &fcode, bpf_filter, 1, net) < 0) + || (pcap_setfilter(handle, &fcode) < 0)) { + traceEvent(TRACE_ERROR, "Could not set BPF filter: %s", pcap_geterr(handle)); + return(3); + } + } + + if(out_fname) { + outf = fopen(out_fname, "wb"); + + if(outf == NULL) { + traceEvent(TRACE_ERROR, "Could not open %s for write[%d]: %s", errno, strerror(errno)); + return(4); + } + } + + dumper = pcap_dump_fopen(handle, outf); + + if(dumper == NULL) { + traceEvent(TRACE_ERROR, "Could dump file: %s", pcap_geterr(handle)); + return(5); + } + +#ifdef WIN32 + SetConsoleCtrlHandler(term_handler, TRUE); +#else + signal(SIGTERM, term_handler); + signal(SIGINT, term_handler); +#endif + + rv = run_packet_loop(); + + /* Cleanup */ + pcap_close(handle); + + if(conf.encrypt_key) free(conf.encrypt_key); + if(bpf_filter) free(bpf_filter); + if(ifname) free(ifname); + + if(out_fname) { + fclose(outf); + free(out_fname); + } + + return(rv); +} diff --git a/bundles/n2n_ntop_v3/tools/n2n-keygen.c b/bundles/n2n_ntop_v3/tools/n2n-keygen.c new file mode 100644 index 00000000..5cc21db9 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/n2n-keygen.c @@ -0,0 +1,76 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + + +#include "n2n.h" + + +int main(int argc, char * argv[]) { + + n2n_private_public_key_t prv; /* 32 bytes private key */ + n2n_private_public_key_t bin; /* 32 bytes public key binary output buffer */ + char asc[44]; /* 43 bytes + 0-terminator ascii string output */ + uint8_t fed = 0; + + // exactly two parameters required + if(argc != 3) { + // error message to stderr to not interfere with batch usage + fprintf(stderr, "\n" + "n2n-keygen tool\n\n" + " usage: n2n-keygen \n\n" + " or n2n-keygen -F \n\n" + " outputs a line to insert at supernode's community file for user-and-\n" + " password authentication or a command line parameter with the public\n" + " federation key for use at edge's command line, please refer to the\n" + " doc/Authentication.md document or the man pages for more details\n\n"); + return 1; + } + + // federation mode? + if(strcmp(argv[1], "-F") == 0) + fed = 1; + + // derive private key from username and password: + // hash username once, hash password twice (so password is bound + // to username but username and password are not interchangeable), + // finally xor the result + // in federation mode: only hash federation name, twice + generate_private_key(prv, argv[2]); + + // hash user name only if required + if(!fed) { + bind_private_key_to_username(prv, argv[1]); + } + + // calculate the public key into binary output buffer + generate_public_key(bin, prv); + + // clear out the private key + memset(prv, 0, sizeof(prv)); + + // convert binary output to 6-bit-ascii string output + bin_to_ascii(asc, bin, sizeof(bin)); + + // output + if(fed) + fprintf(stdout, "-P %s\n", asc); + else + fprintf(stdout, "%c %s %s\n", N2N_USER_KEY_LINE_STARTER, argv[1], asc); + + return 0; +} diff --git a/bundles/n2n_ntop_v3/tools/tests-compress.c b/bundles/n2n_ntop_v3/tools/tests-compress.c new file mode 100644 index 00000000..f68d5108 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/tests-compress.c @@ -0,0 +1,165 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include + +#include + +#include "n2n.h" +#include "hexdump.h" + +/* heap allocation for compression as per lzo example doc */ +#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] +static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); + + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +}; + +static void init_compression_for_benchmark (void) { + + if(lzo_init() != LZO_E_OK) { + traceEvent(TRACE_ERROR, "LZO compression init error"); + exit(1); + } + +#ifdef N2N_HAVE_ZSTD + // zstd does not require initialization. if it were required, this would be a good place +#endif +} + + +static void deinit_compression_for_benchmark (void) { + + // lzo1x does not require de-initialization. if it were required, this would be a good place + +#ifdef N2N_HAVE_ZSTD + // zstd does not require de-initialization. if it were required, this would be a good place +#endif +} + +void test_lzo1x () { + char *test_name = "lzo1x"; + uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression + lzo_uint compression_len = sizeof(compression_buffer); + + if(lzo1x_1_compress(PKT_CONTENT, sizeof(PKT_CONTENT), compression_buffer, &compression_len, wrkmem) != LZO_E_OK) { + fprintf(stderr, "%s: compression error\n", test_name); + exit(1); + } + + assert(compression_len == 47); + + printf("%s: output size = 0x%" PRIx64 "\n", test_name, compression_len); + fhexdump(0, compression_buffer, compression_len, stdout); + + uint8_t deflation_buffer[N2N_PKT_BUF_SIZE]; + lzo_uint deflated_len; + lzo1x_decompress(compression_buffer, compression_len, deflation_buffer, &deflated_len, NULL); + + assert(deflated_len == sizeof(PKT_CONTENT)); + if(memcmp(PKT_CONTENT, deflation_buffer, deflated_len)!=0) { + fprintf(stderr, "%s: round-trip buffer mismatch\n", test_name); + exit(1); + } + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +void test_zstd () { + char *test_name = "zstd"; + +#ifdef N2N_HAVE_ZSTD + uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression + lzo_uint compression_len = sizeof(compression_buffer); + + compression_len = N2N_PKT_BUF_SIZE; + compression_len = ZSTD_compress(compression_buffer, compression_len, PKT_CONTENT, sizeof(PKT_CONTENT), ZSTD_COMPRESSION_LEVEL); + if(ZSTD_isError(compression_len)) { + fprintf(stderr, "%s: compression error\n", test_name); + exit(1); + } + + assert(compression_len == 33); + + printf("%s: output size = 0x%" PRIx64 "\n", test_name, compression_len); + fhexdump(0, compression_buffer, compression_len, stdout); + + uint8_t deflation_buffer[N2N_PKT_BUF_SIZE]; + int64_t deflated_len = sizeof(deflation_buffer); + deflated_len = (int32_t)ZSTD_decompress(deflation_buffer, deflated_len, compression_buffer, compression_len); + if(ZSTD_isError(deflated_len)) { + fprintf(stderr, "%s: decompression error '%s'\n", + test_name, ZSTD_getErrorName(deflated_len)); + exit(1); + } + + assert(deflated_len == sizeof(PKT_CONTENT)); + if(memcmp(PKT_CONTENT, deflation_buffer, deflated_len)!=0) { + fprintf(stderr, "%s: round-trip buffer mismatch\n", test_name); + exit(1); + } + + fprintf(stderr, "%s: tested\n", test_name); +#else + // FIXME - output dummy data to the stdout for easy comparison + printf("zstd: output size = 0x21\n"); + printf("000: 28 b5 2f fd 60 00 01 bd 00 00 80 00 01 02 03 04 |( / ` |\n"); + printf("010: 05 06 07 08 09 0a 0b 0c 0d 0e 0f 01 00 da 47 9d | G |\n"); + printf("020: 4b |K|\n"); + + fprintf(stderr, "%s: not compiled - dummy data output\n", test_name); +#endif + printf("\n"); +} + + +int main (int argc, char * argv[]) { + + /* Also for compression (init moved here for ciphers get run before in case of lzo init error) */ + init_compression_for_benchmark(); + + printf("%s: input size = 0x%" PRIx64 "\n", "original", sizeof(PKT_CONTENT)); + fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout); + printf("\n"); + + test_lzo1x(); + test_zstd(); + + deinit_compression_for_benchmark(); + + return 0; +} + diff --git a/bundles/n2n_ntop_v3/tools/tests-elliptic.c b/bundles/n2n_ntop_v3/tools/tests-elliptic.c new file mode 100644 index 00000000..3a119bc6 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/tests-elliptic.c @@ -0,0 +1,56 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include "n2n.h" +#include "hexdump.h" + +void test_curve25519 (unsigned char *pkt_input, unsigned char *key) { + char *test_name = "curve25519"; + unsigned char pkt_output[32]; + + curve25519(pkt_output, key, pkt_input); + + printf("%s: output\n", test_name); + fhexdump(0, pkt_output, sizeof(pkt_output), stdout); + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +int main (int argc, char * argv[]) { + char *test_name = "environment"; + + unsigned char key[32]; + unsigned char pkt_input[32]; + + memset(pkt_input, 0, 31); + pkt_input[31] = 9; + + memset(key, 0x55, 32); + + printf("%s: input\n", test_name); + fhexdump(0, pkt_input, sizeof(pkt_input), stdout); + printf("%s: key\n", test_name); + fhexdump(0, key, sizeof(key), stdout); + printf("\n"); + + test_curve25519(pkt_input, key); + + return 0; +} + diff --git a/bundles/n2n_ntop_v3/tools/tests-hashing.c b/bundles/n2n_ntop_v3/tools/tests-hashing.c new file mode 100644 index 00000000..51efbeb6 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/tests-hashing.c @@ -0,0 +1,67 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include + +#include "n2n.h" +#include "hexdump.h" + + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +}; + +void test_pearson (void *buf, unsigned int bufsize) { + char *test_name = "pearson"; + + uint64_t hash = pearson_hash_64(buf, bufsize); + + printf("%s: output = 0x%" PRIx64 "\n", test_name, hash); + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +int main (int argc, char * argv[]) { + pearson_hash_init(); + + char *test_name = "environment"; + printf("%s: input size = 0x%" PRIx64 "\n", test_name, sizeof(PKT_CONTENT)); + fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout); + printf("\n"); + + test_pearson(PKT_CONTENT, sizeof(PKT_CONTENT)); + + return 0; +} + diff --git a/bundles/n2n_ntop_v3/tools/tests-transform.c b/bundles/n2n_ntop_v3/tools/tests-transform.c new file mode 100644 index 00000000..1ef42b5e --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/tests-transform.c @@ -0,0 +1,164 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include + +#include "n2n.h" +#include "hexdump.h" + +#define DURATION 2.5 // test duration per algorithm +#define PACKETS_BEFORE_GETTIME 2047 // do not check time after every packet but after (2 ^ n - 1) + + +uint8_t PKT_CONTENT[]={ + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 +}; + +/* Prototypes */ +static ssize_t do_encode_packet ( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ); +static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf); + + +int main (int argc, char * argv[]) { + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + n2n_trans_op_t transop_null, transop_tf; + n2n_trans_op_t transop_aes; + n2n_trans_op_t transop_cc20; + + n2n_trans_op_t transop_speck; + n2n_edge_conf_t conf; + + /* Init configuration */ + edge_init_conf_defaults(&conf); + strncpy((char *)conf.community_name, "abc123def456", sizeof(conf.community_name)); + conf.encrypt_key = "SoMEVer!S$cUREPassWORD"; + + char *test_name = "environment"; + printf("%s: community_name = \"%s\"\n", test_name, conf.community_name); + printf("%s: encrypt_key = \"%s\"\n", test_name, conf.encrypt_key); + printf("%s: input size = 0x%" PRIx64 "\n", test_name, sizeof(PKT_CONTENT)); + fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout); + printf("\n"); + + /* Init transopts */ + n2n_transop_null_init(&conf, &transop_null); + n2n_transop_tf_init(&conf, &transop_tf); + n2n_transop_aes_init(&conf, &transop_aes); + n2n_transop_cc20_init(&conf, &transop_cc20); + n2n_transop_speck_init(&conf, &transop_speck); + + /* Run the tests */ + /* FIXME: interop tests are pretty useless without the expected encrypted buffer data */ + run_transop_benchmark("null", &transop_null, &conf, pktbuf); + run_transop_benchmark("tf", &transop_tf, &conf, pktbuf); + run_transop_benchmark("aes", &transop_aes, &conf, pktbuf); + run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf); + run_transop_benchmark("speck", &transop_speck, &conf, pktbuf); + + /* Cleanup */ + transop_null.deinit(&transop_null); + transop_tf.deinit(&transop_tf); + transop_aes.deinit(&transop_aes); + transop_cc20.deinit(&transop_cc20); + transop_speck.deinit(&transop_speck); + + return 0; +} + +// --- cipher benchmark ------------------------------------------------------------------- + +static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) { + n2n_common_t cmn; + n2n_PACKET_t pkt; + n2n_mac_t mac_buf; + uint8_t decodebuf[N2N_PKT_BUF_SIZE]; + size_t idx; + size_t rem; + size_t nw; + + // encryption + memset(mac_buf, 0, sizeof(mac_buf)); + + nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, conf->community_name); + nw += op_fn->fwd(op_fn, + pktbuf+nw, N2N_PKT_BUF_SIZE-nw, + PKT_CONTENT, sizeof(PKT_CONTENT), mac_buf); + + printf("%s: output size = 0x%" PRIx64 "\n", op_name, nw); + fhexdump(0, pktbuf, nw, stdout); + + // decrpytion + idx=0; + rem=nw; + decode_common( &cmn, pktbuf, &rem, &idx); + decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx ); + op_fn->rev(op_fn, decodebuf, sizeof(decodebuf), pktbuf+idx, rem, 0); + + if(memcmp(decodebuf, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) { + fprintf(stderr, "%s: round-trip buffer mismatch\n", op_name); + exit(1); + } + + fprintf(stderr, "%s: tested\n", op_name); + printf("\n"); +} + + +static ssize_t do_encode_packet ( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c ) +{ + // FIXME: this is a parameter of the test environment + n2n_mac_t destMac={0,1,2,3,4,5}; + + n2n_common_t cmn; + n2n_PACKET_t pkt; + size_t idx; + + + memset( &cmn, 0, sizeof(cmn) ); + cmn.ttl = N2N_DEFAULT_TTL; + cmn.pc = n2n_packet; + cmn.flags=0; /* no options, not from supernode, no socket */ + memcpy( cmn.community, c, N2N_COMMUNITY_SIZE ); + + memset( &pkt, 0, sizeof(pkt) ); + memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE); + memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE); + + pkt.sock.family=0; /* do not encode sock */ + + idx=0; + encode_PACKET( pktbuf, &idx, &cmn, &pkt ); + traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx ); + + return idx; +} diff --git a/bundles/n2n_ntop_v3/tools/tests-wire.c b/bundles/n2n_ntop_v3/tools/tests-wire.c new file mode 100644 index 00000000..9e14f018 --- /dev/null +++ b/bundles/n2n_ntop_v3/tools/tests-wire.c @@ -0,0 +1,201 @@ +/* + * (C) 2007-21 - ntop.org and contributors + * + * 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 3 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, see + * + */ + +#include + +#include "n2n.h" +#include "hexdump.h" + +void init_ip_subnet (n2n_ip_subnet_t * d) { + d->net_addr = 0x20212223; + d->net_bitlen = 25; +} + +void print_ip_subnet (char *test_name, char *field, n2n_ip_subnet_t * d) { + printf("%s: %s.net_addr = 0x%08x\n", + test_name, field, d->net_addr); + printf("%s: %s.net_bitlen = %i\n", + test_name, field, d->net_bitlen); +} + +void init_mac (n2n_mac_t mac, const uint8_t o0, const uint8_t o1, + const uint8_t o2, const uint8_t o3, + const uint8_t o4, const uint8_t o5) { + mac[0] = o0; + mac[1] = o1; + mac[2] = o2; + mac[3] = o3; + mac[4] = o4; + mac[5] = o5; +} + +void print_mac (char *test_name, char *field, n2n_mac_t mac) { + printf("%s: %s[] = %x:%x:%x:%x:%x:%x\n", + test_name, field, + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); +} + +void init_auth (n2n_auth_t *auth) { + auth->scheme = n2n_auth_simple_id; + auth->token_size = 16; + auth->token[0] = 0xfe; + auth->token[4] = 0xfd; + auth->token[8] = 0xfc; + auth->token[15] = 0xfb; +} + +void print_auth (char *test_name, char *field, n2n_auth_t *auth) { + printf("%s: %s.scheme = %i\n", test_name, field, auth->scheme); + printf("%s: %s.token_size = %i\n", test_name, field, auth->token_size); + printf("%s: %s.token[0] = 0x%02x\n", test_name, field, auth->token[0]); +} + +void init_common (n2n_common_t *common, char *community) { + memset( common, 0, sizeof(*common) ); + common->ttl = N2N_DEFAULT_TTL; + common->flags = 0; + strncpy( (char *)common->community, community, N2N_COMMUNITY_SIZE); + common->community[N2N_COMMUNITY_SIZE - 1] = '\0'; +} + +void print_common (char *test_name, n2n_common_t *common) { + printf("%s: common.ttl = %i\n", test_name, common->ttl); + printf("%s: common.flags = %i\n", test_name, common->flags); + printf("%s: common.community = \"%s\"\n", test_name, common->community); +} + +void test_REGISTER (n2n_common_t *common) { + char *test_name = "REGISTER"; + + common->pc = n2n_register; + printf("%s: common.pc = %i\n", test_name, common->pc); + + n2n_REGISTER_t reg; + memset( ®, 0, sizeof(reg) ); + init_mac( reg.srcMac, 0,1,2,3,4,5); + init_mac( reg.dstMac, 0x10,0x11,0x12,0x13,0x14,0x15); + init_ip_subnet(®.dev_addr); + strcpy( (char *)reg.dev_desc, "Dummy_Dev_Desc" ); + + printf("%s: reg.cookie = %i\n", test_name, reg.cookie); + print_mac(test_name, "reg.srcMac", reg.srcMac); + print_mac(test_name, "reg.dstMac", reg.dstMac); + // TODO: print reg.sock + print_ip_subnet(test_name, "reg.dev_addr", ®.dev_addr); + printf("%s: reg.dev_desc = \"%s\"\n", test_name, reg.dev_desc); + printf("\n"); + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + size_t retval = encode_REGISTER( pktbuf, &idx, common, ®); + + printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval); + printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx); + fhexdump(0, pktbuf, idx, stdout); + + // TODO: decode_REGISTER() and print + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +void test_REGISTER_SUPER (n2n_common_t *common) { + char *test_name = "REGISTER_SUPER"; + + common->pc = n2n_register_super; + printf("%s: common.pc = %i\n", test_name, common->pc); + + n2n_REGISTER_SUPER_t reg; + memset( ®, 0, sizeof(reg) ); + init_mac( reg.edgeMac, 0x20,0x21,0x22,0x23,0x24,0x25); + // n2n_sock_t sock + init_ip_subnet(®.dev_addr); + strcpy( (char *)reg.dev_desc, "Dummy_Dev_Desc" ); + init_auth(®.auth); + reg.key_time = 600; + + + printf("%s: reg.cookie = %i\n", test_name, reg.cookie); + print_mac(test_name, "reg.edgeMac", reg.edgeMac); + // TODO: print reg.sock + print_ip_subnet(test_name, "reg.dev_addr", ®.dev_addr); + printf("%s: reg.dev_desc = \"%s\"\n", test_name, reg.dev_desc); + print_auth(test_name, "reg.auth", ®.auth); + printf("%s: reg.key_time = %" PRIi32 "\n", test_name, reg.key_time); + printf("\n"); + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + size_t retval = encode_REGISTER_SUPER( pktbuf, &idx, common, ®); + + printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval); + printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx); + fhexdump(0, pktbuf, idx, stdout); + + // TODO: decode_REGISTER_SUPER() and print + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +void test_UNREGISTER_SUPER (n2n_common_t *common) { + char *test_name = "UNREGISTER_SUPER"; + + common->pc = n2n_unregister_super; + printf("%s: common.pc = %i\n", test_name, common->pc); + + n2n_UNREGISTER_SUPER_t unreg; + memset( &unreg, 0, sizeof(unreg) ); + init_auth(&unreg.auth); + init_mac( unreg.srcMac, 0x30,0x31,0x32,0x33,0x34,0x35); + + + print_auth(test_name, "unreg.auth", &unreg.auth); + print_mac(test_name, "unreg.srcMac", unreg.srcMac); + printf("\n"); + + uint8_t pktbuf[N2N_PKT_BUF_SIZE]; + size_t idx = 0; + size_t retval = encode_UNREGISTER_SUPER( pktbuf, &idx, common, &unreg); + + printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval); + printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx); + fhexdump(0, pktbuf, idx, stdout); + + // TODO: decode_UNREGISTER_SUPER() and print + + fprintf(stderr, "%s: tested\n", test_name); + printf("\n"); +} + +int main (int argc, char * argv[]) { + char *test_name = "environment"; + + n2n_common_t common; + init_common( &common, "abc123def456z" ); + print_common( test_name, &common ); + printf("\n"); + + test_REGISTER(&common); + test_REGISTER_SUPER(&common); + test_UNREGISTER_SUPER(&common); + // TODO: add more wire tests + + return 0; +} + diff --git a/bundles/n2n_ntop_v3/uncrustify.cfg b/bundles/n2n_ntop_v3/uncrustify.cfg new file mode 100644 index 00000000..baef9cdb --- /dev/null +++ b/bundles/n2n_ntop_v3/uncrustify.cfg @@ -0,0 +1,34 @@ +# Initial rules taken from a quick discussion +# (See https://github.com/ntop/n2n/commit/00159d0d012c6836fd972af1748833eeaf50fa22#commitcomment-57137247) + +# 4 space indention (never use tabs) +indent_columns = 4 +indent_with_tabs = 0 +indent_switch_case = 4 + +# space between name and bracket during function define +sp_func_def_paren = force +sp_func_proto_paren = force + +# no space between name and bracket during call +sp_func_call_paren = remove + +# no space after if and while +sp_before_sparen = remove +#sp_while_paren_open = remove # only in newer uncrustify + +# block-braces as seen above +nl_if_brace = remove +nl_brace_else = remove +nl_elseif_brace = remove +nl_else_brace = remove +#nl_before_opening_brace_func_class_def = remove # only in newer uncrustify +nl_for_brace = remove +nl_while_brace = remove + +# multi-line parameters with indentation under the opening bracket +# looks like this is the default, but might be the following: +#indent_func_call_param = false ? + +# Want to keep var definition alignment +#align_keep_extra_space = true diff --git a/bundles/n2n_ntop_v3/win32/CMakeLists.txt b/bundles/n2n_ntop_v3/win32/CMakeLists.txt new file mode 100644 index 00000000..2e96b181 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(n2n_win32 + getopt1.c + getopt.c + wintap.c) +target_link_libraries(n2n_win32 PUBLIC ws2_32.lib) diff --git a/bundles/n2n_ntop_v3/win32/DotNet/n2n.sln b/bundles/n2n_ntop_v3/win32/DotNet/n2n.sln new file mode 100644 index 00000000..95698872 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/DotNet/n2n.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "edge", "n2n.vcproj", "{4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "supernode", "supernode.vcproj", "{BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.ActiveCfg = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Debug|Win32.Build.0 = Debug|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.ActiveCfg = Release|Win32 + {4911ADD4-08A3-4C9F-B9C9-9492DA10D01D}.Release|Win32.Build.0 = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.ActiveCfg = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Debug|Win32.Build.0 = Debug|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.ActiveCfg = Release|Win32 + {BDB93CAB-BE22-4ED6-9A05-2E4D6F1D76E1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bundles/n2n_ntop_v3/win32/DotNet/n2n.suo b/bundles/n2n_ntop_v3/win32/DotNet/n2n.suo new file mode 100644 index 0000000000000000000000000000000000000000..aae212bdc7603fcc776941462dec540d87901d0e GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/bundles/n2n_ntop_v3/win32/DotNet/n2n.vcproj b/bundles/n2n_ntop_v3/win32/DotNet/n2n.vcproj new file mode 100644 index 00000000..d62381d2 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/DotNet/n2n.vcproj @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_ntop_v3/win32/DotNet/supernode.vcproj b/bundles/n2n_ntop_v3/win32/DotNet/supernode.vcproj new file mode 100644 index 00000000..e6a9e0d1 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/DotNet/supernode.vcproj @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/n2n_ntop_v3/win32/Makefile b/bundles/n2n_ntop_v3/win32/Makefile new file mode 100644 index 00000000..3ffda93a --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/Makefile @@ -0,0 +1,19 @@ +# +# This is not a standalone makefile, it must be called from the toplevel +# makefile to inherit the correct environment + +CFLAGS+=-I../include +LDFLAGS+=-L.. + +.PHONY: all clean install + +all: n2n_win32.a + +n2n_win32.a: getopt1.o getopt.o wintap.o + $(AR) rcs $@ $+ + +clean: + rm -rf n2n_win32.a *.o *.gcno *.gcda + +install: + true diff --git a/bundles/n2n_ntop_v3/win32/getopt.c b/bundles/n2n_ntop_v3/win32/getopt.c new file mode 100644 index 00000000..6bbb735a --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/getopt.c @@ -0,0 +1,1074 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include +#ifdef WIN32 +#include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT<_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# ifdef HAVE_LIBINTL_H +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +#ifndef DARWIN +char *optarg; +#endif + + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +#ifndef DARWIN +int optind = 1; +#endif + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +#ifndef DARWIN +#ifdef WIN32 +int opterr = 0; +#else +int opterr = 1; +#endif +#endif + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ +#ifndef DARWIN +int optopt = '?'; +#endif + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +#ifndef WIN32 +# if HAVE_STRING_H +# include +# else +# include +# endif +#endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int print_errors = opterr; + if (optstring[0] == ':') + print_errors = 0; + + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (print_errors) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (print_errors) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (print_errors) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (print_errors) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (print_errors) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt____ (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ + diff --git a/bundles/n2n_ntop_v3/win32/getopt.h b/bundles/n2n_ntop_v3/win32/getopt.h new file mode 100644 index 00000000..b0147e9d --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/getopt.h @@ -0,0 +1,169 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETOPT_H + +#ifndef __need_getopt +# define _GETOPT_H 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +#ifndef __need_getopt +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +# if defined __STDC__ && __STDC__ + const char *name; +# else + char *name; +# endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +# define no_argument 0 +# define required_argument 1 +# define optional_argument 2 +#endif /* need getopt */ + + +/* Get definitions and prototypes for functions to process the + arguments in ARGV (ARGC of them, minus the program name) for + options given in OPTS. + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options + missing arguments, `optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter + takes an argument, to be placed in `optarg'. + + If a letter in OPTS is followed by two colons, its argument is + optional. This behavior is specific to the GNU `getopt'. + + The argument `--' causes premature termination of argument + scanning, explicitly telling `getopt' that there are no more + options. + + If OPTS begins with `--', then non-option arguments are treated as + arguments to the option '\0'. This behavior is specific to the GNU + `getopt'. */ + +#if defined __STDC__ && __STDC__ +# ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int __argc, char *const *__argv, const char *__shortopts); +# else /* not __GNU_LIBRARY__ */ +extern int getopt (); +# endif /* __GNU_LIBRARY__ */ + +# ifndef __need_getopt +extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, + const struct option *__longopts, int *__longind); +extern int getopt_long_only (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int __argc, char *const *__argv, + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only); +# endif +#else /* not __STDC__ */ +extern int getopt (); +# ifndef __need_getopt +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +# endif +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +/* Make sure we later can get all the definitions and declarations. */ +#undef __need_getopt + +#endif /* getopt.h */ diff --git a/bundles/n2n_ntop_v3/win32/getopt1.c b/bundles/n2n_ntop_v3/win32/getopt1.c new file mode 100644 index 00000000..3d264f2d --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/getopt1.c @@ -0,0 +1,188 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/bundles/n2n_ntop_v3/win32/n2n_win32.h b/bundles/n2n_ntop_v3/win32/n2n_win32.h new file mode 100644 index 00000000..8cddbb0e --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/n2n_win32.h @@ -0,0 +1,132 @@ +/* + + (C) 2007-09 - Luca Deri + +*/ + +#ifndef _N2N_WIN32_H_ +#define _N2N_WIN32_H_ + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#define WIN32_LEAN_AND_MEAN + +#if defined(__MINGW32__) +/* should be defined here and before winsock gets included */ +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x501 //Otherwise the linker doesnt find getaddrinfo +#endif /* #ifndef _WIN32_WINNT */ +#include +#endif /* #if defined(__MINGW32__) */ + + +#include +#include +#include +#include +#if defined(_MSC_VER) +#include +#pragma comment(lib,"Iphlpapi.lib") +#endif +#include +#include +#include + + +#include "wintap.h" + +#undef EAFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define MAX(a,b) (a > b ? a : b) +#define MIN(a,b) (a < b ? a : b) + +#define snprintf _snprintf +#define strdup _strdup + +#define socklen_t int + + +/* ************************************* */ + +struct ip { +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#else + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif + u_char ip_tos; /* type of service */ + short ip_len; /* total length */ + u_short ip_id; /* identification */ + short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + + +/* ************************************* */ + + +typedef struct tuntap_dev { + HANDLE device_handle; + char *device_name; + char *ifName; + int if_idx; + OVERLAPPED overlap_read, overlap_write; + n2n_mac_t mac_addr; + uint32_t ip_addr; + uint32_t device_mask; + unsigned int mtu; + unsigned int metric; + unsigned int metric_original; +} tuntap_dev; + + +/* ************************************* */ + + +#define index(a, b) strchr(a, b) +#define sleep(x) Sleep(x * 1000) + + +/* ************************************* */ + + +#define HAVE_PTHREAD +#define pthread_t HANDLE +#define pthread_mutex_t HANDLE + +#define pthread_create(p_thread_handle, attr, thread_func, p_param) \ + (*p_thread_handle = CreateThread(0 /* default security flags */, 0 /*default stack*/, \ + thread_func, p_param, 0 /* default creation flags */, \ + NULL) == 0) + +#define pthread_cancel(p_thread_handle) \ + TerminateThread(p_thread_handle, 0) + +#define pthread_mutex_init(p_mutex_handle, attr) \ + *p_mutex_handle = CreateMutex(NULL /*default security flags */, \ + FALSE /* initially not owned */, NULL /* unnamed */) + +#define pthread_mutex_lock(mutex) \ + WaitForSingleObject(*mutex, INFINITE) + +#define pthread_mutex_trylock(mutex) \ + WaitForSingleObject(*mutex, NULL) + +#define pthread_mutex_unlock(mutex) \ + ReleaseMutex(*mutex) + + +/* ************************************* */ + + +#endif diff --git a/bundles/n2n_ntop_v3/win32/version-msvc.c b/bundles/n2n_ntop_v3/win32/version-msvc.c new file mode 100644 index 00000000..92cce068 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/version-msvc.c @@ -0,0 +1,3 @@ +const char * n2n_sw_version = "2.0.0"; +const char * n2n_sw_osName = "Win32"; +const char * n2n_sw_buildDate = __DATE__ " " __TIME__; diff --git a/bundles/n2n_ntop_v3/win32/winconfig.h b/bundles/n2n_ntop_v3/win32/winconfig.h new file mode 100644 index 00000000..c206f138 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/winconfig.h @@ -0,0 +1,15 @@ +/* winconfig.h. Win32 replacement for file generated from config.h.in by configure. */ + +/* OS name */ +#ifndef PACKAGE_OSNAME +#define PACKAGE_OSNAME N2N_OSNAME +#endif + +/* Define to the version of this package. */ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION N2N_VERSION +#endif +#ifndef GIT_RELEASE +#define GIT_RELEASE N2N_VERSION +#endif + diff --git a/bundles/n2n_ntop_v3/win32/wintap.c b/bundles/n2n_ntop_v3/win32/wintap.c new file mode 100644 index 00000000..6170124c --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/wintap.c @@ -0,0 +1,517 @@ +/* + (C) 2007-09 - Luca Deri +*/ + +#include "n2n.h" +#include "n2n_win32.h" + +/* ***************************************************** */ + +void initWin32() { + WSADATA wsaData; + int err; + + err = WSAStartup(MAKEWORD(2, 2), &wsaData ); + if( err != 0 ) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("FATAL ERROR: unable to initialise Winsock 2.x."); + exit(EXIT_FAILURE); + } +} + + +void destroyWin32() { + WSACleanup(); +} + +struct win_adapter_info { + HANDLE handle; + char adapterid[1024]; + char adaptername[1024]; +}; + +/* ***************************************************** */ + +static HANDLE open_tap_device(const char *adapterid) { + char tapname[1024]; + _snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); + + return(CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, + 0, /* Don't let other processes share or open + the resource until the handle's been closed */ + 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0)); +} + +/* ***************************************************** */ + +static void iterate_win_network_adapters( + int (*callback)(struct win_adapter_info*, struct tuntap_dev *), + void *userdata) { + HKEY key, key2; + char regpath[1024]; + long len, rc; + int found = 0; + int err, i; + struct win_adapter_info adapter; + + /* Open registry and look for network adapters */ + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: [rc=%d]\n", rc); + exit(EXIT_FAILURE); + /* MSVC Note: If you keep getting rc=2 errors, make sure you set: + Project -> Properties -> Configuration Properties -> General -> Character set + to: "Use Multi-Byte Character Set" + */ + } + + for (i = 0; ; i++) { + len = sizeof(adapter.adapterid); + if(RegEnumKeyEx(key, i, (LPTSTR)adapter.adapterid, &len, 0, 0, 0, NULL)) + break; + + /* Find out more about this adapter */ + + _snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapter.adapterid); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adapter.adaptername); + err = RegQueryValueEx(key2, "Name", 0, 0, adapter.adaptername, &len); + + RegCloseKey(key2); + + if(err) + continue; + + + adapter.handle = open_tap_device(adapter.adapterid); + + if(adapter.handle != INVALID_HANDLE_VALUE) { + /* Valid device, use the callback */ + if(!callback(&adapter, userdata)) + break; + else + CloseHandle(adapter.handle); + /* continue */ + } + } + + RegCloseKey(key); +} + +/* ***************************************************** */ + +static int print_adapter_callback(struct win_adapter_info *adapter, struct tuntap_dev *device) { + printf(" %s - %s\n", adapter->adapterid, adapter->adaptername); + + /* continue */ + return(1); +} + +void win_print_available_adapters() { + iterate_win_network_adapters(print_adapter_callback, NULL); +} + +/* ***************************************************** */ + +static int lookup_adapter_info_reg(const char *target_adapter, char *regpath, size_t regpath_size) { + HKEY key, key2; + long len, rc; + char index[16]; + int err, i; + char adapter_name[N2N_IFNAMSIZ]; + int rv = 0; + + if((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADAPTER_INFO_KEY, 0, KEY_READ, &key))) { + printf("Unable to read registry: %s, [rc=%d]\n", ADAPTER_INFO_KEY, rc); + exit(EXIT_FAILURE); + } + + for(i = 0; ; i++) { + len = sizeof(index); + if(RegEnumKeyEx(key, i, (LPTSTR)index, &len, 0, 0, 0, NULL)) + break; + + _snprintf(regpath, regpath_size, "%s\\%s", ADAPTER_INFO_KEY, index); + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)regpath, 0, KEY_READ, &key2)) + continue; + + len = sizeof(adapter_name); + err = RegQueryValueEx(key2, "NetCfgInstanceId", 0, 0, adapter_name, &len); + + RegCloseKey(key2); + + if(err) + continue; + + if(!strcmp(adapter_name, target_adapter)) { + rv = 1; + break; + } + } + + RegCloseKey(key); + return(rv); +} + +/* ***************************************************** */ + +static void set_interface_mac(struct tuntap_dev *device, const char *mac_str) { + char cmd[256]; + char mac_buf[18]; + char adapter_info_reg[1024]; + + uint64_t mac = 0; + uint8_t *ptr = (uint8_t*)&mac; + + if(strlen(mac_str) != 17) { + printf("Invalid MAC: %s\n", mac_str); + exit(EXIT_FAILURE); + } + + /* Remove the colons */ + for(int i=0; i<6; i++) { + mac_buf[i*2] = mac_str[2*i + i]; + mac_buf[i*2+1] = mac_str[2*i + i + 1]; + } + mac_buf[12] = '\0'; + + if(!lookup_adapter_info_reg(device->device_name, adapter_info_reg, sizeof(adapter_info_reg))) { + printf("Could not determine adapter MAC registry key\n"); + exit(EXIT_FAILURE); + } + + _snprintf(cmd, sizeof(cmd), + "reg add HKEY_LOCAL_MACHINE\\%s /v MAC /d %s /f > nul", adapter_info_reg, mac_buf); + system(cmd); + + /* Put down then up again to apply */ + CloseHandle(device->device_handle); + _snprintf(cmd, sizeof(cmd), "netsh interface set interface \"%s\" disabled > nul", device->ifName); + system(cmd); + _snprintf(cmd, sizeof(cmd), "netsh interface set interface \"%s\" enabled > nul", device->ifName); + system(cmd); + + device->device_handle = open_tap_device(device->device_name); + if(device->device_handle == INVALID_HANDLE_VALUE) { + printf("Reopening TAP device \"%s\" failed\n", device->device_name); + exit(EXIT_FAILURE); + } +} + +/* ***************************************************** */ + +static int choose_adapter_callback(struct win_adapter_info *adapter, struct tuntap_dev *device) { + if(device->device_name) { + /* A device name filter was set, name must match */ + if(strcmp(device->device_name, adapter->adapterid) && + strcmp(device->device_name, adapter->adaptername)) { + /* Not found, continue */ + return(1); + } + } /* otherwise just pick the first available adapter */ + + /* Adapter found, break */ + device->device_handle = adapter->handle; + if(device->device_name) free(device->device_name); + device->device_name = _strdup(adapter->adapterid); + device->ifName = _strdup(adapter->adaptername); + return(0); +} + +/* ***************************************************** */ + +int open_wintap(struct tuntap_dev *device, + const char * devname, + const char * address_mode, /* "static" or "dhcp" */ + char *device_ip, + char *device_mask, + const char *device_mac, + int mtu, + int metric) { + + char cmd[256]; + DWORD len; + ULONG status = TRUE; + + memset(device, 0, sizeof(struct tuntap_dev)); + device->device_handle = INVALID_HANDLE_VALUE; + device->device_name = devname[0] ? _strdup(devname) : NULL; + device->ifName = NULL; + device->ip_addr = inet_addr(device_ip); + + iterate_win_network_adapters(choose_adapter_callback, device); + + if(device->device_handle == INVALID_HANDLE_VALUE) { + if(!devname[0]) + printf("No Windows tap devices found, did you run tapinstall.exe?\n"); + else + printf("Cannot find tap device \"%s\"\n", devname); + return -1; + } + + /* ************************************** */ + + /* interface index, required for routing */ + + ULONG buffer_len = 0; + IP_ADAPTER_INFO *buffer; + + // get required buffer size and allocate buffer + GetAdaptersInfo(NULL, &buffer_len); + buffer = malloc(buffer_len); + + // find device by name and get its index + if(buffer && !GetAdaptersInfo(buffer, &buffer_len)) { + IP_ADAPTER_INFO *i; + for(i = buffer; i != NULL; i = i->Next) { + if(!strcmp(device->device_name, i->AdapterName)) { + device->if_idx = i->Index; + break; + } + } + } + + free(buffer); + + /* ************************************** */ + + if(device_mac[0]) + set_interface_mac(device, device_mac); + + /* Get MAC address from tap device->device_name */ + + if(!DeviceIoControl(device->device_handle, TAP_IOCTL_GET_MAC, + device->mac_addr, sizeof(device->mac_addr), + device->mac_addr, sizeof(device->mac_addr), &len, 0)) { + printf("Could not get MAC address from Windows tap %s (%s)\n", + device->device_name, device->ifName); + return -1; + } + + device->mtu = mtu; + + printf("Open device [name=%s][ip=%s][ifName=%s][MTU=%d][mac=%02X:%02X:%02X:%02X:%02X:%02X]\n", + device->device_name, device_ip, device->ifName, device->mtu, + device->mac_addr[0] & 0xFF, + device->mac_addr[1] & 0xFF, + device->mac_addr[2] & 0xFF, + device->mac_addr[3] & 0xFF, + device->mac_addr[4] & 0xFF, + device->mac_addr[5] & 0xFF); + + /* ****************** */ + + if ( 0 == strcmp("dhcp", address_mode) ) + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" dhcp > nul", + device->ifName); + } + else + { + _snprintf(cmd, sizeof(cmd), + "netsh interface ip set address \"%s\" static %s %s > nul", + device->ifName, device_ip, device_mask); + } + + if(system(cmd) == 0) { + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + } else + printf("WARNING: Unable to set device %s IP address [%s]\n", + device->ifName, cmd); + + /* ****************** */ + + /* MTU */ + + _snprintf(cmd, sizeof(cmd), + "netsh interface ipv4 set subinterface \"%s\" mtu=%d store=persistent > nul", + device->ifName, mtu); + + if(system(cmd) != 0) + printf("WARNING: Unable to set device %s parameters MTU=%d store=persistent [%s]\n", + device->ifName, mtu, cmd); + + /* ****************** */ + + /* metric */ + + PMIB_IPINTERFACE_ROW Row; + + if(metric) { /* try to change only if a value has been given, otherwise leave with default or as set before */ + // find & store original metric + Row = calloc(1, sizeof(MIB_IPINTERFACE_ROW)); + InitializeIpInterfaceEntry(Row); + Row->InterfaceIndex = device->if_idx; + Row->Family = AF_INET; + GetIpInterfaceEntry(Row); + + device->metric_original = Row->Metric; + device->metric = metric; + + // set new value + Row->Metric = metric; + + // store + Row->SitePrefixLength = 0; /* if not set to zero, following function call fails... */ + SetIpInterfaceEntry(Row); + + free(Row); + } + + /* ****************** */ + + + /* set driver media status to 'connected' (i.e. set the interface up) */ + if (!DeviceIoControl (device->device_handle, TAP_IOCTL_SET_MEDIA_STATUS, + &status, sizeof (status), + &status, sizeof (status), &len, NULL)) + printf("WARNING: Unable to enable TAP adapter\n"); + + /* + * Initialize overlapped structures + */ + device->overlap_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + device->overlap_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!device->overlap_read.hEvent || !device->overlap_write.hEvent) { + return -1; + } + + return(0); +} + +/* ************************************************ */ + +int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD read_size, last_err; + + ResetEvent(tuntap->overlap_read.hEvent); + if (ReadFile(tuntap->device_handle, buf, len, &read_size, &tuntap->overlap_read)) { + //printf("tun_read(len=%d)\n", read_size); + return read_size; + } + switch (last_err = GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_read.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_read, &read_size, FALSE); + return read_size; + break; + default: + printf("GetLastError() returned %d\n", last_err); + break; + } + + return -1; +} +/* ************************************************ */ + +int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) +{ + DWORD write_size; + + //printf("tun_write(len=%d)\n", len); + + ResetEvent(tuntap->overlap_write.hEvent); + if (WriteFile(tuntap->device_handle, + buf, + len, + &write_size, + &tuntap->overlap_write)) { + //printf("DONE tun_write(len=%d)\n", write_size); + return write_size; + } + switch (GetLastError()) { + case ERROR_IO_PENDING: + WaitForSingleObject(tuntap->overlap_write.hEvent, INFINITE); + GetOverlappedResult(tuntap->device_handle, &tuntap->overlap_write, + &write_size, FALSE); + return write_size; + break; + default: + break; + } + + return -1; +} + +/* ************************************************ */ + +int tuntap_open(struct tuntap_dev *device, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu, + int metric) { + return(open_wintap(device, dev, address_mode, device_ip, device_mask, device_mac, mtu, metric)); +} + +/* ************************************************ */ + +void tuntap_close(struct tuntap_dev *tuntap) { + + PMIB_IPINTERFACE_ROW Row; + + if(tuntap->metric) { /* only required if a value has been given (and thus stored) */ + // find device entry + Row = calloc(1, sizeof(MIB_IPINTERFACE_ROW)); + InitializeIpInterfaceEntry(Row); + Row->InterfaceIndex = tuntap->if_idx; + Row->Family = AF_INET; + GetIpInterfaceEntry(Row); + + // restore original value + Row->Metric = tuntap->metric_original; + + // store + Row->SitePrefixLength = 0; /* if not set to zero, following function call fails... */ + SetIpInterfaceEntry(Row); + + free(Row); + } + + CloseHandle(tuntap->device_handle); +} + +/* Fill out the ip_addr value from the interface. Called to pick up dynamic + * address changes. */ +void tuntap_get_address(struct tuntap_dev *tuntap) +{ +} + +/* ************************************************ */ + +#if 0 +int main(int argc, char* argv[]) { + struct tuntap_dev tuntap; + int i; + int mtu = 1400; + + printf("Welcome to n2n\n"); + initWin32(); + open_wintap(&tuntap, "static", "1.2.3.20", "255.255.255.0", mtu, 0); + + for(i=0; i<10; i++) { + u_char buf[MTU]; + int rc; + + rc = tun_read(&tuntap, buf, sizeof(buf)); + buf[0]=2; + buf[1]=3; + buf[2]=4; + + printf("tun_read returned %d\n", rc); + rc = tun_write(&tuntap, buf, rc); + printf("tun_write returned %d\n", rc); + } + // rc = tun_open (device->device_name, IF_MODE_TUN); + WSACleanup (); + return(0); +} + +#endif diff --git a/bundles/n2n_ntop_v3/win32/wintap.h b/bundles/n2n_ntop_v3/win32/wintap.h new file mode 100644 index 00000000..ce53b550 --- /dev/null +++ b/bundles/n2n_ntop_v3/win32/wintap.h @@ -0,0 +1,72 @@ +/* + (C) 2007 - Luca Deri +*/ + +#ifndef _WINTAP_H_ +#define _WINTAP_H_ + +#undef UNICODE +#undef _UNICODE +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + + + +//=============================================== +// This file is included both by OpenVPN and +// the TAP-Win32 driver and contains definitions +// common to both. +//=============================================== + +//============= +// TAP IOCTLs +//============= + +#define TAP_CONTROL_CODE(request,method) \ + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + +#define TAP_IOCTL_GET_MAC TAP_CONTROL_CODE (1, METHOD_BUFFERED) +#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE (2, METHOD_BUFFERED) +#define TAP_IOCTL_GET_MTU TAP_CONTROL_CODE (3, METHOD_BUFFERED) +#define TAP_IOCTL_GET_INFO TAP_CONTROL_CODE (4, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE (5, METHOD_BUFFERED) +#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE (6, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_MASQ TAP_CONTROL_CODE (7, METHOD_BUFFERED) +#define TAP_IOCTL_GET_LOG_LINE TAP_CONTROL_CODE (8, METHOD_BUFFERED) +#define TAP_IOCTL_CONFIG_DHCP_SET_OPT TAP_CONTROL_CODE (9, METHOD_BUFFERED) + +//================= +// Registry keys +//================= + +#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define ADAPTER_INFO_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +//====================== +// Filesystem prefixes +//====================== + +#define USERMODEDEVICEDIR "\\\\.\\Global\\" +#define SYSDEVICEDIR "\\Device\\" +#define USERDEVICEDIR "\\DosDevices\\Global\\" +#define TAPSUFFIX ".tap" + +//========================================================= +// TAP_COMPONENT_ID -- This string defines the TAP driver +// type -- different component IDs can reside in the system +// simultaneously. +//========================================================= + +#define TAP_COMPONENT_ID "tap0801" + +extern void initWin32(); +extern void destroyWin32(); +extern void win_print_available_adapters(); + +#endif \ No newline at end of file diff --git a/bundles/n2n_ntop_v3/wireshark/README.md b/bundles/n2n_ntop_v3/wireshark/README.md new file mode 100644 index 00000000..4c0b6fdd --- /dev/null +++ b/bundles/n2n_ntop_v3/wireshark/README.md @@ -0,0 +1,9 @@ +Wireshark Lua plugin to dissect n2n traffic. + +Quick load: + +``` + wireshark -X lua_script:n2n.lua +``` + +NOTE: the dissector only decodes traffic on UDP port 50001. In order to decode n2n traffic on another UDP port you can use the "Decode As..." function of wireshark. diff --git a/bundles/n2n_ntop_v3/wireshark/n2n.lua b/bundles/n2n_ntop_v3/wireshark/n2n.lua new file mode 100644 index 00000000..ff453410 --- /dev/null +++ b/bundles/n2n_ntop_v3/wireshark/n2n.lua @@ -0,0 +1,316 @@ +-- (C) 2019 - ntop.org and contributors + +n2n = Proto("n2n", "n2n Protocol") + +-- ############################################# + +PKT_TYPE_PING = 0 +PKT_TYPE_REGISTER = 1 +PKT_TYPE_DEREGISTER = 2 +PKT_TYPE_PACKET = 3 +PKT_TYPE_REGISTER_ACK = 4 +PKT_TYPE_REGISTER_SUPER = 5 +PKT_TYPE_REGISTER_SUPER_ACK = 6 +PKT_TYPE_REGISTER_SUPER_NAK = 7 +PKT_TYPE_FEDERATION = 8 +PKT_TYPE_PEER_INFO = 9 +PKT_TYPE_QUERY_PEER = 10 + +PKT_TRANSFORM_NULL = 1 +PKT_TRANSFORM_TWOFISH = 2 +PKT_TRANSFORM_AESCBC = 3 + +FLAG_FROM_SUPERNODE = 0x0020 +FLAG_SOCKET = 0x0040 +FLAG_OPTIONS = 0x0080 + +SOCKET_FAMILY_AF_INET = 0x0000 +SOCKET_FAMILY_AF_INET6 = 0x8000 + +-- ############################################# + +version = ProtoField.uint8("n2n.version", "version", base.DEC) +ttl = ProtoField.uint8("n2n.ttl", "ttl", base.DEC) + +packet_type_mask = 0x001f +pkt_type_2_str = { + [PKT_TYPE_PING] = "ping", + [PKT_TYPE_REGISTER] = "register", + [PKT_TYPE_DEREGISTER] = "deregister", + [PKT_TYPE_PACKET] = "packet", + [PKT_TYPE_REGISTER_ACK] = "register_ack", + [PKT_TYPE_REGISTER_SUPER] = "register_super", + [PKT_TYPE_REGISTER_SUPER_ACK] = "register_super_ack", + [PKT_TYPE_REGISTER_SUPER_NAK] = "register_super_nak", + [PKT_TYPE_FEDERATION] = "federation", + [PKT_TYPE_PEER_INFO] = "peer_info", + [PKT_TYPE_QUERY_PEER] = "query_peer", +} +packet_type = ProtoField.uint8("n2n.packet_type", "packetType", base.HEX, pkt_type_2_str, packet_type_mask) + +flags_mask = 0xffe0 +flags = ProtoField.uint16("n2n.flags", "Flags", base.HEX, nil, flags_mask) +from_supernode_flag = ProtoField.uint16("n2n.flags.from_supernode", "from_supernode", base.BOOLEAN, nil, FLAG_FROM_SUPERNODE) +socket_flag = ProtoField.uint16("n2n.flags.socket", "socket", base.BOOLEAN, nil, FLAG_SOCKET) +options_flag = ProtoField.uint16("n2n.flags.options", "options", base.BOOLEAN, nil, FLAG_OPTIONS) +community = ProtoField.string("n2n.community", "Community", base.ASCII) + +-- ############################################# + +src_mac = ProtoField.ether("n2n.src_mac", "Source") +dst_mac = ProtoField.ether("n2n.dst_mac", "Destination") +socket_info = ProtoField.none("n2n.socket", "Socket Info") +socket_family = ProtoField.uint16("n2n.socket.family", "Family", base.HEX, { + [0] = "AF_INET", +}) +socket_port = ProtoField.uint16("n2n.socket.port", "Port") +socket_ipv4 = ProtoField.ipv4("n2n.socket.ipv4", "IPv4") +socket_ipv6 = ProtoField.ipv6("n2n.socket.ipv6", "IPv6") + +-- ############################################# + +peer_info_field = ProtoField.none("n2n.peer_info", "PeerInfo") +peer_info_flags = ProtoField.uint16("n2n.peer_info.flags", "Flags") +peer_info_mac = ProtoField.ether("n2n.peer_info.query_mac", "Query") + +query_peer_field = ProtoField.none("n2n.query_peer", "QueryPeer") + +-- ############################################# + + + +packet_field = ProtoField.none("n2n.packet", "Packet") +packet_transform = ProtoField.uint16("n2n.packet.transform", "Transform", base.HEX, { + [PKT_TRANSFORM_NULL] = "Plaintext", + [PKT_TRANSFORM_TWOFISH] = "TwoFish", + [PKT_TRANSFORM_AESCBC] = "AES CBC", +}) +packet_payload = ProtoField.bytes("n2n.packet.payload", "Payload") + +-- ############################################# + +register_field = ProtoField.none("n2n.register", "Register") +register_cookie = ProtoField.uint32("n2n.register.cookie", "Cookie", base.HEX) + +register_ack_field = ProtoField.none("n2n.register_ack", "RegisterACK") +register_ack_cookie = ProtoField.uint32("n2n.register_ack.cookie", "Cookie", base.HEX) + +register_super_field = ProtoField.none("n2n.register_super", "RegisterSuper") +register_super_cookie = ProtoField.uint32("n2n.register_super.cookie", "Cookie", base.HEX) +register_super_auth_schema = ProtoField.uint16("n2n.register_super.auth.schema", "AuthSchema", base.HEX) +register_super_auth_data = ProtoField.uint16("n2n.register_super.auth.data", "AuthData", base.HEX) + +register_super_ack_field = ProtoField.none("n2n.register_super_ack", "RegisterSuperACK") +register_super_ack_cookie = ProtoField.uint32("n2n.register_super_ack.cookie", "Cookie", base.HEX) +register_super_ack_lifetime = ProtoField.uint16("n2n.register_super_ack.lifetime", "Registration Lifetime", base.DEC) +register_super_ack_num_sn = ProtoField.uint8("n2n.register_super_ack.num_sn", "Num Supernodes", base.DEC) + +-- ############################################# + +n2n.fields = { + version, ttl, packet_type, + flags, from_supernode_flag, socket_flag, options_flag, + community, + + -- Generic + src_mac, dst_mac, + socket_info, socket_family, socket_port, socket_ipv4, socket_ipv6, + + -- PKT_TYPE_REGISTER + register_field, register_cookie, + -- PKT_TYPE_PACKET + packet_field, packet_transform, packet_payload, + -- PKT_TYPE_REGISTER_ACK + register_ack_field, register_ack_cookie, + -- PKT_TYPE_REGISTER_SUPER + register_super_field, register_super_cookie, register_super_auth_schema, register_super_auth_data, + -- PKT_TYPE_REGISTER_SUPER_ACK + register_super_ack_field, register_super_ack_cookie, register_super_ack_lifetime, register_super_ack_num_sn, + -- PKT_TYPE_PEER_INFO + peer_info_field, peer_info_flags, peer_info_mac, + -- PKT_TYPE_QUERY_PEER + query_peer_field, +} + +-- ############################################# + +function dissect_socket(subtree, buffer, offset) + local sock_baselen = 4 + local sock_protolen = 0 + buffer = buffer(offset) + local sock_family = bit.band(buffer(0,4):uint(), 0xFFFF0000) + + if(sock_family == SOCKET_FAMILY_AF_INET) then + sock_protolen = 4 + elseif(sock_family == SOCKET_FAMILY_AF_INET6) then + sock_protolen = 16 + end + + local totlen = sock_baselen + sock_protolen + local socktree = subtree:add(socket_info, buffer(0, totlen)) + + socktree:add(socket_family, buffer(0, 2)) + socktree:add(socket_port, buffer(2, 2)) + + if(sock_family == SOCKET_FAMILY_AF_INET) then + socktree:add(socket_ipv4, buffer(4, sock_protolen)) + elseif(sock_family == SOCKET_FAMILY_AF_INET6) then + socktree:add(socket_ipv6, buffer(4, sock_protolen)) + end + + return offset+totlen, socktree +end + +-- ############################################# + +function dissect_register(subtree, buffer, flags) + local regtree = subtree:add(register_field, buffer) + + regtree:add(register_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(dst_mac, buffer(10,6)) + + if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then + dissect_socket(regtree, buffer, 16) + end + + return regtree +end + +-- ############################################# + +function dissect_register_ack(subtree, buffer, flags) + local regtree = subtree:add(register_ack_field, buffer) + + regtree:add(register_ack_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(dst_mac, buffer(10,6)) + + return regtree +end + +-- ############################################# + +function dissect_packet(subtree, buffer, flags, pinfo) + local pktree = subtree:add(packet_field, buffer) + + pktree:add(src_mac, buffer(0,6)) + pktree:add(dst_mac, buffer(6,6)) + + if(bit.band(flags, FLAG_SOCKET) == FLAG_SOCKET) then + idx = dissect_socket(pktree, buffer, 12) + else + idx = 12 + end + + pktree:add(packet_transform, buffer(idx,2)) + local payload = pktree:add(packet_payload, buffer(idx+2)) + local transform = buffer(idx,2):uint() + + -- Can only dissect unencrypted data + if(transform == PKT_TRANSFORM_NULL) then + Dissector.get("eth_withoutfcs"):call(buffer(idx+2):tvb(), pinfo, payload) + end + + return pktree +end + +-- ############################################# + +function dissect_register_super(subtree, buffer, flags) + local regtree = subtree:add(register_super_field, buffer) + + regtree:add(register_super_cookie, buffer(0,4)) + regtree:add(src_mac, buffer(4,6)) + regtree:add(register_super_auth_schema, buffer(10,2)) + regtree:add(register_super_auth_data, buffer(12,2)) + + return regtree +end + +-- ############################################# + +function dissect_register_super_ack(subtree, buffer, flags) + local regtree = subtree:add(register_super_ack_field, buffer) + + regtree:add(register_super_ack_cookie, buffer(0,4)) + regtree:add(dst_mac, buffer(4,6)) + regtree:add(register_super_ack_lifetime, buffer(10,2)) + local idx = dissect_socket(regtree, buffer, 12) + regtree:add(register_super_ack_num_sn, buffer(idx, 1)) + + return regtree +end + +-- ############################################# + +function dissect_peer_info(subtree, buffer, flags) + local peertree = subtree:add(peer_info_field, buffer) + + peertree:add(peer_info_flags, buffer(0,2)) + peertree:add(peer_info_mac, buffer(2,6)) + dissect_socket(peertree, buffer, 8) + + return peertree +end + +-- ############################################# + +function dissect_query_peer(subtree, buffer, flags) + local peertree = subtree:add(query_peer_field, buffer) + + peertree:add(src_mac, buffer(0,6)) + peertree:add(dst_mac, buffer(6,6)) + + return peertree +end + +-- ############################################# + +function n2n.dissector(buffer, pinfo, tree) + local length = buffer:len() + if length < 20 then return end + + pinfo.cols.protocol = n2n.name + + local pkt_type = bit.band(buffer(2,2):uint(), packet_type_mask) + local subtree = tree:add(n2n, buffer(), string.format("n2n Protocol, Type: %s", pkt_type_2_str[pkt_type] or "Unknown")) + + -- Common + subtree:add(version, buffer(0,1)) + subtree:add(ttl, buffer(1,1)) + subtree:add(packet_type, buffer(2,2)) + local flags_buffer = buffer(2,2) + local flags_tree = subtree:add(flags, flags_buffer) + subtree:add(community, buffer(4,16)) + + -- Flags + flags_tree:add(from_supernode_flag, flags_buffer) + flags_tree:add(socket_flag, flags_buffer) + flags_tree:add(options_flag, flags_buffer) + + -- Packet specific + local flags = bit.band(buffer(2,2):uint(), flags_mask) + local typebuf = buffer(20) + + if(pkt_type == PKT_TYPE_REGISTER) then + dissect_register(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_REGISTER) then + dissect_register_ack(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_PACKET) then + dissect_packet(subtree, typebuf, flags, pinfo) + elseif(pkt_type == PKT_TYPE_REGISTER_SUPER) then + dissect_register_super(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_REGISTER_SUPER_ACK) then + dissect_register_super_ack(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_PEER_INFO) then + dissect_peer_info(subtree, typebuf, flags) + elseif(pkt_type == PKT_TYPE_QUERY_PEER) then + dissect_query_peer(subtree, typebuf, flags) + end +end + +-- ############################################# + +local udp_port = DissectorTable.get("udp.port") +udp_port:add(50001, n2n) diff --git a/bundles/slog/slog.c b/bundles/slog/slog.c new file mode 100644 index 00000000..c7231bf0 --- /dev/null +++ b/bundles/slog/slog.c @@ -0,0 +1,133 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-21. +// + +#include "slog.h" +#include +#include +#include +#include +#include +#include + +#define SLOG_MAX_CHECK_TIMES 100 + +static FILE* create_and_open_file(char* path) +{ + int ret; + FILE* fp = NULL; + char* c = NULL; + const char* p = path; + + if (!path || path[0] == '\0') { + return NULL; + } + if (path[0] == '/') path++; + while (path[0] != '\0') { + c = strchr(path, '/'); + if (c == NULL) { + fp = fopen(p, "a"); + return fp; + } + *c = '\0'; + ret = mkdir(p, 0755); + *c = '/'; + if (ret != 0) { + if (errno != EEXIST) { + return NULL; + } + } + path = c + 1; + } + + return NULL; +} + +static slog_t* check_log_path(slog_t* slog) +{ + if (!slog) + return NULL; + if (!slog->path) { + fclose(slog->fp); + free(slog); + return NULL; + } + slog->times = 0; + if (!access(slog->path, W_OK)) + return slog; + if (slog->fp) { + fclose(slog->fp); + slog->fp = NULL; + } + slog->fp = create_and_open_file(slog->path); + return slog; +} + +slog_t* initslog(int base, const char* path) +{ + if (base < 0 || path == NULL || path[0] == '\0') + return NULL; + char* p = strdup(path); + FILE* fp = create_and_open_file(p); + if (fp == NULL) { + free(p); + return NULL; + } + slog_t* slog = malloc(sizeof(slog_t)); + slog->fp = fp; + slog->base = base; + slog->path = p; + slog->times = 0; + return slog; +} + +slog_t* writeslog(slog_t* p, int level, const char* tag, const char* text) +{ + return printslog(p, level, tag, "%s\n", text); +} + +slog_t* printslog(slog_t* p, int level, const char* tag, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + p = vprintslog(p, level, tag, fmt, ap); + va_end(ap); + return p; +} + +slog_t* vprintslog(slog_t* p, int level, const char* tag, const char* fmt, va_list ap) +{ + if (!p) { + return NULL; + } + if (level < p->base) { + return p; + } +#ifndef NDEBUG + __android_log_vprint(level, tag, fmt, ap); +#endif /* #ifndef NDEBUG */ + if (p->fp) { + fprintf(p->fp, "%s: ", tag); + vfprintf(p->fp, fmt, ap); + fflush(p->fp); + } + p->times++; + if (p->times > SLOG_MAX_CHECK_TIMES) { + fflush(p->fp); + p = check_log_path(p); + } + return p; +} + +void closeslog(slog_t* p) +{ + if (p) { + if (p->fp) { + fclose(p->fp); + } + if (p->path) { + free(p->path); + } + free(p); + } +} diff --git a/bundles/slog/slog.h b/bundles/slog/slog.h new file mode 100644 index 00000000..1853f1c3 --- /dev/null +++ b/bundles/slog/slog.h @@ -0,0 +1,24 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-21. +// + +#ifndef _SIMPLELOG_H_ +#define _SIMPLELOG_H_ + +#include +#include + +typedef struct slog_st { + FILE* fp; + int base; + char* path; + int times; +} slog_t; + +slog_t* initslog(int base, const char* path); +slog_t* writeslog(slog_t* p, int level, const char* tag, const char* text); +slog_t* printslog(slog_t* p, int level, const char* tag, const char* fmt, ...); +slog_t* vprintslog(slog_t* p, int level, const char* tag, const char* fmt, va_list ap); +void closeslog(slog_t* p); + +#endif //_SIMPLELOG_H_ diff --git a/bundles/tun2tap/tun2tap.c b/bundles/tun2tap/tun2tap.c new file mode 100644 index 00000000..02c5958d --- /dev/null +++ b/bundles/tun2tap/tun2tap.c @@ -0,0 +1,9 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-20. +// + +#include "tun2tap.h" + +u8_t* uip_buf = NULL; +u8_t uip_arp_buf[UIP_LLH_LEN + UIP_ARP_LEN]; +u16_t uip_arp_len = 0; diff --git a/bundles/tun2tap/tun2tap.h b/bundles/tun2tap/tun2tap.h new file mode 100644 index 00000000..cb38a422 --- /dev/null +++ b/bundles/tun2tap/tun2tap.h @@ -0,0 +1,53 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-14. +// + +#ifndef _TUN2TAP_H_ +#define _TUN2TAP_H_ + +#ifdef HTONS +#undef HTONS +#endif + +#include "uip-conf.h" +#include +#include + +#define UIP_ARP_LEN 28 + +struct arp_hdr { + struct uip_eth_hdr ethhdr; + u16_t hwtype; + u16_t protocol; + u8_t hwlen; + u8_t protolen; + u16_t opcode; + struct uip_eth_addr shwaddr; + u16_t sipaddr[2]; + struct uip_eth_addr dhwaddr; + u16_t dipaddr[2]; +}; + +struct ethip_hdr { + struct uip_eth_hdr ethhdr; + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +}; + +#define BUF ((struct arp_hdr *)&uip_buf[0]) +#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) + +extern u8_t* uip_buf; +extern u8_t uip_arp_buf[UIP_LLH_LEN + UIP_ARP_LEN]; +extern u16_t uip_arp_len; + +#endif //_TUN2TAP_H_ diff --git a/bundles/tun2tap/tun2tap_appdef.h b/bundles/tun2tap/tun2tap_appdef.h new file mode 100644 index 00000000..03d490da --- /dev/null +++ b/bundles/tun2tap/tun2tap_appdef.h @@ -0,0 +1,13 @@ +// +// Created by switchwang(https://github.com/switch-st) on 2018-04-14. +// + +#ifndef _TUN2TAP_DEFINE_H_ +#define _TUN2TAP_DEFINE_H_ + +#define uip_tcp_appstate_t void* +#define UIP_APPCALL() + +extern u8_t* uip_buf; + +#endif //_TUN2TAP_DEFINE_H_ diff --git a/bundles/tun2tap/uip-conf.h b/bundles/tun2tap/uip-conf.h new file mode 100644 index 00000000..8b755cc1 --- /dev/null +++ b/bundles/tun2tap/uip-conf.h @@ -0,0 +1,163 @@ +/** + * \addtogroup uipopt + * @{ + */ + +/** + * \name Project-specific configuration options + * @{ + * + * uIP has a number of configuration options that can be overridden + * for each project. These are kept in a project-specific uip-conf.h + * file and all configuration names have the prefix UIP_CONF. + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * An example uIP configuration file + * \author + * Adam Dunkels + */ + +#ifndef __UIP_CONF_H__ +#define __UIP_CONF_H__ + +#include + +/** + * 8 bit datatype + * + * This typedef defines the 8-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint8_t u8_t; + +/** + * 16 bit datatype + * + * This typedef defines the 16-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint16_t u16_t; + +/** + * Statistics datatype + * + * This typedef defines the dataype used for keeping statistics in + * uIP. + * + * \hideinitializer + */ +typedef unsigned short uip_stats_t; + +/** + * Maximum number of TCP connections. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_CONNECTIONS 40 + +/** + * Maximum number of listening TCP ports. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_LISTENPORTS 40 + +/** + * uIP buffer size. + * + * \hideinitializer + */ +/*#define UIP_CONF_BUFFER_SIZE 420*/ +#define UIP_CONF_BUFFER_SIZE 2048 + +/** + * Manually define the uip_buf. + * + * \hideinitializer + */ +#define UIP_CONF_EXTERNAL_BUFFER + +/** + * CPU byte order. + * Defined in CMakeList.txt + * + * \hideinitializer + */ +#ifndef UIP_CONF_BYTE_ORDER +#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN +#endif + +/** + * Logging on or off + * + * \hideinitializer + */ +/*#define UIP_CONF_LOGGING 1*/ +#define UIP_CONF_LOGGING 0 + +/** + * UDP support on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP 0 + +/** + * UDP checksums on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP_CHECKSUMS 1 + +/** + * uIP statistics on or off + * + * \hideinitializer + */ +#define UIP_CONF_STATISTICS 1 + +/* Here we include the header file for the application(s) we use in + our project. */ +#include "tun2tap_appdef.h" + +#endif /* __UIP_CONF_H__ */ + +/** @} */ +/** @} */ diff --git a/bundles/uip/README b/bundles/uip/README new file mode 100644 index 00000000..b5015386 --- /dev/null +++ b/bundles/uip/README @@ -0,0 +1,13 @@ +uIP is a very small implementation of the TCP/IP stack that is written +by Adam Dunkels . More information can be obtained +at the uIP homepage at http://www.sics.se/~adam/uip/. + +This is version $Name: uip-1-0 $. + +The directory structure look as follows: + +apps/ - Example applications +doc/ - Documentation +lib/ - Library code used by some applications +uip/ - uIP TCP/IP stack code +unix/ - uIP as a user space process under FreeBSD or Linux diff --git a/bundles/uip/apps/README b/bundles/uip/apps/README new file mode 100644 index 00000000..0096c4e4 --- /dev/null +++ b/bundles/uip/apps/README @@ -0,0 +1,2 @@ +This directory contains a few example applications. They are not all +heavily tested, however. diff --git a/bundles/uip/apps/dhcpc/Makefile.dhcpc b/bundles/uip/apps/dhcpc/Makefile.dhcpc new file mode 100644 index 00000000..f84c84ff --- /dev/null +++ b/bundles/uip/apps/dhcpc/Makefile.dhcpc @@ -0,0 +1 @@ +APP_SOURCES += dhcpc.c timer.c diff --git a/bundles/uip/apps/dhcpc/dhcpc.c b/bundles/uip/apps/dhcpc/dhcpc.c new file mode 100644 index 00000000..ac738e7e --- /dev/null +++ b/bundles/uip/apps/dhcpc/dhcpc.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + */ + +#include +#include + +#include "uip.h" +#include "dhcpc.h" +#include "timer.h" +#include "pt.h" + +#define STATE_INITIAL 0 +#define STATE_SENDING 1 +#define STATE_OFFER_RECEIVED 2 +#define STATE_CONFIG_RECEIVED 3 + +static struct dhcpc_state s; + +struct dhcp_msg { + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; +#ifndef UIP_CONF_DHCP_LIGHT + u8_t sname[64]; + u8_t file[128]; +#endif + u8_t options[312]; +}; + +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPC_SERVER_PORT 67 +#define DHCPC_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +static const u8_t xid[4] = {0xad, 0xde, 0x12, 0x23}; +static const u8_t magic_cookie[4] = {99, 130, 83, 99}; +/*---------------------------------------------------------------------------*/ +static u8_t * +add_msg_type(u8_t *optptr, u8_t type) +{ + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_server_id(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + memcpy(optptr, s.serverid, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_ipaddr(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_IPADDR; + *optptr++ = 4; + memcpy(optptr, s.ipaddr, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_options(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_LIST; + *optptr++ = 3; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = DHCP_OPTION_DNS_SERVER; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_end(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static void +create_msg(register struct dhcp_msg *m) +{ + m->op = DHCP_REQUEST; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = s.mac_len; + m->hops = 0; + memcpy(m->xid, xid, sizeof(m->xid)); + m->secs = 0; + m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ + /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ + memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr)); + memset(m->yiaddr, 0, sizeof(m->yiaddr)); + memset(m->siaddr, 0, sizeof(m->siaddr)); + memset(m->giaddr, 0, sizeof(m->giaddr)); + memcpy(m->chaddr, s.mac_addr, s.mac_len); + memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); +#ifndef UIP_CONF_DHCP_LIGHT + memset(m->sname, 0, sizeof(m->sname)); + memset(m->file, 0, sizeof(m->file)); +#endif + + memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +} +/*---------------------------------------------------------------------------*/ +static void +send_discover(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPDISCOVER); + end = add_req_options(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static void +send_request(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPREQUEST); + end = add_server_id(end); + end = add_req_ipaddr(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_options(u8_t *optptr, int len) +{ + u8_t *end = optptr + len; + u8_t type = 0; + + while(optptr < end) { + switch(*optptr) { + case DHCP_OPTION_SUBNET_MASK: + memcpy(s.netmask, optptr + 2, 4); + break; + case DHCP_OPTION_ROUTER: + memcpy(s.default_router, optptr + 2, 4); + break; + case DHCP_OPTION_DNS_SERVER: + memcpy(s.dnsaddr, optptr + 2, 4); + break; + case DHCP_OPTION_MSG_TYPE: + type = *(optptr + 2); + break; + case DHCP_OPTION_SERVER_ID: + memcpy(s.serverid, optptr + 2, 4); + break; + case DHCP_OPTION_LEASE_TIME: + memcpy(s.lease_time, optptr + 2, 4); + break; + case DHCP_OPTION_END: + return type; + } + + optptr += optptr[1] + 2; + } + return type; +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_msg(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + if(m->op == DHCP_REPLY && + memcmp(m->xid, xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + memcpy(s.ipaddr, m->yiaddr, 4); + return parse_options(&m->options[4], uip_datalen()); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_dhcp(void)) +{ + PT_BEGIN(&s.pt); + + /* try_again:*/ + s.state = STATE_SENDING; + s.ticks = CLOCK_SECOND; + + do { + send_discover(); + timer_set(&s.timer, s.ticks); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); + + if(uip_newdata() && parse_msg() == DHCPOFFER) { + s.state = STATE_OFFER_RECEIVED; + break; + } + + if(s.ticks < CLOCK_SECOND * 60) { + s.ticks *= 2; + } + } while(s.state != STATE_OFFER_RECEIVED); + + s.ticks = CLOCK_SECOND; + + do { + send_request(); + timer_set(&s.timer, s.ticks); + PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); + + if(uip_newdata() && parse_msg() == DHCPACK) { + s.state = STATE_CONFIG_RECEIVED; + break; + } + + if(s.ticks <= CLOCK_SECOND * 10) { + s.ticks += CLOCK_SECOND; + } else { + PT_RESTART(&s.pt); + } + } while(s.state != STATE_CONFIG_RECEIVED); + +#if 0 + printf("Got IP address %d.%d.%d.%d\n", + uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), + uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); + printf("Got netmask %d.%d.%d.%d\n", + uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), + uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); + printf("Got DNS server %d.%d.%d.%d\n", + uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), + uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); + printf("Got default router %d.%d.%d.%d\n", + uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), + uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); + printf("Lease expires in %ld seconds\n", + ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); +#endif + + dhcpc_configured(&s); + + /* timer_stop(&s.timer);*/ + + /* + * PT_END restarts the thread so we do this instead. Eventually we + * should reacquire expired leases here. + */ + while(1) { + PT_YIELD(&s.pt); + } + + PT_END(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_init(const void *mac_addr, int mac_len) +{ + uip_ipaddr_t addr; + + s.mac_addr = mac_addr; + s.mac_len = mac_len; + + s.state = STATE_INITIAL; + uip_ipaddr(addr, 255,255,255,255); + s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT)); + if(s.conn != NULL) { + uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT)); + } + PT_INIT(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_appcall(void) +{ + handle_dhcp(); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_request(void) +{ + u16_t ipaddr[2]; + + if(s.state == STATE_INITIAL) { + uip_ipaddr(ipaddr, 0,0,0,0); + uip_sethostaddr(ipaddr); + /* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/apps/dhcpc/dhcpc.h b/bundles/uip/apps/dhcpc/dhcpc.h new file mode 100644 index 00000000..c6550ec5 --- /dev/null +++ b/bundles/uip/apps/dhcpc/dhcpc.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +#ifndef __DHCPC_H__ +#define __DHCPC_H__ + +#include "timer.h" +#include "pt.h" + +struct dhcpc_state { + struct pt pt; + char state; + struct uip_udp_conn *conn; + struct timer timer; + u16_t ticks; + const void *mac_addr; + int mac_len; + + u8_t serverid[4]; + + u16_t lease_time[2]; + u16_t ipaddr[2]; + u16_t netmask[2]; + u16_t dnsaddr[2]; + u16_t default_router[2]; +}; + +void dhcpc_init(const void *mac_addr, int mac_len); +void dhcpc_request(void); + +void dhcpc_appcall(void); + +void dhcpc_configured(const struct dhcpc_state *s); + +typedef struct dhcpc_state uip_udp_appstate_t; +#define UIP_UDP_APPCALL dhcpc_appcall + + +#endif /* __DHCPC_H__ */ diff --git a/bundles/uip/apps/hello-world/Makefile.hello-world b/bundles/uip/apps/hello-world/Makefile.hello-world new file mode 100644 index 00000000..e34aaf51 --- /dev/null +++ b/bundles/uip/apps/hello-world/Makefile.hello-world @@ -0,0 +1 @@ +APP_SOURCES += hello-world.c diff --git a/bundles/uip/apps/hello-world/hello-world.c b/bundles/uip/apps/hello-world/hello-world.c new file mode 100644 index 00000000..7d0697ce --- /dev/null +++ b/bundles/uip/apps/hello-world/hello-world.c @@ -0,0 +1,100 @@ +/** + * \addtogroup helloworld + * @{ + */ + +/** + * \file + * An example of how to write uIP applications + * with protosockets. + * \author + * Adam Dunkels + */ + +/* + * This is a short example of how to write uIP applications using + * protosockets. + */ + +/* + * We define the application state (struct hello_world_state) in the + * hello-world.h file, so we need to include it here. We also include + * uip.h (since this cannot be included in hello-world.h) and + * , since we use the memcpy() function in the code. + */ +#include "hello-world.h" +#include "uip.h" +#include + +/* + * Declaration of the protosocket function that handles the connection + * (defined at the end of the code). + */ +static int handle_connection(struct hello_world_state *s); +/*---------------------------------------------------------------------------*/ +/* + * The initialization function. We must explicitly call this function + * from the system initialization code, some time after uip_init() is + * called. + */ +void +hello_world_init(void) +{ + /* We start to listen for connections on TCP port 1000. */ + uip_listen(HTONS(1000)); +} +/*---------------------------------------------------------------------------*/ +/* + * In hello-world.h we have defined the UIP_APPCALL macro to + * hello_world_appcall so that this funcion is uIP's application + * function. This function is called whenever an uIP event occurs + * (e.g. when a new connection is established, new data arrives, sent + * data is acknowledged, data needs to be retransmitted, etc.). + */ +void +hello_world_appcall(void) +{ + /* + * The uip_conn structure has a field called "appstate" that holds + * the application state of the connection. We make a pointer to + * this to access it easier. + */ + struct hello_world_state *s = &(uip_conn->appstate); + + /* + * If a new connection was just established, we should initialize + * the protosocket in our applications' state structure. + */ + if(uip_connected()) { + PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer)); + } + + /* + * Finally, we run the protosocket function that actually handles + * the communication. We pass it a pointer to the application state + * of the current connection. + */ + handle_connection(s); +} +/*---------------------------------------------------------------------------*/ +/* + * This is the protosocket function that handles the communication. A + * protosocket function must always return an int, but must never + * explicitly return - all return statements are hidden in the PSOCK + * macros. + */ +static int +handle_connection(struct hello_world_state *s) +{ + PSOCK_BEGIN(&s->p); + + PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n"); + PSOCK_READTO(&s->p, '\n'); + strncpy(s->name, s->inputbuffer, sizeof(s->name)); + PSOCK_SEND_STR(&s->p, "Hello "); + PSOCK_SEND_STR(&s->p, s->name); + PSOCK_CLOSE(&s->p); + + PSOCK_END(&s->p); +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/apps/hello-world/hello-world.h b/bundles/uip/apps/hello-world/hello-world.h new file mode 100644 index 00000000..5ef333b8 --- /dev/null +++ b/bundles/uip/apps/hello-world/hello-world.h @@ -0,0 +1,52 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup helloworld Hello, world + * @{ + * + * A small example showing how to write applications with + * \ref psock "protosockets". + */ + +/** + * \file + * Header file for an example of how to write uIP applications + * with protosockets. + * \author + * Adam Dunkels + */ + +#ifndef __HELLO_WORLD_H__ +#define __HELLO_WORLD_H__ + +/* Since this file will be included by uip.h, we cannot include uip.h + here. But we might need to include uipopt.h if we need the u8_t and + u16_t datatypes. */ +#include "uipopt.h" + +#include "psock.h" + +/* Next, we define the uip_tcp_appstate_t datatype. This is the state + of our application, and the memory required for this state is + allocated together with each TCP connection. One application state + for each TCP connection. */ +typedef struct hello_world_state { + struct psock p; + char inputbuffer[10]; + char name[40]; +} uip_tcp_appstate_t; + +/* Finally we define the application function to be called by uIP. */ +void hello_world_appcall(void); +#ifndef UIP_APPCALL +#define UIP_APPCALL hello_world_appcall +#endif /* UIP_APPCALL */ + +void hello_world_init(void); + +#endif /* __HELLO_WORLD_H__ */ +/** @} */ +/** @} */ diff --git a/bundles/uip/apps/resolv/Makefile.resolv b/bundles/uip/apps/resolv/Makefile.resolv new file mode 100644 index 00000000..94c37d8c --- /dev/null +++ b/bundles/uip/apps/resolv/Makefile.resolv @@ -0,0 +1 @@ +APP_SOURCES += resolv.c diff --git a/bundles/uip/apps/resolv/resolv.c b/bundles/uip/apps/resolv/resolv.c new file mode 100644 index 00000000..8afbca6c --- /dev/null +++ b/bundles/uip/apps/resolv/resolv.c @@ -0,0 +1,464 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup resolv DNS resolver + * @{ + * + * The uIP DNS resolver functions are used to lookup a hostname and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the resolv_lookup() + * function. New hostnames can be resolved using the resolv_query() + * function. + * + * When a hostname has been resolved (or found to be non-existant), + * the resolver code calls a callback function called resolv_found() + * that must be implemented by the module that uses the resolver. + */ + +/** + * \file + * DNS host name to IP address resolver. + * \author Adam Dunkels + * + * This file implements a DNS host name to IP address resolver. + */ + +/* + * Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $ + * + */ + +#include "resolv.h" +#include "uip.h" + +#include + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +/** \internal The maximum number of retries when asking for a name. */ +#define MAX_RETRIES 8 + +/** \internal The DNS message header. */ +struct dns_hdr { + u16_t id; + u8_t flags1, flags2; +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + u16_t numquestions; + u16_t numanswers; + u16_t numauthrr; + u16_t numextrarr; +}; + +/** \internal The DNS answer message structure. */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t class; + u16_t ttl[2]; + u16_t len; + uip_ipaddr_t ipaddr; +}; + +struct namemap { +#define STATE_UNUSED 0 +#define STATE_NEW 1 +#define STATE_ASKING 2 +#define STATE_DONE 3 +#define STATE_ERROR 4 + u8_t state; + u8_t tmr; + u8_t retries; + u8_t seqno; + u8_t err; + char name[32]; + uip_ipaddr_t ipaddr; +}; + +#ifndef UIP_CONF_RESOLV_ENTRIES +#define RESOLV_ENTRIES 4 +#else /* UIP_CONF_RESOLV_ENTRIES */ +#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES +#endif /* UIP_CONF_RESOLV_ENTRIES */ + + +static struct namemap names[RESOLV_ENTRIES]; + +static u8_t seqno; + +static struct uip_udp_conn *resolv_conn = NULL; + + +/*---------------------------------------------------------------------------*/ +/** \internal + * Walk through a compact encoded DNS name and return the end of it. + * + * \return The end of the name. + */ +/*---------------------------------------------------------------------------*/ +static unsigned char * +parse_name(unsigned char *query) +{ + unsigned char n; + + do { + n = *query++; + + while(n > 0) { + /* printf("%c", *query);*/ + ++query; + --n; + }; + /* printf(".");*/ + } while(*query != 0); + /* printf("\n");*/ + return query + 1; +} +/*---------------------------------------------------------------------------*/ +/** \internal + * Runs through the list of names to see if there are any that have + * not yet been queried and, if so, sends out a query. + */ +/*---------------------------------------------------------------------------*/ +static void +check_entries(void) +{ + register struct dns_hdr *hdr; + char *query, *nptr, *nameptr; + static u8_t i; + static u8_t n; + register struct namemap *namemapptr; + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + namemapptr = &names[i]; + if(namemapptr->state == STATE_NEW || + namemapptr->state == STATE_ASKING) { + if(namemapptr->state == STATE_ASKING) { + if(--namemapptr->tmr == 0) { + if(++namemapptr->retries == MAX_RETRIES) { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + continue; + } + namemapptr->tmr = namemapptr->retries; + } else { + /* printf("Timer %d\n", namemapptr->tmr);*/ + /* Its timer has not run out, so we move on to next + entry. */ + continue; + } + } else { + namemapptr->state = STATE_ASKING; + namemapptr->tmr = 1; + namemapptr->retries = 0; + } + hdr = (struct dns_hdr *)uip_appdata; + memset(hdr, 0, sizeof(struct dns_hdr)); + hdr->id = htons(i); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = HTONS(1); + query = (char *)uip_appdata + 12; + nameptr = namemapptr->name; + --nameptr; + /* Convert hostname into suitable query format. */ + do { + ++nameptr; + nptr = query; + ++query; + for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) { + *query = *nameptr; + ++query; + ++n; + } + *nptr = n; + } while(*nameptr != 0); + { + static unsigned char endquery[] = + {0,0,1,0,1}; + memcpy(query, endquery, 5); + } + uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata)); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +/** \internal + * Called when new UDP data arrives. + */ +/*---------------------------------------------------------------------------*/ +static void +newdata(void) +{ + char *nameptr; + struct dns_answer *ans; + struct dns_hdr *hdr; + static u8_t nquestions, nanswers; + static u8_t i; + register struct namemap *namemapptr; + + hdr = (struct dns_hdr *)uip_appdata; + /* printf("ID %d\n", htons(hdr->id)); + printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); + printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); + printf("Num questions %d, answers %d, authrr %d, extrarr %d\n", + htons(hdr->numquestions), + htons(hdr->numanswers), + htons(hdr->numauthrr), + htons(hdr->numextrarr)); + */ + + /* The ID in the DNS header should be our entry into the name + table. */ + i = htons(hdr->id); + namemapptr = &names[i]; + if(i < RESOLV_ENTRIES && + namemapptr->state == STATE_ASKING) { + + /* This entry is now finished. */ + namemapptr->state = STATE_DONE; + namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* Check for error. If so, call callback to inform. */ + if(namemapptr->err != 0) { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + return; + } + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Skip the name in the question. XXX: This should really be + checked agains the name in the question, to be sure that they + match. */ + nameptr = parse_name((char *)uip_appdata + 12) + 4; + + while(nanswers > 0) { + /* The first byte in the answer resource record determines if it + is a compressed record or a normal one. */ + if(*nameptr & 0xc0) { + /* Compressed name. */ + nameptr +=2; + /* printf("Compressed anwser\n");*/ + } else { + /* Not compressed name. */ + nameptr = parse_name((char *)nameptr); + } + + ans = (struct dns_answer *)nameptr; + /* printf("Answer: type %x, class %x, ttl %x, length %x\n", + htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) + << 16) | htons(ans->ttl[1]), htons(ans->len));*/ + + /* Check for IP address type and Internet class. Others are + discarded. */ + if(ans->type == HTONS(1) && + ans->class == HTONS(1) && + ans->len == HTONS(4)) { + /* printf("IP address %d.%d.%d.%d\n", + htons(ans->ipaddr[0]) >> 8, + htons(ans->ipaddr[0]) & 0xff, + htons(ans->ipaddr[1]) >> 8, + htons(ans->ipaddr[1]) & 0xff);*/ + /* XXX: we should really check that this IP address is the one + we want. */ + namemapptr->ipaddr[0] = ans->ipaddr[0]; + namemapptr->ipaddr[1] = ans->ipaddr[1]; + + resolv_found(namemapptr->name, namemapptr->ipaddr); + return; + } else { + nameptr = nameptr + 10 + htons(ans->len); + } + --nanswers; + } + } + +} +/*---------------------------------------------------------------------------*/ +/** \internal + * The main UDP function. + */ +/*---------------------------------------------------------------------------*/ +void +resolv_appcall(void) +{ + if(uip_udp_conn->rport == HTONS(53)) { + if(uip_poll()) { + check_entries(); + } + if(uip_newdata()) { + newdata(); + } + } +} +/*---------------------------------------------------------------------------*/ +/** + * Queues a name so that a question for the name will be sent out. + * + * \param name The hostname that is to be queried. + */ +/*---------------------------------------------------------------------------*/ +void +resolv_query(char *name) +{ + static u8_t i; + static u8_t lseq, lseqi; + register struct namemap *nameptr; + + lseq = lseqi = 0; + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + nameptr = &names[i]; + if(nameptr->state == STATE_UNUSED) { + break; + } + if(seqno - nameptr->seqno > lseq) { + lseq = seqno - nameptr->seqno; + lseqi = i; + } + } + + if(i == RESOLV_ENTRIES) { + i = lseqi; + nameptr = &names[i]; + } + + /* printf("Using entry %d\n", i);*/ + + strcpy(nameptr->name, name); + nameptr->state = STATE_NEW; + nameptr->seqno = seqno; + ++seqno; +} +/*---------------------------------------------------------------------------*/ +/** + * Look up a hostname in the array of known hostnames. + * + * \note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function resolv_query() can be used to send a query + * for a hostname. + * + * \return A pointer to a 4-byte representation of the hostname's IP + * address, or NULL if the hostname was not found in the array of + * hostnames. + */ +/*---------------------------------------------------------------------------*/ +u16_t * +resolv_lookup(char *name) +{ + static u8_t i; + struct namemap *nameptr; + + /* Walk through the list to see if the name is in there. If it is + not, we return NULL. */ + for(i = 0; i < RESOLV_ENTRIES; ++i) { + nameptr = &names[i]; + if(nameptr->state == STATE_DONE && + strcmp(name, nameptr->name) == 0) { + return nameptr->ipaddr; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * Obtain the currently configured DNS server. + * + * \return A pointer to a 4-byte representation of the IP address of + * the currently configured DNS server or NULL if no DNS server has + * been configured. + */ +/*---------------------------------------------------------------------------*/ +u16_t * +resolv_getserver(void) +{ + if(resolv_conn == NULL) { + return NULL; + } + return resolv_conn->ripaddr; +} +/*---------------------------------------------------------------------------*/ +/** + * Configure which DNS server to use for queries. + * + * \param dnsserver A pointer to a 4-byte representation of the IP + * address of the DNS server to be configured. + */ +/*---------------------------------------------------------------------------*/ +void +resolv_conf(u16_t *dnsserver) +{ + if(resolv_conn != NULL) { + uip_udp_remove(resolv_conn); + } + + resolv_conn = uip_udp_new(dnsserver, HTONS(53)); +} +/*---------------------------------------------------------------------------*/ +/** + * Initalize the resolver. + */ +/*---------------------------------------------------------------------------*/ +void +resolv_init(void) +{ + static u8_t i; + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + names[i].state = STATE_DONE; + } + +} +/*---------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/bundles/uip/apps/resolv/resolv.h b/bundles/uip/apps/resolv/resolv.h new file mode 100644 index 00000000..abab34e1 --- /dev/null +++ b/bundles/uip/apps/resolv/resolv.h @@ -0,0 +1,75 @@ +/** + * \addtogroup resolv + * @{ + */ +/** + * \file + * DNS resolver code header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: resolv.h,v 1.4 2006/06/11 21:46:37 adam Exp $ + * + */ +#ifndef __RESOLV_H__ +#define __RESOLV_H__ + +typedef int uip_udp_appstate_t; +void resolv_appcall(void); +#define UIP_UDP_APPCALL resolv_appcall + +#include "uipopt.h" + +/** + * Callback function which is called when a hostname is found. + * + * This function must be implemented by the module that uses the DNS + * resolver. It is called when a hostname is found, or when a hostname + * was not found. + * + * \param name A pointer to the name that was looked up. \param + * ipaddr A pointer to a 4-byte array containing the IP address of the + * hostname, or NULL if the hostname could not be found. + */ +void resolv_found(char *name, u16_t *ipaddr); + +/* Functions. */ +void resolv_conf(u16_t *dnsserver); +u16_t *resolv_getserver(void); +void resolv_init(void); +u16_t *resolv_lookup(char *name); +void resolv_query(char *name); + +#endif /* __RESOLV_H__ */ + +/** @} */ diff --git a/bundles/uip/apps/smtp/Makefile.smtp b/bundles/uip/apps/smtp/Makefile.smtp new file mode 100644 index 00000000..8b3a5aa4 --- /dev/null +++ b/bundles/uip/apps/smtp/Makefile.smtp @@ -0,0 +1 @@ +APP_SOURCES += smtp.c smtp-strings.c memb.c diff --git a/bundles/uip/apps/smtp/makestrings b/bundles/uip/apps/smtp/makestrings new file mode 100644 index 00000000..bea18a6c --- /dev/null +++ b/bundles/uip/apps/smtp/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "};\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("smtp-strings"); + +exit 0; + diff --git a/bundles/uip/apps/smtp/smtp-strings b/bundles/uip/apps/smtp/smtp-strings new file mode 100644 index 00000000..27f639c2 --- /dev/null +++ b/bundles/uip/apps/smtp/smtp-strings @@ -0,0 +1,11 @@ +smtp_220 "220" +smtp_helo "HELO " +smtp_mail_from "MAIL FROM: " +smtp_rcpt_to "RCPT TO: " +smtp_data "DATA\r\n" +smtp_to "To: " +smtp_from "From: " +smtp_subject "Subject: " +smtp_quit "QUIT\r\n" +smtp_crnl "\r\n" +smtp_crnlperiodcrnl "\r\n.\r\n" \ No newline at end of file diff --git a/bundles/uip/apps/smtp/smtp-strings.c b/bundles/uip/apps/smtp/smtp-strings.c new file mode 100644 index 00000000..f3981a17 --- /dev/null +++ b/bundles/uip/apps/smtp/smtp-strings.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: smtp-strings.c,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +const char smtp_220[4] = +/* "220" */ +{0x32, 0x32, 0x30, }; +const char smtp_helo[6] = +/* "HELO " */ +{0x48, 0x45, 0x4c, 0x4f, 0x20, }; +const char smtp_mail_from[12] = +/* "MAIL FROM: " */ +{0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x20, }; +const char smtp_rcpt_to[10] = +/* "RCPT TO: " */ +{0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, 0x20, }; +const char smtp_data[7] = +/* "DATA\r\n" */ +{0x44, 0x41, 0x54, 0x41, 0xd, 0xa, }; +const char smtp_to[5] = +/* "To: " */ +{0x54, 0x6f, 0x3a, 0x20, }; +const char smtp_cc[5] = +/* "Cc: " */ +{0x43, 0x63, 0x3a, 0x20, }; +const char smtp_from[7] = +/* "From: " */ +{0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, }; +const char smtp_subject[10] = +/* "Subject: " */ +{0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, }; +const char smtp_quit[7] = +/* "QUIT\r\n" */ +{0x51, 0x55, 0x49, 0x54, 0xd, 0xa, }; +const char smtp_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char smtp_crnlperiodcrnl[6] = +/* "\r\n.\r\n" */ +{0xd, 0xa, 0x2e, 0xd, 0xa, }; diff --git a/bundles/uip/apps/smtp/smtp-strings.h b/bundles/uip/apps/smtp/smtp-strings.h new file mode 100644 index 00000000..f5ae68c8 --- /dev/null +++ b/bundles/uip/apps/smtp/smtp-strings.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: smtp-strings.h,v 1.3 2006/06/11 21:46:37 adam Exp $ + */ +extern const char smtp_220[4]; +extern const char smtp_helo[6]; +extern const char smtp_mail_from[12]; +extern const char smtp_rcpt_to[10]; +extern const char smtp_data[7]; +extern const char smtp_to[5]; +extern const char smtp_cc[5]; +extern const char smtp_from[7]; +extern const char smtp_subject[10]; +extern const char smtp_quit[7]; +extern const char smtp_crnl[3]; +extern const char smtp_crnlperiodcrnl[6]; diff --git a/bundles/uip/apps/smtp/smtp.c b/bundles/uip/apps/smtp/smtp.c new file mode 100644 index 00000000..a860006a --- /dev/null +++ b/bundles/uip/apps/smtp/smtp.c @@ -0,0 +1,262 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup smtp SMTP E-mail sender + * @{ + * + * The Simple Mail Transfer Protocol (SMTP) as defined by RFC821 is + * the standard way of sending and transfering e-mail on the + * Internet. This simple example implementation is intended as an + * example of how to implement protocols in uIP, and is able to send + * out e-mail but has not been extensively tested. + */ + +/** + * \file + * SMTP example implementation + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: smtp.c,v 1.4 2006/06/11 21:46:37 adam Exp $ + */ +#include "smtp.h" + +#include "smtp-strings.h" +#include "psock.h" +#include "uip.h" + +#include + +static struct smtp_state s; + +static char *localhostname; +static uip_ipaddr_t smtpserver; + +#define ISO_nl 0x0a +#define ISO_cr 0x0d + +#define ISO_period 0x2e + +#define ISO_2 0x32 +#define ISO_3 0x33 +#define ISO_4 0x34 +#define ISO_5 0x35 + + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(smtp_thread(void)) +{ + PSOCK_BEGIN(&s.psock); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(strncmp(s.inputbuffer, smtp_220, 3) != 0) { + PSOCK_CLOSE(&s.psock); + smtp_done(2); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_helo); + PSOCK_SEND_STR(&s.psock, localhostname); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(3); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_mail_from); + PSOCK_SEND_STR(&s.psock, s.from); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(4); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to); + PSOCK_SEND_STR(&s.psock, s.to); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(5); + PSOCK_EXIT(&s.psock); + } + + if(s.cc != 0) { + PSOCK_SEND_STR(&s.psock, (char *)smtp_rcpt_to); + PSOCK_SEND_STR(&s.psock, s.cc); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(6); + PSOCK_EXIT(&s.psock); + } + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_data); + + PSOCK_READTO(&s.psock, ISO_nl); + + if(s.inputbuffer[0] != ISO_3) { + PSOCK_CLOSE(&s.psock); + smtp_done(7); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_to); + PSOCK_SEND_STR(&s.psock, s.to); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + if(s.cc != 0) { + PSOCK_SEND_STR(&s.psock, (char *)smtp_cc); + PSOCK_SEND_STR(&s.psock, s.cc); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_from); + PSOCK_SEND_STR(&s.psock, s.from); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_SEND_STR(&s.psock, (char *)smtp_subject); + PSOCK_SEND_STR(&s.psock, s.subject); + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnl); + + PSOCK_SEND(&s.psock, s.msg, s.msglen); + + PSOCK_SEND_STR(&s.psock, (char *)smtp_crnlperiodcrnl); + + PSOCK_READTO(&s.psock, ISO_nl); + if(s.inputbuffer[0] != ISO_2) { + PSOCK_CLOSE(&s.psock); + smtp_done(8); + PSOCK_EXIT(&s.psock); + } + + PSOCK_SEND_STR(&s.psock, (char *)smtp_quit); + smtp_done(SMTP_ERR_OK); + PSOCK_END(&s.psock); +} +/*---------------------------------------------------------------------------*/ +void +smtp_appcall(void) +{ + if(uip_closed()) { + s.connected = 0; + return; + } + if(uip_aborted() || uip_timedout()) { + s.connected = 0; + smtp_done(1); + return; + } + smtp_thread(); +} +/*---------------------------------------------------------------------------*/ +/** + * Specificy an SMTP server and hostname. + * + * This function is used to configure the SMTP module with an SMTP + * server and the hostname of the host. + * + * \param lhostname The hostname of the uIP host. + * + * \param server A pointer to a 4-byte array representing the IP + * address of the SMTP server to be configured. + */ +void +smtp_configure(char *lhostname, void *server) +{ + localhostname = lhostname; + uip_ipaddr_copy(smtpserver, server); +} +/*---------------------------------------------------------------------------*/ +/** + * Send an e-mail. + * + * \param to The e-mail address of the receiver of the e-mail. + * \param cc The e-mail address of the CC: receivers of the e-mail. + * \param from The e-mail address of the sender of the e-mail. + * \param subject The subject of the e-mail. + * \param msg The actual e-mail message. + * \param msglen The length of the e-mail message. + */ +unsigned char +smtp_send(char *to, char *cc, char *from, + char *subject, char *msg, u16_t msglen) +{ + struct uip_conn *conn; + + conn = uip_connect(smtpserver, HTONS(25)); + if(conn == NULL) { + return 0; + } + s.connected = 1; + s.to = to; + s.cc = cc; + s.from = from; + s.subject = subject; + s.msg = msg; + s.msglen = msglen; + + PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer)); + + return 1; +} +/*---------------------------------------------------------------------------*/ +void +smtp_init(void) +{ + s.connected = 0; +} +/*---------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/bundles/uip/apps/smtp/smtp.h b/bundles/uip/apps/smtp/smtp.h new file mode 100644 index 00000000..44d0766e --- /dev/null +++ b/bundles/uip/apps/smtp/smtp.h @@ -0,0 +1,103 @@ + +/** + * \addtogroup smtp + * @{ + */ + + +/** + * \file + * SMTP header file + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: smtp.h,v 1.4 2006/06/11 21:46:37 adam Exp $ + * + */ +#ifndef __SMTP_H__ +#define __SMTP_H__ + +#include "uipopt.h" + +/** + * Error number that signifies a non-error condition. + */ +#define SMTP_ERR_OK 0 + +/** + * Callback function that is called when an e-mail transmission is + * done. + * + * This function must be implemented by the module that uses the SMTP + * module. + * + * \param error The number of the error if an error occured, or + * SMTP_ERR_OK. + */ +void smtp_done(unsigned char error); + +void smtp_init(void); + +/* Functions. */ +void smtp_configure(char *localhostname, u16_t *smtpserver); +unsigned char smtp_send(char *to, char *from, + char *subject, char *msg, + u16_t msglen); +#define SMTP_SEND(to, cc, from, subject, msg) \ + smtp_send(to, cc, from, subject, msg, strlen(msg)) + +void smtp_appcall(void); + +struct smtp_state { + u8_t state; + char *to; + char *from; + char *subject; + char *msg; + u16_t msglen; + + u16_t sentlen, textlen; + u16_t sendptr; + +}; + + +#ifndef UIP_APPCALL +#define UIP_APPCALL smtp_appcall +#endif +typedef struct smtp_state uip_tcp_appstate_t; + + +#endif /* __SMTP_H__ */ + +/** @} */ diff --git a/bundles/uip/apps/telnetd/Makefile.telnetd b/bundles/uip/apps/telnetd/Makefile.telnetd new file mode 100644 index 00000000..afb1b593 --- /dev/null +++ b/bundles/uip/apps/telnetd/Makefile.telnetd @@ -0,0 +1 @@ +APP_SOURCES += telnetd.c shell.c memb.c diff --git a/bundles/uip/apps/telnetd/shell.c b/bundles/uip/apps/telnetd/shell.c new file mode 100644 index 00000000..9345cae9 --- /dev/null +++ b/bundles/uip/apps/telnetd/shell.c @@ -0,0 +1,123 @@ + /* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $ + * + */ + +#include "shell.h" + +#include + +struct ptentry { + char *commandstr; + void (* pfunc)(char *str); +}; + +#define SHELL_PROMPT "uIP 1.0> " + +/*---------------------------------------------------------------------------*/ +static void +parse(register char *str, struct ptentry *t) +{ + struct ptentry *p; + for(p = t; p->commandstr != NULL; ++p) { + if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) { + break; + } + } + + p->pfunc(str); +} +/*---------------------------------------------------------------------------*/ +static void +inttostr(register char *str, unsigned int i) +{ + str[0] = '0' + i / 100; + if(str[0] == '0') { + str[0] = ' '; + } + str[1] = '0' + (i / 10) % 10; + if(str[0] == ' ' && str[1] == '0') { + str[1] = ' '; + } + str[2] = '0' + i % 10; + str[3] = ' '; + str[4] = 0; +} +/*---------------------------------------------------------------------------*/ +static void +help(char *str) +{ + shell_output("Available commands:", ""); + shell_output("stats - show network statistics", ""); + shell_output("conn - show TCP connections", ""); + shell_output("help, ? - show help", ""); + shell_output("exit - exit shell", ""); +} +/*---------------------------------------------------------------------------*/ +static void +unknown(char *str) +{ + if(strlen(str) > 0) { + shell_output("Unknown command: ", str); + } +} +/*---------------------------------------------------------------------------*/ +static struct ptentry parsetab[] = + {{"stats", help}, + {"conn", help}, + {"help", help}, + {"exit", shell_quit}, + {"?", help}, + + /* Default action */ + {NULL, unknown}}; +/*---------------------------------------------------------------------------*/ +void +shell_init(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +shell_start(void) +{ + shell_output("uIP command shell", ""); + shell_output("Type '?' and return for help", ""); + shell_prompt(SHELL_PROMPT); +} +/*---------------------------------------------------------------------------*/ +void +shell_input(char *cmd) +{ + parse(cmd, parsetab); + shell_prompt(SHELL_PROMPT); +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/apps/telnetd/shell.h b/bundles/uip/apps/telnetd/shell.h new file mode 100644 index 00000000..b57d7be2 --- /dev/null +++ b/bundles/uip/apps/telnetd/shell.h @@ -0,0 +1,104 @@ +/** + * \file + * Interface for the Contiki shell. + * \author Adam Dunkels + * + * Some of the functions declared in this file must be implemented as + * a shell back-end in the architecture specific files of a Contiki + * port. + */ + + +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki desktop OS. + * + * $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $ + * + */ +#ifndef __SHELL_H__ +#define __SHELL_H__ + +/** + * Initialize the shell. + * + * Called when the shell front-end process starts. This function may + * be used to start listening for signals. + */ +void shell_init(void); + +/** + * Start the shell back-end. + * + * Called by the front-end when a new shell is started. + */ +void shell_start(void); + +/** + * Process a shell command. + * + * This function will be called by the shell GUI / telnet server whan + * a command has been entered that should be processed by the shell + * back-end. + * + * \param command The command to be processed. + */ +void shell_input(char *command); + +/** + * Quit the shell. + * + */ +void shell_quit(char *); + + +/** + * Print a string to the shell window. + * + * This function is implemented by the shell GUI / telnet server and + * can be called by the shell back-end to output a string in the + * shell window. The string is automatically appended with a linebreak. + * + * \param str1 The first half of the string to be output. + * \param str2 The second half of the string to be output. + */ +void shell_output(char *str1, char *str2); + +/** + * Print a prompt to the shell window. + * + * This function can be used by the shell back-end to print out a + * prompt to the shell window. + * + * \param prompt The prompt to be printed. + * + */ +void shell_prompt(char *prompt); + +#endif /* __SHELL_H__ */ diff --git a/bundles/uip/apps/telnetd/telnetd.c b/bundles/uip/apps/telnetd/telnetd.c new file mode 100644 index 00000000..7a5ae858 --- /dev/null +++ b/bundles/uip/apps/telnetd/telnetd.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $ + * + */ + +#include "uip.h" +#include "telnetd.h" +#include "memb.h" +#include "shell.h" + +#include + +#define ISO_nl 0x0a +#define ISO_cr 0x0d + +struct telnetd_line { + char line[TELNETD_CONF_LINELEN]; +}; +MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES); + +#define STATE_NORMAL 0 +#define STATE_IAC 1 +#define STATE_WILL 2 +#define STATE_WONT 3 +#define STATE_DO 4 +#define STATE_DONT 5 +#define STATE_CLOSE 6 + +static struct telnetd_state s; + +#define TELNET_IAC 255 +#define TELNET_WILL 251 +#define TELNET_WONT 252 +#define TELNET_DO 253 +#define TELNET_DONT 254 +/*---------------------------------------------------------------------------*/ +static char * +alloc_line(void) +{ + return memb_alloc(&linemem); +} +/*---------------------------------------------------------------------------*/ +static void +dealloc_line(char *line) +{ + memb_free(&linemem, line); +} +/*---------------------------------------------------------------------------*/ +void +shell_quit(char *str) +{ + s.state = STATE_CLOSE; +} +/*---------------------------------------------------------------------------*/ +static void +sendline(char *line) +{ + static unsigned int i; + + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + if(s.lines[i] == NULL) { + s.lines[i] = line; + break; + } + } + if(i == TELNETD_CONF_NUMLINES) { + dealloc_line(line); + } +} +/*---------------------------------------------------------------------------*/ +void +shell_prompt(char *str) +{ + char *line; + line = alloc_line(); + if(line != NULL) { + strncpy(line, str, TELNETD_CONF_LINELEN); + /* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/ + sendline(line); + } +} +/*---------------------------------------------------------------------------*/ +void +shell_output(char *str1, char *str2) +{ + static unsigned len; + char *line; + + line = alloc_line(); + if(line != NULL) { + len = strlen(str1); + strncpy(line, str1, TELNETD_CONF_LINELEN); + if(len < TELNETD_CONF_LINELEN) { + strncpy(line + len, str2, TELNETD_CONF_LINELEN - len); + } + len = strlen(line); + if(len < TELNETD_CONF_LINELEN - 2) { + line[len] = ISO_cr; + line[len+1] = ISO_nl; + line[len+2] = 0; + } + /* petsciiconv_toascii(line, TELNETD_CONF_LINELEN);*/ + sendline(line); + } +} +/*---------------------------------------------------------------------------*/ +void +telnetd_init(void) +{ + uip_listen(HTONS(23)); + memb_init(&linemem); + shell_init(); +} +/*---------------------------------------------------------------------------*/ +static void +acked(void) +{ + static unsigned int i; + + while(s.numsent > 0) { + dealloc_line(s.lines[0]); + for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) { + s.lines[i - 1] = s.lines[i]; + } + s.lines[TELNETD_CONF_NUMLINES - 1] = NULL; + --s.numsent; + } +} +/*---------------------------------------------------------------------------*/ +static void +senddata(void) +{ + static char *bufptr, *lineptr; + static int buflen, linelen; + + bufptr = uip_appdata; + buflen = 0; + for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES && + s.lines[s.numsent] != NULL ; ++s.numsent) { + lineptr = s.lines[s.numsent]; + linelen = strlen(lineptr); + if(linelen > TELNETD_CONF_LINELEN) { + linelen = TELNETD_CONF_LINELEN; + } + if(buflen + linelen < uip_mss()) { + memcpy(bufptr, lineptr, linelen); + bufptr += linelen; + buflen += linelen; + } else { + break; + } + } + uip_send(uip_appdata, buflen); +} +/*---------------------------------------------------------------------------*/ +static void +closed(void) +{ + static unsigned int i; + + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + if(s.lines[i] != NULL) { + dealloc_line(s.lines[i]); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +get_char(u8_t c) +{ + if(c == ISO_cr) { + return; + } + + s.buf[(int)s.bufptr] = c; + if(s.buf[(int)s.bufptr] == ISO_nl || + s.bufptr == sizeof(s.buf) - 1) { + if(s.bufptr > 0) { + s.buf[(int)s.bufptr] = 0; + /* petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);*/ + } + shell_input(s.buf); + s.bufptr = 0; + } else { + ++s.bufptr; + } +} +/*---------------------------------------------------------------------------*/ +static void +sendopt(u8_t option, u8_t value) +{ + char *line; + line = alloc_line(); + if(line != NULL) { + line[0] = TELNET_IAC; + line[1] = option; + line[2] = value; + line[3] = 0; + sendline(line); + } +} +/*---------------------------------------------------------------------------*/ +static void +newdata(void) +{ + u16_t len; + u8_t c; + char *dataptr; + + + len = uip_datalen(); + dataptr = (char *)uip_appdata; + + while(len > 0 && s.bufptr < sizeof(s.buf)) { + c = *dataptr; + ++dataptr; + --len; + switch(s.state) { + case STATE_IAC: + if(c == TELNET_IAC) { + get_char(c); + s.state = STATE_NORMAL; + } else { + switch(c) { + case TELNET_WILL: + s.state = STATE_WILL; + break; + case TELNET_WONT: + s.state = STATE_WONT; + break; + case TELNET_DO: + s.state = STATE_DO; + break; + case TELNET_DONT: + s.state = STATE_DONT; + break; + default: + s.state = STATE_NORMAL; + break; + } + } + break; + case STATE_WILL: + /* Reply with a DONT */ + sendopt(TELNET_DONT, c); + s.state = STATE_NORMAL; + break; + + case STATE_WONT: + /* Reply with a DONT */ + sendopt(TELNET_DONT, c); + s.state = STATE_NORMAL; + break; + case STATE_DO: + /* Reply with a WONT */ + sendopt(TELNET_WONT, c); + s.state = STATE_NORMAL; + break; + case STATE_DONT: + /* Reply with a WONT */ + sendopt(TELNET_WONT, c); + s.state = STATE_NORMAL; + break; + case STATE_NORMAL: + if(c == TELNET_IAC) { + s.state = STATE_IAC; + } else { + get_char(c); + } + break; + } + + + } + +} +/*---------------------------------------------------------------------------*/ +void +telnetd_appcall(void) +{ + static unsigned int i; + if(uip_connected()) { + /* tcp_markconn(uip_conn, &s);*/ + for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) { + s.lines[i] = NULL; + } + s.bufptr = 0; + s.state = STATE_NORMAL; + + shell_start(); + } + + if(s.state == STATE_CLOSE) { + s.state = STATE_NORMAL; + uip_close(); + return; + } + + if(uip_closed() || + uip_aborted() || + uip_timedout()) { + closed(); + } + + if(uip_acked()) { + acked(); + } + + if(uip_newdata()) { + newdata(); + } + + if(uip_rexmit() || + uip_newdata() || + uip_acked() || + uip_connected() || + uip_poll()) { + senddata(); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/apps/telnetd/telnetd.h b/bundles/uip/apps/telnetd/telnetd.h new file mode 100644 index 00000000..2ee8acdb --- /dev/null +++ b/bundles/uip/apps/telnetd/telnetd.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $ + * + */ +#ifndef __TELNETD_H__ +#define __TELNETD_H__ + +#include "uipopt.h" + +void telnetd_appcall(void); + +#ifndef TELNETD_CONF_LINELEN +#define TELNETD_CONF_LINELEN 40 +#endif +#ifndef TELNETD_CONF_NUMLINES +#define TELNETD_CONF_NUMLINES 16 +#endif + +struct telnetd_state { + char *lines[TELNETD_CONF_NUMLINES]; + char buf[TELNETD_CONF_LINELEN]; + char bufptr; + u8_t numsent; + u8_t state; +}; + +typedef struct telnetd_state uip_tcp_appstate_t; + +#ifndef UIP_APPCALL +#define UIP_APPCALL telnetd_appcall +#endif + +#endif /* __TELNETD_H__ */ diff --git a/bundles/uip/apps/webclient/Makefile.webclient b/bundles/uip/apps/webclient/Makefile.webclient new file mode 100644 index 00000000..e6e7f082 --- /dev/null +++ b/bundles/uip/apps/webclient/Makefile.webclient @@ -0,0 +1 @@ +APP_SOURCES += webclient-strings.c webclient.c diff --git a/bundles/uip/apps/webclient/makestrings b/bundles/uip/apps/webclient/makestrings new file mode 100644 index 00000000..6dec075d --- /dev/null +++ b/bundles/uip/apps/webclient/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "0 };\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("webclient-strings"); + +exit 0; + diff --git a/bundles/uip/apps/webclient/webclient-strings b/bundles/uip/apps/webclient/webclient-strings new file mode 100644 index 00000000..a3313972 --- /dev/null +++ b/bundles/uip/apps/webclient/webclient-strings @@ -0,0 +1,31 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".text" +http_txt ".txt" +http_user_agent_fields "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" diff --git a/bundles/uip/apps/webclient/webclient-strings.c b/bundles/uip/apps/webclient/webclient-strings.c new file mode 100644 index 00000000..94723308 --- /dev/null +++ b/bundles/uip/apps/webclient/webclient-strings.c @@ -0,0 +1,93 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0 }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, 0 }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, 0 }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, 0 }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, 0 }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0 }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0 }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0 }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0 }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0 }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, 0 }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, 0 }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0 }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, 0 }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, 0 }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, 0 }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, 0 }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, 0 }; +const char http_text[6] = +/* ".text" */ +{0x2e, 0x74, 0x65, 0x78, 0x74, 0 }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, 0 }; +const char http_user_agent_fields[77] = +/* "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0xd, 0xa, 0 }; diff --git a/bundles/uip/apps/webclient/webclient-strings.h b/bundles/uip/apps/webclient/webclient-strings.h new file mode 100644 index 00000000..9e3ec934 --- /dev/null +++ b/bundles/uip/apps/webclient/webclient-strings.h @@ -0,0 +1,31 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[6]; +extern const char http_txt[5]; +extern const char http_user_agent_fields[77]; diff --git a/bundles/uip/apps/webclient/webclient.c b/bundles/uip/apps/webclient/webclient.c new file mode 100644 index 00000000..746c008c --- /dev/null +++ b/bundles/uip/apps/webclient/webclient.c @@ -0,0 +1,439 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup webclient Web client + * @{ + * + * This example shows a HTTP client that is able to download web pages + * and files from web servers. It requires a number of callback + * functions to be implemented by the module that utilizes the code: + * webclient_datahandler(), webclient_connected(), + * webclient_timedout(), webclient_aborted(), webclient_closed(). + */ + +/** + * \file + * Implementation of the HTTP client. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ + +#include "uip.h" +#include "uiplib.h" +#include "webclient.h" +#include "resolv.h" + +#include + +#define WEBCLIENT_TIMEOUT 100 + +#define WEBCLIENT_STATE_STATUSLINE 0 +#define WEBCLIENT_STATE_HEADERS 1 +#define WEBCLIENT_STATE_DATA 2 +#define WEBCLIENT_STATE_CLOSE 3 + +#define HTTPFLAG_NONE 0 +#define HTTPFLAG_OK 1 +#define HTTPFLAG_MOVED 2 +#define HTTPFLAG_ERROR 3 + + +#define ISO_nl 0x0a +#define ISO_cr 0x0d +#define ISO_space 0x20 + + +static struct webclient_state s; + +/*-----------------------------------------------------------------------------------*/ +char * +webclient_mimetype(void) +{ + return s.mimetype; +} +/*-----------------------------------------------------------------------------------*/ +char * +webclient_filename(void) +{ + return s.file; +} +/*-----------------------------------------------------------------------------------*/ +char * +webclient_hostname(void) +{ + return s.host; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +webclient_port(void) +{ + return s.port; +} +/*-----------------------------------------------------------------------------------*/ +void +webclient_init(void) +{ + +} +/*-----------------------------------------------------------------------------------*/ +static void +init_connection(void) +{ + s.state = WEBCLIENT_STATE_STATUSLINE; + + s.getrequestleft = sizeof(http_get) - 1 + 1 + + sizeof(http_10) - 1 + + sizeof(http_crnl) - 1 + + sizeof(http_host) - 1 + + sizeof(http_crnl) - 1 + + strlen(http_user_agent_fields) + + strlen(s.file) + strlen(s.host); + s.getrequestptr = 0; + + s.httpheaderlineptr = 0; +} +/*-----------------------------------------------------------------------------------*/ +void +webclient_close(void) +{ + s.state = WEBCLIENT_STATE_CLOSE; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +webclient_get(char *host, u16_t port, char *file) +{ + struct uip_conn *conn; + uip_ipaddr_t *ipaddr; + static uip_ipaddr_t addr; + + /* First check if the host is an IP address. */ + ipaddr = &addr; + if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) { + ipaddr = (uip_ipaddr_t *)resolv_lookup(host); + + if(ipaddr == NULL) { + return 0; + } + } + + conn = uip_connect(ipaddr, htons(port)); + + if(conn == NULL) { + return 0; + } + + s.port = port; + strncpy(s.file, file, sizeof(s.file)); + strncpy(s.host, host, sizeof(s.host)); + + init_connection(); + return 1; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned char * +copy_string(unsigned char *dest, + const unsigned char *src, unsigned char len) +{ + strncpy(dest, src, len); + return dest + len; +} +/*-----------------------------------------------------------------------------------*/ +static void +senddata(void) +{ + u16_t len; + char *getrequest; + char *cptr; + + if(s.getrequestleft > 0) { + cptr = getrequest = (char *)uip_appdata; + + cptr = copy_string(cptr, http_get, sizeof(http_get) - 1); + cptr = copy_string(cptr, s.file, strlen(s.file)); + *cptr++ = ISO_space; + cptr = copy_string(cptr, http_10, sizeof(http_10) - 1); + + cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1); + + cptr = copy_string(cptr, http_host, sizeof(http_host) - 1); + cptr = copy_string(cptr, s.host, strlen(s.host)); + cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1); + + cptr = copy_string(cptr, http_user_agent_fields, + strlen(http_user_agent_fields)); + + len = s.getrequestleft > uip_mss()? + uip_mss(): + s.getrequestleft; + uip_send(&(getrequest[s.getrequestptr]), len); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +acked(void) +{ + u16_t len; + + if(s.getrequestleft > 0) { + len = s.getrequestleft > uip_mss()? + uip_mss(): + s.getrequestleft; + s.getrequestleft -= len; + s.getrequestptr += len; + } +} +/*-----------------------------------------------------------------------------------*/ +static u16_t +parse_statusline(u16_t len) +{ + char *cptr; + + while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { + s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; + ++((char *)uip_appdata); + --len; + if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { + + if((strncmp(s.httpheaderline, http_10, + sizeof(http_10) - 1) == 0) || + (strncmp(s.httpheaderline, http_11, + sizeof(http_11) - 1) == 0)) { + cptr = &(s.httpheaderline[9]); + s.httpflag = HTTPFLAG_NONE; + if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { + /* 200 OK */ + s.httpflag = HTTPFLAG_OK; + } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || + strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { + /* 301 Moved permanently or 302 Found. Location: header line + will contain thw new location. */ + s.httpflag = HTTPFLAG_MOVED; + } else { + s.httpheaderline[s.httpheaderlineptr - 1] = 0; + } + } else { + uip_abort(); + webclient_aborted(); + return 0; + } + + /* We're done parsing the status line, so we reset the pointer + and start parsing the HTTP headers.*/ + s.httpheaderlineptr = 0; + s.state = WEBCLIENT_STATE_HEADERS; + break; + } else { + ++s.httpheaderlineptr; + } + } + return len; +} +/*-----------------------------------------------------------------------------------*/ +static char +casecmp(char *str1, const char *str2, char len) +{ + static char c; + + while(len > 0) { + c = *str1; + /* Force lower-case characters. */ + if(c & 0x40) { + c |= 0x20; + } + if(*str2 != c) { + return 1; + } + ++str1; + ++str2; + --len; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +static u16_t +parse_headers(u16_t len) +{ + char *cptr; + static unsigned char i; + + while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { + s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; + ++((char *)uip_appdata); + --len; + if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { + /* We have an entire HTTP header line in s.httpheaderline, so + we parse it. */ + if(s.httpheaderline[0] == ISO_cr) { + /* This was the last header line (i.e., and empty "\r\n"), so + we are done with the headers and proceed with the actual + data. */ + s.state = WEBCLIENT_STATE_DATA; + return len; + } + + s.httpheaderline[s.httpheaderlineptr - 1] = 0; + /* Check for specific HTTP header fields. */ + if(casecmp(s.httpheaderline, http_content_type, + sizeof(http_content_type) - 1) == 0) { + /* Found Content-type field. */ + cptr = strchr(s.httpheaderline, ';'); + if(cptr != NULL) { + *cptr = 0; + } + strncpy(s.mimetype, s.httpheaderline + + sizeof(http_content_type) - 1, sizeof(s.mimetype)); + } else if(casecmp(s.httpheaderline, http_location, + sizeof(http_location) - 1) == 0) { + cptr = s.httpheaderline + + sizeof(http_location) - 1; + + if(strncmp(cptr, http_http, 7) == 0) { + cptr += 7; + for(i = 0; i < s.httpheaderlineptr - 7; ++i) { + if(*cptr == 0 || + *cptr == '/' || + *cptr == ' ' || + *cptr == ':') { + s.host[i] = 0; + break; + } + s.host[i] = *cptr; + ++cptr; + } + } + strncpy(s.file, cptr, sizeof(s.file)); + /* s.file[s.httpheaderlineptr - i] = 0;*/ + } + + + /* We're done parsing, so we reset the pointer and start the + next line. */ + s.httpheaderlineptr = 0; + } else { + ++s.httpheaderlineptr; + } + } + return len; +} +/*-----------------------------------------------------------------------------------*/ +static void +newdata(void) +{ + u16_t len; + + len = uip_datalen(); + + if(s.state == WEBCLIENT_STATE_STATUSLINE) { + len = parse_statusline(len); + } + + if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) { + len = parse_headers(len); + } + + if(len > 0 && s.state == WEBCLIENT_STATE_DATA && + s.httpflag != HTTPFLAG_MOVED) { + webclient_datahandler((char *)uip_appdata, len); + } +} +/*-----------------------------------------------------------------------------------*/ +void +webclient_appcall(void) +{ + if(uip_connected()) { + s.timer = 0; + s.state = WEBCLIENT_STATE_STATUSLINE; + senddata(); + webclient_connected(); + return; + } + + if(s.state == WEBCLIENT_STATE_CLOSE) { + webclient_closed(); + uip_abort(); + return; + } + + if(uip_aborted()) { + webclient_aborted(); + } + if(uip_timedout()) { + webclient_timedout(); + } + + + if(uip_acked()) { + s.timer = 0; + acked(); + } + if(uip_newdata()) { + s.timer = 0; + newdata(); + } + if(uip_rexmit() || + uip_newdata() || + uip_acked()) { + senddata(); + } else if(uip_poll()) { + ++s.timer; + if(s.timer == WEBCLIENT_TIMEOUT) { + webclient_timedout(); + uip_abort(); + return; + } + /* senddata();*/ + } + + if(uip_closed()) { + if(s.httpflag != HTTPFLAG_MOVED) { + /* Send NULL data to signal EOF. */ + webclient_datahandler(NULL, 0); + } else { + if(resolv_lookup(s.host) == NULL) { + resolv_query(s.host); + } + webclient_get(s.host, s.port, s.file); + } + } +} +/*-----------------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/bundles/uip/apps/webclient/webclient.h b/bundles/uip/apps/webclient/webclient.h new file mode 100644 index 00000000..44cb95ca --- /dev/null +++ b/bundles/uip/apps/webclient/webclient.h @@ -0,0 +1,228 @@ +/** + * \addtogroup webclient + * @{ + */ + +/** + * \file + * Header file for the HTTP client. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: webclient.h,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ +#ifndef __WEBCLIENT_H__ +#define __WEBCLIENT_H__ + + +#include "webclient-strings.h" +#include "uipopt.h" + +#define WEBCLIENT_CONF_MAX_URLLEN 100 + +struct webclient_state { + u8_t timer; + u8_t state; + u8_t httpflag; + + u16_t port; + char host[40]; + char file[WEBCLIENT_CONF_MAX_URLLEN]; + u16_t getrequestptr; + u16_t getrequestleft; + + char httpheaderline[200]; + u16_t httpheaderlineptr; + + char mimetype[32]; +}; + +typedef struct webclient_state uip_tcp_appstate_t; +#define UIP_APPCALL webclient_appcall + +/** + * Callback function that is called from the webclient code when HTTP + * data has been received. + * + * This function must be implemented by the module that uses the + * webclient code. The function is called from the webclient module + * when HTTP data has been received. The function is not called when + * HTTP headers are received, only for the actual data. + * + * \note This function is called many times, repetedly, when data is + * being received, and not once when all data has been received. + * + * \param data A pointer to the data that has been received. + * \param len The length of the data that has been received. + */ +void webclient_datahandler(char *data, u16_t len); + +/** + * Callback function that is called from the webclient code when the + * HTTP connection has been connected to the web server. + * + * This function must be implemented by the module that uses the + * webclient code. + */ +void webclient_connected(void); + +/** + * Callback function that is called from the webclient code if the + * HTTP connection to the web server has timed out. + * + * This function must be implemented by the module that uses the + * webclient code. + */ +void webclient_timedout(void); + +/** + * Callback function that is called from the webclient code if the + * HTTP connection to the web server has been aborted by the web + * server. + * + * This function must be implemented by the module that uses the + * webclient code. + */ +void webclient_aborted(void); + +/** + * Callback function that is called from the webclient code when the + * HTTP connection to the web server has been closed. + * + * This function must be implemented by the module that uses the + * webclient code. + */ +void webclient_closed(void); + + + +/** + * Initialize the webclient module. + */ +void webclient_init(void); + +/** + * Open an HTTP connection to a web server and ask for a file using + * the GET method. + * + * This function opens an HTTP connection to the specified web server + * and requests the specified file using the GET method. When the HTTP + * connection has been connected, the webclient_connected() callback + * function is called and when the HTTP data arrives the + * webclient_datahandler() callback function is called. + * + * The callback function webclient_timedout() is called if the web + * server could not be contacted, and the webclient_aborted() callback + * function is called if the HTTP connection is aborted by the web + * server. + * + * When the HTTP request has been completed and the HTTP connection is + * closed, the webclient_closed() callback function will be called. + * + * \note If the function is passed a host name, it must already be in + * the resolver cache in order for the function to connect to the web + * server. It is therefore up to the calling module to implement the + * resolver calls and the signal handler used for reporting a resolv + * query answer. + * + * \param host A pointer to a string containing either a host name or + * a numerical IP address in dotted decimal notation (e.g., 192.168.23.1). + * + * \param port The port number to which to connect, in host byte order. + * + * \param file A pointer to the name of the file to get. + * + * \retval 0 if the host name could not be found in the cache, or + * if a TCP connection could not be created. + * + * \retval 1 if the connection was initiated. + */ +unsigned char webclient_get(char *host, u16_t port, char *file); + +/** + * Close the currently open HTTP connection. + */ +void webclient_close(void); +void webclient_appcall(void); + +/** + * Obtain the MIME type of the current HTTP data stream. + * + * \return A pointer to a string contaning the MIME type. The string + * may be empty if no MIME type was reported by the web server. + */ +char *webclient_mimetype(void); + +/** + * Obtain the filename of the current HTTP data stream. + * + * The filename of an HTTP request may be changed by the web server, + * and may therefore not be the same as when the original GET request + * was made with webclient_get(). This function is used for obtaining + * the current filename. + * + * \return A pointer to the current filename. + */ +char *webclient_filename(void); + +/** + * Obtain the hostname of the current HTTP data stream. + * + * The hostname of the web server of an HTTP request may be changed + * by the web server, and may therefore not be the same as when the + * original GET request was made with webclient_get(). This function + * is used for obtaining the current hostname. + * + * \return A pointer to the current hostname. + */ +char *webclient_hostname(void); + +/** + * Obtain the port number of the current HTTP data stream. + * + * The port number of an HTTP request may be changed by the web + * server, and may therefore not be the same as when the original GET + * request was made with webclient_get(). This function is used for + * obtaining the current port number. + * + * \return The port number of the current HTTP data stream, in host byte order. + */ +unsigned short webclient_port(void); + + + +#endif /* __WEBCLIENT_H__ */ + +/** @} */ diff --git a/bundles/uip/apps/webserver/Makefile.webserver b/bundles/uip/apps/webserver/Makefile.webserver new file mode 100644 index 00000000..7d3e0869 --- /dev/null +++ b/bundles/uip/apps/webserver/Makefile.webserver @@ -0,0 +1 @@ +APP_SOURCES += httpd.c http-strings.c httpd-fs.c httpd-cgi.c diff --git a/bundles/uip/apps/webserver/http-strings b/bundles/uip/apps/webserver/http-strings new file mode 100644 index 00000000..d0b9121b --- /dev/null +++ b/bundles/uip/apps/webserver/http-strings @@ -0,0 +1,35 @@ +http_http "http://" +http_200 "200 " +http_301 "301 " +http_302 "302 " +http_get "GET " +http_10 "HTTP/1.0" +http_11 "HTTP/1.1" +http_content_type "content-type: " +http_texthtml "text/html" +http_location "location: " +http_host "host: " +http_crnl "\r\n" +http_index_html "/index.html" +http_404_html "/404.html" +http_referer "Referer:" +http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" +http_content_type_plain "Content-type: text/plain\r\n\r\n" +http_content_type_html "Content-type: text/html\r\n\r\n" +http_content_type_css "Content-type: text/css\r\n\r\n" +http_content_type_text "Content-type: text/text\r\n\r\n" +http_content_type_png "Content-type: image/png\r\n\r\n" +http_content_type_gif "Content-type: image/gif\r\n\r\n" +http_content_type_jpg "Content-type: image/jpeg\r\n\r\n" +http_content_type_binary "Content-type: application/octet-stream\r\n\r\n" +http_html ".html" +http_shtml ".shtml" +http_htm ".htm" +http_css ".css" +http_png ".png" +http_gif ".gif" +http_jpg ".jpg" +http_text ".txt" +http_txt ".txt" + diff --git a/bundles/uip/apps/webserver/http-strings.c b/bundles/uip/apps/webserver/http-strings.c new file mode 100644 index 00000000..0d822baf --- /dev/null +++ b/bundles/uip/apps/webserver/http-strings.c @@ -0,0 +1,102 @@ +const char http_http[8] = +/* "http://" */ +{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_200[5] = +/* "200 " */ +{0x32, 0x30, 0x30, 0x20, }; +const char http_301[5] = +/* "301 " */ +{0x33, 0x30, 0x31, 0x20, }; +const char http_302[5] = +/* "302 " */ +{0x33, 0x30, 0x32, 0x20, }; +const char http_get[5] = +/* "GET " */ +{0x47, 0x45, 0x54, 0x20, }; +const char http_10[9] = +/* "HTTP/1.0" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, }; +const char http_11[9] = +/* "HTTP/1.1" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, }; +const char http_content_type[15] = +/* "content-type: " */ +{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, }; +const char http_texthtml[10] = +/* "text/html" */ +{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_location[11] = +/* "location: " */ +{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, }; +const char http_host[7] = +/* "host: " */ +{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, }; +const char http_crnl[3] = +/* "\r\n" */ +{0xd, 0xa, }; +const char http_index_html[12] = +/* "/index.html" */ +{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_404_html[10] = +/* "/404.html" */ +{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_referer[9] = +/* "Referer:" */ +{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, }; +const char http_header_200[84] = +/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_header_404[91] = +/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0 http://www.sics.se/~adam/uip/\r\nConnection: close\r\n" */ +{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, }; +const char http_content_type_plain[29] = +/* "Content-type: text/plain\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_html[28] = +/* "Content-type: text/html\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_css [27] = +/* "Content-type: text/css\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_text[28] = +/* "Content-type: text/text\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_png [28] = +/* "Content-type: image/png\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_gif [28] = +/* "Content-type: image/gif\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_jpg [29] = +/* "Content-type: image/jpeg\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, }; +const char http_content_type_binary[43] = +/* "Content-type: application/octet-stream\r\n\r\n" */ +{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, }; +const char http_html[6] = +/* ".html" */ +{0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_shtml[7] = +/* ".shtml" */ +{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_htm[5] = +/* ".htm" */ +{0x2e, 0x68, 0x74, 0x6d, }; +const char http_css[5] = +/* ".css" */ +{0x2e, 0x63, 0x73, 0x73, }; +const char http_png[5] = +/* ".png" */ +{0x2e, 0x70, 0x6e, 0x67, }; +const char http_gif[5] = +/* ".gif" */ +{0x2e, 0x67, 0x69, 0x66, }; +const char http_jpg[5] = +/* ".jpg" */ +{0x2e, 0x6a, 0x70, 0x67, }; +const char http_text[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; +const char http_txt[5] = +/* ".txt" */ +{0x2e, 0x74, 0x78, 0x74, }; diff --git a/bundles/uip/apps/webserver/http-strings.h b/bundles/uip/apps/webserver/http-strings.h new file mode 100644 index 00000000..f121dd73 --- /dev/null +++ b/bundles/uip/apps/webserver/http-strings.h @@ -0,0 +1,34 @@ +extern const char http_http[8]; +extern const char http_200[5]; +extern const char http_301[5]; +extern const char http_302[5]; +extern const char http_get[5]; +extern const char http_10[9]; +extern const char http_11[9]; +extern const char http_content_type[15]; +extern const char http_texthtml[10]; +extern const char http_location[11]; +extern const char http_host[7]; +extern const char http_crnl[3]; +extern const char http_index_html[12]; +extern const char http_404_html[10]; +extern const char http_referer[9]; +extern const char http_header_200[84]; +extern const char http_header_404[91]; +extern const char http_content_type_plain[29]; +extern const char http_content_type_html[28]; +extern const char http_content_type_css [27]; +extern const char http_content_type_text[28]; +extern const char http_content_type_png [28]; +extern const char http_content_type_gif [28]; +extern const char http_content_type_jpg [29]; +extern const char http_content_type_binary[43]; +extern const char http_html[6]; +extern const char http_shtml[7]; +extern const char http_htm[5]; +extern const char http_css[5]; +extern const char http_png[5]; +extern const char http_gif[5]; +extern const char http_jpg[5]; +extern const char http_text[5]; +extern const char http_txt[5]; diff --git a/bundles/uip/apps/webserver/httpd-cgi.c b/bundles/uip/apps/webserver/httpd-cgi.c new file mode 100644 index 00000000..62570359 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-cgi.c @@ -0,0 +1,203 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-2006, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $ + * + */ + +#include "uip.h" +#include "psock.h" +#include "httpd.h" +#include "httpd-cgi.h" +#include "httpd-fs.h" + +#include +#include + +HTTPD_CGI_CALL(file, "file-stats", file_stats); +HTTPD_CGI_CALL(tcp, "tcp-connections", tcp_stats); +HTTPD_CGI_CALL(net, "net-stats", net_stats); + +static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, NULL }; + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_cgifunction +httpd_cgi(char *name) +{ + const struct httpd_cgi_call **f; + + /* Find the matching name in the table, return the function. */ + for(f = calls; *f != NULL; ++f) { + if(strncmp((*f)->name, name, strlen((*f)->name)) == 0) { + return (*f)->function; + } + } + return nullfunction; +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_file_stats(void *arg) +{ + char *f = (char *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, "%5u", httpd_fs_count(f)); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, strchr(ptr, ' ') + 1); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static const char closed[] = /* "CLOSED",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0}; +static const char syn_rcvd[] = /* "SYN-RCVD",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, + 0x44, 0}; +static const char syn_sent[] = /* "SYN-SENT",*/ +{0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, + 0x54, 0}; +static const char established[] = /* "ESTABLISHED",*/ +{0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, + 0x45, 0x44, 0}; +static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x31, 0}; +static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ +{0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, + 0x54, 0x2d, 0x32, 0}; +static const char closing[] = /* "CLOSING",*/ +{0x43, 0x4c, 0x4f, 0x53, 0x49, + 0x4e, 0x47, 0}; +static const char time_wait[] = /* "TIME-WAIT,"*/ +{0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, + 0x49, 0x54, 0}; +static const char last_ack[] = /* "LAST-ACK"*/ +{0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, + 0x4b, 0}; + +static const char *states[] = { + closed, + syn_rcvd, + syn_sent, + established, + fin_wait_1, + fin_wait_2, + closing, + time_wait, + last_ack}; + + +static unsigned short +generate_tcp_stats(void *arg) +{ + struct uip_conn *conn; + struct httpd_state *s = (struct httpd_state *)arg; + + conn = &uip_conns[s->count]; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%d%u.%u.%u.%u:%u%s%u%u%c %c\r\n", + htons(conn->lport), + htons(conn->ripaddr[0]) >> 8, + htons(conn->ripaddr[0]) & 0xff, + htons(conn->ripaddr[1]) >> 8, + htons(conn->ripaddr[1]) & 0xff, + htons(conn->rport), + states[conn->tcpstateflags & UIP_TS_MASK], + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + + for(s->count = 0; s->count < UIP_CONNS; ++s->count) { + if((uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { + PSOCK_GENERATOR_SEND(&s->sout, generate_tcp_stats, s); + } + } + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_net_stats(void *arg) +{ + struct httpd_state *s = (struct httpd_state *)arg; + return snprintf((char *)uip_appdata, UIP_APPDATA_SIZE, + "%5u\n", ((uip_stats_t *)&uip_stat)[s->count]); +} + +static +PT_THREAD(net_stats(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + +#if UIP_STATISTICS + + for(s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); + ++s->count) { + PSOCK_GENERATOR_SEND(&s->sout, generate_net_stats, s); + } + +#endif /* UIP_STATISTICS */ + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/bundles/uip/apps/webserver/httpd-cgi.h b/bundles/uip/apps/webserver/httpd-cgi.h new file mode 100644 index 00000000..e6ba51e7 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-cgi.h @@ -0,0 +1,84 @@ +/** + * \addtogroup httpd + * @{ + */ + +/** + * \file + * Web server script interface header file + * \author + * Adam Dunkels + * + */ + + + +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd-cgi.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ + +#ifndef __HTTPD_CGI_H__ +#define __HTTPD_CGI_H__ + +#include "psock.h" +#include "httpd.h" + +typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *)); + +httpd_cgifunction httpd_cgi(char *name); + +struct httpd_cgi_call { + const char *name; + const httpd_cgifunction function; +}; + +/** + * \brief HTTPD CGI function declaration + * \param name The C variable name of the function + * \param str The string name of the function, used in the script file + * \param function A pointer to the function that implements it + * + * This macro is used for declaring a HTTPD CGI + * function. This function is then added to the list of + * HTTPD CGI functions with the httpd_cgi_add() function. + * + * \hideinitializer + */ +#define HTTPD_CGI_CALL(name, str, function) \ +static PT_THREAD(function(struct httpd_state *, char *)); \ +static const struct httpd_cgi_call name = {str, function} + +void httpd_cgi_init(void); +#endif /* __HTTPD_CGI_H__ */ + +/** @} */ diff --git a/bundles/uip/apps/webserver/httpd-fs.c b/bundles/uip/apps/webserver/httpd-fs.c new file mode 100644 index 00000000..21185e87 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ + +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +#include "httpd-fsdata.c" + +#if HTTPD_FS_STATISTICS +static u16_t count[HTTPD_FS_NUMFILES]; +#endif /* HTTPD_FS_STATISTICS */ + +/*-----------------------------------------------------------------------------------*/ +static u8_t +httpd_fs_strcmp(const char *str1, const char *str2) +{ + u8_t i; + i = 0; + loop: + + if(str2[i] == 0 || + str1[i] == '\r' || + str1[i] == '\n') { + return 0; + } + + if(str1[i] != str2[i]) { + return 1; + } + + + ++i; + goto loop; +} +/*-----------------------------------------------------------------------------------*/ +int +httpd_fs_open(const char *name, struct httpd_fs_file *file) +{ +#if HTTPD_FS_STATISTICS + u16_t i = 0; +#endif /* HTTPD_FS_STATISTICS */ + struct httpd_fsdata_file_noconst *f; + + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + file->data = f->data; + file->len = f->len; +#if HTTPD_FS_STATISTICS + ++count[i]; +#endif /* HTTPD_FS_STATISTICS */ + return 1; + } +#if HTTPD_FS_STATISTICS + ++i; +#endif /* HTTPD_FS_STATISTICS */ + + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +void +httpd_fs_init(void) +{ +#if HTTPD_FS_STATISTICS + u16_t i; + for(i = 0; i < HTTPD_FS_NUMFILES; i++) { + count[i] = 0; + } +#endif /* HTTPD_FS_STATISTICS */ +} +/*-----------------------------------------------------------------------------------*/ +#if HTTPD_FS_STATISTICS +u16_t httpd_fs_count +(char *name) +{ + struct httpd_fsdata_file_noconst *f; + u16_t i; + + i = 0; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + return count[i]; + } + ++i; + } + return 0; +} +#endif /* HTTPD_FS_STATISTICS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/bundles/uip/apps/webserver/httpd-fs.h b/bundles/uip/apps/webserver/httpd-fs.h new file mode 100644 index 00000000..d80ed3df --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ +#ifndef __HTTPD_FS_H__ +#define __HTTPD_FS_H__ + +#define HTTPD_FS_STATISTICS 1 + +struct httpd_fs_file { + char *data; + int len; +}; + +/* file must be allocated by caller and will be filled in + by the function. */ +int httpd_fs_open(const char *name, struct httpd_fs_file *file); + +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 +u16_t httpd_fs_count(char *name); +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ + +void httpd_fs_init(void); + +#endif /* __HTTPD_FS_H__ */ diff --git a/bundles/uip/apps/webserver/httpd-fs/404.html b/bundles/uip/apps/webserver/httpd-fs/404.html new file mode 100644 index 00000000..a17711d0 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/404.html @@ -0,0 +1,8 @@ + + +
+

404 - file not found

+

Go here instead.

+
+ + \ No newline at end of file diff --git a/bundles/uip/apps/webserver/httpd-fs/fade.png b/bundles/uip/apps/webserver/httpd-fs/fade.png new file mode 100644 index 0000000000000000000000000000000000000000..a9e69f75deda76937ede6e5d6d3bc94b8d43375e GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^EI`b~!2~2_W@bbJDb50q$YKTtZeb8+WSBKa0w~B{ z;_2(kevOSoMA~wF^nu4fA=whwh!W@g+}zZ>5(ej@)Wnk16ovB4k_?5Aj8p}8Pv3y| zDXMuug;t&}jv*Y^OM4837z6~4=$X%RNd5c2`3sj!Z^-PEXJ*+>C@xH&c%{T_Whmnh n&4?5GJ&rV%a4+Vsxy|yzf%X2v&wqfbP0l+XkKD_%S1 literal 0 HcmV?d00001 diff --git a/bundles/uip/apps/webserver/httpd-fs/files.shtml b/bundles/uip/apps/webserver/httpd-fs/files.shtml new file mode 100644 index 00000000..811e2303 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/files.shtml @@ -0,0 +1,35 @@ +%!: /header.html +

File statistics

+
+ + + + + + + + + + + + + + + +
/index.html%! file-stats /index.html +
/files.shtml%! file-stats /files.shtml +
/tcp.shtml%! file-stats /tcp.shtml +
/stats.shtml%! file-stats /stats.shtml +
/style.css%! file-stats /style.css +
/404.html%! file-stats /404.html +
/fade.png%! file-stats /fade.png +
+
+%!: /footer.html diff --git a/bundles/uip/apps/webserver/httpd-fs/footer.html b/bundles/uip/apps/webserver/httpd-fs/footer.html new file mode 100644 index 00000000..1fd5f4f2 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/footer.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/bundles/uip/apps/webserver/httpd-fs/header.html b/bundles/uip/apps/webserver/httpd-fs/header.html new file mode 100644 index 00000000..7b1a1fe7 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/header.html @@ -0,0 +1,18 @@ + + + + Welcome to the uIP web server! + + + + + + +
diff --git a/bundles/uip/apps/webserver/httpd-fs/index.html b/bundles/uip/apps/webserver/httpd-fs/index.html new file mode 100644 index 00000000..27cbc93f --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/index.html @@ -0,0 +1,29 @@ + + + + Welcome to the uIP web server! + + + + + + +
+

+ These web pages are served by a small web server running on top of + the uIP embedded TCP/IP + stack. +

+

+ Click on the links above for web server statistics. +

+ + + diff --git a/bundles/uip/apps/webserver/httpd-fs/processes.shtml b/bundles/uip/apps/webserver/httpd-fs/processes.shtml new file mode 100644 index 00000000..2f93e359 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/processes.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

System processes


+ +%! processes +%!: /footer.html \ No newline at end of file diff --git a/bundles/uip/apps/webserver/httpd-fs/stats.shtml b/bundles/uip/apps/webserver/httpd-fs/stats.shtml new file mode 100644 index 00000000..c63ed4af --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/stats.shtml @@ -0,0 +1,31 @@ +%!: /header.html +

Network statistics

+
+
IDNamePriorityPoll handlerEvent handlerProcstate
+
+IP           Packets received
+             Packets sent
+	     Packets dropped
+IP errors    IP version/header length
+             IP length, high byte
+             IP length, low byte
+             IP fragments
+             Header checksum
+             Wrong protocol
+ICMP	     Packets received
+             Packets sent
+             Packets dropped
+             Type errors
+TCP          Packets received
+             Packets sent
+             Packets dropped
+             Checksum errors
+             Data packets without ACKs
+             Resets
+             Retransmissions
+	     No connection avaliable
+	     Connection attempts to closed ports
+
%! net-stats
+
+ +%!: /footer.html diff --git a/bundles/uip/apps/webserver/httpd-fs/style.css b/bundles/uip/apps/webserver/httpd-fs/style.css new file mode 100644 index 00000000..ba6df7f1 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/style.css @@ -0,0 +1,92 @@ +h1 +{ + text-align: center; + font-size:14pt; + font-family:arial,helvetica; + font-weight:bold; + padding:10px; +} + +body +{ + + background-color: #fffeec; + color:black; + + font-size:8pt; + font-family:arial,helvetica; +} + +.menu +{ + margin: 4px; + width:60%; + + padding:2px; + + border: solid 1px; + background-color: #fffcd2; + text-align:left; + + font-size:9pt; + font-family:arial,helvetica; +} + +div.menubox +{ + width: 25%; + border: 0; + float: left; +text-align: center; +} + +.contentblock +{ + margin: 4px; + width:60%; + + padding:2px; + + border: 1px dotted; + background-color: white; + + font-size:8pt; + font-family:arial,helvetica; + +} + +p.intro +{ + margin-left:20px; + margin-right:20px; + + font-size:10pt; +/* font-weight:bold; */ + font-family:arial,helvetica; +} + +p.clink +{ + font-size:12pt; + font-family:courier,monospace; + text-align:center; +} + +p.clink9 +{ + font-size:9pt; + font-family:courier,monospace; + text-align:center; +} + + +p +{ + padding-left:10px; +} + +p.right +{ + text-align:right; +} + diff --git a/bundles/uip/apps/webserver/httpd-fs/tcp.shtml b/bundles/uip/apps/webserver/httpd-fs/tcp.shtml new file mode 100644 index 00000000..4c4bffe9 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fs/tcp.shtml @@ -0,0 +1,5 @@ +%!: /header.html +

Current connections


+ +%! tcp-connections +%!: /footer.html \ No newline at end of file diff --git a/bundles/uip/apps/webserver/httpd-fsdata.c b/bundles/uip/apps/webserver/httpd-fsdata.c new file mode 100644 index 00000000..491095ec --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fsdata.c @@ -0,0 +1,607 @@ +static const unsigned char data_processes_shtml[] = { + /* /processes.shtml */ + 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x68, + 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, + 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x49, 0x44, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, 0x65, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, 0x6f, 0x6c, 0x6c, + 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x50, + 0x72, 0x6f, 0x63, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, + 0x21, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, + 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, 0x6f, 0x6f, + 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0}; + +static const unsigned char data_404_html[] = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3d, 0x22, 0x77, 0x68, 0x69, 0x74, 0x65, 0x22, + 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x68, 0x31, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x3c, 0x2f, 0x68, 0x31, 0x3e, + 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, + 0x3e, 0x47, 0x6f, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x68, 0x65, 0x72, 0x65, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x65, + 0x61, 0x64, 0x2e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, +0}; + +static const unsigned char data_files_shtml[] = { + /* /files.shtml */ + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x31, + 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3e, + 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, 0x30, 0x22, 0x3e, + 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, + 0x3e, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, + 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, + 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, + 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, + 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31, + 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, + 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, + 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, + 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, + 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, + 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x31, 0x30, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, 0x21, 0x20, + 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x20, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x72, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, + 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, + 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x74, 0x63, 0x70, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, + 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, + 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, 0x63, + 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, + 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, + 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x25, + 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, + 0x73, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x2f, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, + 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3c, 0x2f, 0x74, + 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, + 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, + 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0xa, 0x3e, 0x20, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, + 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x34, + 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x2f, + 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, + 0x64, 0x3e, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, + 0x73, 0x72, 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, + 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2f, 0x34, 0x30, 0x34, + 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3e, 0x20, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, + 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x3e, 0x2f, 0x66, 0x61, + 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0xa, 0x3c, 0x74, 0x64, 0x3e, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0xa, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x73, 0x72, + 0x63, 0x3d, 0x22, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, + 0x6e, 0x67, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3d, 0x31, 0x30, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, + 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x20, 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, + 0x70, 0x6e, 0x67, 0xa, 0x3e, 0x20, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x3c, 0x2f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, + 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, + 0x6d, 0x6c, 0xa, 0}; + +static const unsigned char data_footer_html[] = { + /* /footer.html */ + 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x20, 0x20, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0xa, + 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0}; + +static const unsigned char data_header_html[] = { + /* /header.html */ + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77, + 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, + 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, + 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20, + 0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, + 0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22, + 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, + 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0xa, 0x20, + 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0}; + +static const unsigned char data_index_html[] = { + /* /index.html */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x20, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x33, 0x43, 0x2f, + 0x2f, 0x44, 0x54, 0x44, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x34, 0x2e, 0x30, 0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x2f, 0x45, + 0x4e, 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x54, 0x52, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x34, + 0x2f, 0x6c, 0x6f, 0x6f, 0x73, 0x65, 0x2e, 0x64, 0x74, 0x64, + 0x22, 0x3e, 0xa, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x49, 0x50, 0x20, 0x77, + 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x21, + 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x72, + 0x65, 0x6c, 0x3d, 0x22, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, + 0x68, 0x65, 0x65, 0x74, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, + 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0x22, 0x3e, 0x20, + 0x20, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x62, 0x67, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x22, 0x23, + 0x66, 0x66, 0x66, 0x65, 0x65, 0x63, 0x22, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x3d, 0x22, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x22, + 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, + 0x75, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, + 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x22, 0x3e, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x20, 0x70, 0x61, 0x67, 0x65, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, 0x65, 0x6e, 0x75, 0x62, + 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, + 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6d, + 0x65, 0x6e, 0x75, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x74, 0x63, 0x70, + 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x3e, 0x4e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0xa, 0x20, 0x20, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, + 0x20, 0x20, 0x3c, 0x62, 0x72, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x22, 0x3e, 0xa, 0x20, 0x20, 0x3c, 0x70, + 0x3e, 0xa, 0x20, 0x20, 0x54, 0x68, 0x65, 0x73, 0x65, 0x20, + 0x77, 0x65, 0x62, 0x20, 0x70, 0x61, 0x67, 0x65, 0x73, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x66, + 0xa, 0x20, 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, + 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, + 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x22, 0x3e, 0x75, 0x49, 0x50, + 0x20, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, + 0x54, 0x43, 0x50, 0x2f, 0x49, 0x50, 0xa, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x3c, 0x2f, 0x61, 0x3e, 0x2e, 0xa, + 0x20, 0x20, 0x3c, 0x2f, 0x70, 0x3e, 0xa, 0x20, 0x20, 0x3c, + 0x70, 0x3e, 0xa, 0x20, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, + 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x2e, 0xa, 0x20, 0x20, 0x3c, + 0x2f, 0x70, 0x3e, 0xa, 0xa, 0x20, 0x20, 0x3c, 0x2f, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0xa, 0x3c, 0x2f, 0x68, 0x74, 0x6d, + 0x6c, 0x3e, 0xa, 0}; + +static const unsigned char data_style_css[] = { + /* /style.css */ + 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x63, 0x73, 0x73, 0, + 0x68, 0x31, 0x20, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x34, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, + 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, + 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, + 0x78, 0x3b, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x62, 0x6f, 0x64, + 0x79, 0xa, 0x7b, 0xa, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x65, + 0x65, 0x63, 0x3b, 0xa, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0xa, 0xa, + 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, + 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0xa, 0x7d, 0xa, + 0xa, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0xa, 0x7b, 0xa, 0x20, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, + 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70, + 0x78, 0x3b, 0xa, 0x9, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x31, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, + 0x63, 0x64, 0x32, 0x3b, 0xa, 0x20, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, + 0x66, 0x74, 0x3b, 0xa, 0x20, 0x20, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39, + 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, + 0x69, 0x61, 0x6c, 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, + 0x69, 0x63, 0x61, 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, + 0x64, 0x69, 0x76, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x62, 0x6f, + 0x78, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x20, 0x32, 0x35, 0x25, 0x3b, 0xa, 0x20, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x30, 0x3b, + 0xa, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x20, + 0x6c, 0x65, 0x66, 0x74, 0x3b, 0xa, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, 0xa, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0xa, 0x7b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x70, 0x78, + 0x3b, 0xa, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x36, 0x30, 0x25, 0x3b, 0xa, 0xa, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x32, 0x70, 0x78, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x64, 0x6f, 0x74, 0x74, + 0x65, 0x64, 0x3b, 0xa, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, + 0xa, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x38, 0x70, 0x74, 0x3b, 0xa, 0x20, + 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, + 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x68, + 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x20, + 0x20, 0xa, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x69, 0x6e, + 0x74, 0x72, 0x6f, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x20, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0xa, 0xa, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x30, 0x70, 0x74, 0x3b, 0xa, 0x2f, 0x2a, 0x20, 0x20, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x20, 0x2a, 0x2f, + 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x61, 0x72, 0x69, 0x61, 0x6c, + 0x2c, 0x68, 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, + 0x3b, 0x20, 0x20, 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63, + 0x6c, 0x69, 0x6e, 0x6b, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, + 0x32, 0x70, 0x74, 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63, + 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e, + 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa, + 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, + 0xa, 0x7d, 0xa, 0xa, 0x70, 0x2e, 0x63, 0x6c, 0x69, 0x6e, + 0x6b, 0x39, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x39, 0x70, 0x74, + 0x3b, 0xa, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x63, 0x6f, 0x75, 0x72, + 0x69, 0x65, 0x72, 0x2c, 0x6d, 0x6f, 0x6e, 0x6f, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3b, 0x20, 0x20, 0xa, 0x20, 0x20, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0xa, 0x7d, 0xa, + 0xa, 0xa, 0x70, 0xa, 0x7b, 0xa, 0x20, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0xa, 0x7d, 0xa, 0xa, + 0x70, 0x2e, 0x72, 0x69, 0x67, 0x68, 0x74, 0xa, 0x7b, 0xa, + 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x20, + 0xa, 0x7d, 0xa, 0xa, 0}; + +static const unsigned char data_tcp_shtml[] = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0xa, + 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, + 0x68, 0x3e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, + 0x3e, 0x52, 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46, + 0x6c, 0x61, 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, + 0x2f, 0x74, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x20, 0x74, 0x63, + 0x70, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, +0}; + +static const unsigned char data_fade_png[] = { + /* /fade.png */ + 0x2f, 0x66, 0x61, 0x64, 0x65, 0x2e, 0x70, 0x6e, 0x67, 0, + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 00, 00, + 00, 0xd, 0x49, 0x48, 0x44, 0x52, 00, 00, 00, 0x4, + 00, 00, 00, 0xa, 0x8, 0x2, 00, 00, 00, 0x1c, + 0x99, 0x68, 0x59, 00, 00, 00, 0x9, 0x70, 0x48, 0x59, + 0x73, 00, 00, 0xb, 0x13, 00, 00, 0xb, 0x13, 0x1, + 00, 0x9a, 0x9c, 0x18, 00, 00, 00, 0x7, 0x74, 0x49, + 0x4d, 0x45, 0x7, 0xd6, 0x6, 0x8, 0x14, 0x1b, 0x39, 0xaf, + 0x5b, 0xc0, 0xe3, 00, 00, 00, 0x1d, 0x74, 0x45, 0x58, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 00, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, + 0xef, 0x64, 0x25, 0x6e, 00, 00, 00, 0x3a, 0x49, 0x44, + 0x41, 0x54, 0x8, 0xd7, 0x75, 0x8c, 0x31, 0x12, 00, 0x10, + 0x10, 0xc4, 0x2e, 0x37, 0x9e, 0x40, 0x65, 0xfd, 0xff, 0x83, + 0xf4, 0xa, 0x1c, 0x8d, 0x54, 0x9b, 0xc9, 0xcc, 0x9a, 0x3d, + 0x90, 0x73, 0x71, 0x67, 0x91, 0xd4, 0x74, 0x36, 0xa9, 0x55, + 0x1, 0xf8, 0x29, 0x58, 0xc8, 0xbf, 0x48, 0xc4, 0x81, 0x74, + 0xb, 0xa3, 0xf, 0x7c, 0xdb, 0x4, 0xe8, 0x40, 0x5, 0xdf, + 0xa1, 0xf3, 0xfc, 0x73, 00, 00, 00, 00, 0x49, 0x45, + 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0}; + +static const unsigned char data_stats_shtml[] = { + /* /stats.shtml */ + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0, + 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0xa, 0x3c, 0x68, 0x31, + 0x3e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0x3c, + 0x2f, 0x68, 0x31, 0x3e, 0xa, 0x3c, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0xa, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x33, 0x30, + 0x30, 0x22, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, + 0x22, 0x30, 0x22, 0x3e, 0xa, 0x3c, 0x74, 0x72, 0x3e, 0x3c, + 0x74, 0x64, 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0xa, 0x49, + 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, + 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, + 0x73, 0x65, 0x6e, 0x74, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x49, 0x50, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x20, 0x20, 0x20, 0x20, + 0x49, 0x50, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, + 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x68, + 0x69, 0x67, 0x68, 0x20, 0x62, 0x79, 0x74, 0x65, 0xa, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x49, 0x50, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x20, 0x62, 0x79, 0x74, + 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x49, 0x50, 0x20, 0x66, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x57, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0xa, 0x49, 0x43, 0x4d, 0x50, 0x9, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x54, 0x79, 0x70, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x73, 0xa, 0x54, 0x43, 0x50, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x64, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x74, 0x73, 0x20, 0x73, 0x65, 0x6e, 0x74, 0xa, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x20, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0xa, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, + 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, + 0x41, 0x43, 0x4b, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x73, 0x65, 0x74, 0x73, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x65, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x76, 0x61, 0x6c, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0xa, 0x9, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x20, + 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x20, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0xa, 0x3c, 0x2f, 0x70, 0x72, + 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, + 0x3e, 0x3c, 0x70, 0x72, 0x65, 0x3e, 0x25, 0x21, 0x20, 0x6e, + 0x65, 0x74, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0xa, 0x3c, + 0x2f, 0x70, 0x72, 0x65, 0x3e, 0x3c, 0x2f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0xa, 0x3c, 0x2f, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3e, 0xa, 0x25, 0x21, 0x3a, 0x20, 0x2f, 0x66, + 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2e, 0x68, 0x74, 0x6d, 0x6c, + 0xa, 0}; + +const struct httpd_fsdata_file file_processes_shtml[] = {{NULL, data_processes_shtml, data_processes_shtml + 17, sizeof(data_processes_shtml) - 17}}; + +const struct httpd_fsdata_file file_404_html[] = {{file_processes_shtml, data_404_html, data_404_html + 10, sizeof(data_404_html) - 10}}; + +const struct httpd_fsdata_file file_files_shtml[] = {{file_404_html, data_files_shtml, data_files_shtml + 13, sizeof(data_files_shtml) - 13}}; + +const struct httpd_fsdata_file file_footer_html[] = {{file_files_shtml, data_footer_html, data_footer_html + 13, sizeof(data_footer_html) - 13}}; + +const struct httpd_fsdata_file file_header_html[] = {{file_footer_html, data_header_html, data_header_html + 13, sizeof(data_header_html) - 13}}; + +const struct httpd_fsdata_file file_index_html[] = {{file_header_html, data_index_html, data_index_html + 12, sizeof(data_index_html) - 12}}; + +const struct httpd_fsdata_file file_style_css[] = {{file_index_html, data_style_css, data_style_css + 11, sizeof(data_style_css) - 11}}; + +const struct httpd_fsdata_file file_tcp_shtml[] = {{file_style_css, data_tcp_shtml, data_tcp_shtml + 11, sizeof(data_tcp_shtml) - 11}}; + +const struct httpd_fsdata_file file_fade_png[] = {{file_tcp_shtml, data_fade_png, data_fade_png + 10, sizeof(data_fade_png) - 10}}; + +const struct httpd_fsdata_file file_stats_shtml[] = {{file_fade_png, data_stats_shtml, data_stats_shtml + 13, sizeof(data_stats_shtml) - 13}}; + +#define HTTPD_FS_ROOT file_stats_shtml + +#define HTTPD_FS_NUMFILES 10 diff --git a/bundles/uip/apps/webserver/httpd-fsdata.h b/bundles/uip/apps/webserver/httpd-fsdata.h new file mode 100644 index 00000000..0ad2d6e7 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd-fsdata.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $ + */ +#ifndef __HTTPD_FSDATA_H__ +#define __HTTPD_FSDATA_H__ + +#include "uip.h" + +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; + const char *name; + const char *data; + const int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +struct httpd_fsdata_file_noconst { + struct httpd_fsdata_file *next; + char *name; + char *data; + int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +#endif /* __HTTPD_FSDATA_H__ */ diff --git a/bundles/uip/apps/webserver/httpd.c b/bundles/uip/apps/webserver/httpd.c new file mode 100644 index 00000000..937e1382 --- /dev/null +++ b/bundles/uip/apps/webserver/httpd.c @@ -0,0 +1,338 @@ +/** + * \addtogroup apps + * @{ + */ + +/** + * \defgroup httpd Web server + * @{ + * The uIP web server is a very simplistic implementation of an HTTP + * server. It can serve web pages and files from a read-only ROM + * filesystem, and provides a very small scripting language. + + */ + +/** + * \file + * Web server + * \author + * Adam Dunkels + */ + + +/* + * Copyright (c) 2004, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd.c,v 1.2 2006/06/11 21:46:38 adam Exp $ + */ + +#include "uip.h" +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-cgi.h" +#include "http-strings.h" + +#include + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_bang 0x21 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_colon 0x3a + + +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_part_of_file(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + memcpy(uip_appdata, s->file.data, s->len); + + return s->len; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_part_of_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND(&s->sout, s->file.data, s->len); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static void +next_scriptstate(struct httpd_state *s) +{ + char *p; + p = strchr(s->scriptptr, ISO_nl) + 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_script(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->scriptpt); + + + while(s->file.len > 0) { + + /* Check if we should start executing a script. */ + if(*s->file.data == ISO_percent && + *(s->file.data + 1) == ISO_bang) { + s->scriptptr = s->file.data + 3; + s->scriptlen = s->file.len - 3; + if(*(s->scriptptr - 1) == ISO_colon) { + httpd_fs_open(s->scriptptr + 1, &s->file); + PT_WAIT_THREAD(&s->scriptpt, send_file(s)); + } else { + PT_WAIT_THREAD(&s->scriptpt, + httpd_cgi(s->scriptptr)(s, s->scriptptr)); + } + next_scriptstate(s); + + /* The script is over, so we reset the pointers and continue + sending the rest of the file. */ + s->file.data = s->scriptptr; + s->file.len = s->scriptlen; + } else { + /* See if we find the start of script marker in the block of HTML + to be sent. */ + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + if(*s->file.data == ISO_percent) { + ptr = strchr(s->file.data + 1, ISO_percent); + } else { + ptr = strchr(s->file.data, ISO_percent); + } + if(ptr != NULL && + ptr != s->file.data) { + s->len = (int)(ptr - s->file.data); + if(s->len >= uip_mss()) { + s->len = uip_mss(); + } + } + PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); + s->file.data += s->len; + s->file.len -= s->len; + + } + } + + PT_END(&s->scriptpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + + PSOCK_BEGIN(&s->sout); + + PSOCK_SEND_STR(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + PSOCK_SEND_STR(&s->sout, http_content_type_binary); + } else if(strncmp(http_html, ptr, 5) == 0 || + strncmp(http_shtml, ptr, 6) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_html); + } else if(strncmp(http_css, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_css); + } else if(strncmp(http_png, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_png); + } else if(strncmp(http_gif, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_gif); + } else if(strncmp(http_jpg, ptr, 4) == 0) { + PSOCK_SEND_STR(&s->sout, http_content_type_jpg); + } else { + PSOCK_SEND_STR(&s->sout, http_content_type_plain); + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->outputpt); + + if(!httpd_fs_open(s->filename, &s->file)) { + httpd_fs_open(http_404_html, &s->file); + strcpy(s->filename, http_404_html); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, + http_header_200)); + ptr = strchr(s->filename, ISO_period); + if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { + PT_INIT(&s->scriptpt); + PT_WAIT_THREAD(&s->outputpt, handle_script(s)); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_file(s)); + } + } + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); + } + + /* httpd_log_file(uip_conn->ripaddr, s->filename);*/ + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + /* httpd_log(&s->inputbuf[9]);*/ + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void) +{ + struct httpd_state *s = (struct httpd_state *)&(uip_conn->appstate); + + if(uip_closed() || uip_aborted() || uip_timedout()) { + } else if(uip_connected()) { + PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->state = STATE_WAITING; + /* timer_set(&s->timer, CLOCK_SECOND * 100);*/ + s->timer = 0; + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + ++s->timer; + if(s->timer >= 20) { + uip_abort(); + } + } else { + s->timer = 0; + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the web server + * + * This function initializes the web server and should be + * called at system boot-up. + */ +void +httpd_init(void) +{ + uip_listen(HTONS(80)); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/bundles/uip/apps/webserver/httpd.h b/bundles/uip/apps/webserver/httpd.h new file mode 100644 index 00000000..270d49de --- /dev/null +++ b/bundles/uip/apps/webserver/httpd.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2001-2005, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: httpd.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ + +#ifndef __HTTPD_H__ +#define __HTTPD_H__ + +#include "psock.h" +#include "httpd-fs.h" + +struct httpd_state { + unsigned char timer; + struct psock sin, sout; + struct pt outputpt, scriptpt; + char inputbuf[50]; + char filename[20]; + char state; + struct httpd_fs_file file; + int len; + char *scriptptr; + int scriptlen; + + unsigned short count; +}; + +void httpd_init(void); +void httpd_appcall(void); + +void httpd_log(char *msg); +void httpd_log_file(u16_t *requester, char *file); + +#endif /* __HTTPD_H__ */ diff --git a/bundles/uip/apps/webserver/makefsdata b/bundles/uip/apps/webserver/makefsdata new file mode 100644 index 00000000..b2109abd --- /dev/null +++ b/bundles/uip/apps/webserver/makefsdata @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +open(OUTPUT, "> httpd-fsdata.c"); + +chdir("httpd-fs"); + +opendir(DIR, "."); +@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +closedir(DIR); + +foreach $file (@files) { + + if(-d $file && $file !~ /^\./) { + print "Processing directory $file\n"; + opendir(DIR, $file); + @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); + closedir(DIR); + printf "Adding files @newfiles\n"; + @files = (@files, map { $_ = "$file/$_" } @newfiles); + next; + } +} + +foreach $file (@files) { + if(-f $file) { + + print "Adding file $file\n"; + + open(FILE, $file) || die "Could not open file $file\n"; + + $file =~ s-^-/-; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + # for AVR, add PROGMEM here + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "0};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@pfiles, $file); + } +} + +for($i = 0; $i < @fvars; $i++) { + $file = $pfiles[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n"); diff --git a/bundles/uip/apps/webserver/makestrings b/bundles/uip/apps/webserver/makestrings new file mode 100644 index 00000000..20f0e242 --- /dev/null +++ b/bundles/uip/apps/webserver/makestrings @@ -0,0 +1,40 @@ +#!/usr/bin/perl + + +sub stringify { + my $name = shift(@_); + open(OUTPUTC, "> $name.c"); + open(OUTPUTH, "> $name.h"); + + open(FILE, "$name"); + + while() { + if(/(.+) "(.+)"/) { + $var = $1; + $data = $2; + + $datan = $data; + $datan =~ s/\\r/\r/g; + $datan =~ s/\\n/\n/g; + $datan =~ s/\\01/\01/g; + $datan =~ s/\\0/\0/g; + + printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1); + printf(OUTPUTC "/* \"$data\" */\n"); + printf(OUTPUTC "{"); + for($j = 0; $j < length($datan); $j++) { + printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1))); + } + printf(OUTPUTC "};\n"); + + printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1); + + } + } + close(OUTPUTC); + close(OUTPUTH); +} +stringify("http-strings"); + +exit 0; + diff --git a/bundles/uip/apps/webserver/webserver.h b/bundles/uip/apps/webserver/webserver.h new file mode 100644 index 00000000..48753e69 --- /dev/null +++ b/bundles/uip/apps/webserver/webserver.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $ + * + */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ + +#include "httpd.h" + +typedef struct httpd_state uip_tcp_appstate_t; +/* UIP_APPCALL: the name of the application function. This function + must return void and take no arguments (i.e., C type "void + appfunc(void)"). */ +#ifndef UIP_APPCALL +#define UIP_APPCALL httpd_appcall +#endif + + +#endif /* __WEBSERVER_H__ */ diff --git a/bundles/uip/lib/memb.c b/bundles/uip/lib/memb.c new file mode 100644 index 00000000..777b52f7 --- /dev/null +++ b/bundles/uip/lib/memb.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $ + */ + +/** + * \addtogroup memb + * @{ + */ + + /** + * \file + * Memory block allocation routines. + * \author Adam Dunkels + */ +#include + +#include "memb.h" + +/*---------------------------------------------------------------------------*/ +void +memb_init(struct memb_blocks *m) +{ + memset(m->count, 0, m->num); + memset(m->mem, 0, m->size * m->num); +} +/*---------------------------------------------------------------------------*/ +void * +memb_alloc(struct memb_blocks *m) +{ + int i; + + for(i = 0; i < m->num; ++i) { + if(m->count[i] == 0) { + /* If this block was unused, we increase the reference count to + indicate that it now is used and return a pointer to the + memory block. */ + ++(m->count[i]); + return (void *)((char *)m->mem + (i * m->size)); + } + } + + /* No free block was found, so we return NULL to indicate failure to + allocate block. */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +char +memb_free(struct memb_blocks *m, void *ptr) +{ + int i; + char *ptr2; + + /* Walk through the list of blocks and try to find the block to + which the pointer "ptr" points to. */ + ptr2 = (char *)m->mem; + for(i = 0; i < m->num; ++i) { + + if(ptr2 == (char *)ptr) { + /* We've found to block to which "ptr" points so we decrease the + reference count and return the new value of it. */ + if(m->count[i] > 0) { + /* Make sure that we don't deallocate free memory. */ + --(m->count[i]); + } + return m->count[i]; + } + ptr2 += m->size; + } + return -1; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/bundles/uip/lib/memb.h b/bundles/uip/lib/memb.h new file mode 100644 index 00000000..b725ebe1 --- /dev/null +++ b/bundles/uip/lib/memb.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $ + */ + +/** + * \defgroup memb Memory block management functions + * + * The memory block allocation routines provide a simple yet powerful + * set of functions for managing a set of memory blocks of fixed + * size. A set of memory blocks is statically declared with the + * MEMB() macro. Memory blocks are allocated from the declared + * memory by the memb_alloc() function, and are deallocated with the + * memb_free() function. + * + * \note Because of namespace clashes only one MEMB() can be + * declared per C module, and the name scope of a MEMB() memory + * block is local to each C module. + * + * The following example shows how to declare and use a memory block + * called "cmem" which has 8 chunks of memory with each memory chunk + * being 20 bytes large. + * + * @{ + */ + + +/** + * \file + * Memory block allocation routines. + * \author + * Adam Dunkels + * + */ + +#ifndef __MEMB_H__ +#define __MEMB_H__ + +/* + * Here we define a C preprocessing macro for concatenating to + * strings. We need use two macros in order to allow concatenation of + * two #defined macros. + */ +#define MEMB_CONCAT2(s1, s2) s1##s2 +#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2) + +/** + * Declare a memory block. + * + * This macro is used to staticall declare a block of memory that can + * be used by the block allocation functions. The macro statically + * declares a C array with a size that matches the specified number of + * blocks and their individual sizes. + * + * Example: + \code +MEMB(connections, sizeof(struct connection), 16); + \endcode + * + * \param name The name of the memory block (later used with + * memb_init(), memb_alloc() and memb_free()). + * + * \param size The size of each memory chunk, in bytes. + * + * \param num The total number of memory chunks in the block. + * + */ +#define MEMB(name, structure, num) \ + static char MEMB_CONCAT(name,_memb_count)[num]; \ + static structure MEMB_CONCAT(name,_memb_mem)[num]; \ + static struct memb_blocks name = {sizeof(structure), num, \ + MEMB_CONCAT(name,_memb_count), \ + (void *)MEMB_CONCAT(name,_memb_mem)} + +struct memb_blocks { + unsigned short size; + unsigned short num; + char *count; + void *mem; +}; + +/** + * Initialize a memory block that was declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void memb_init(struct memb_blocks *m); + +/** + * Allocate a memory block from a block of memory declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void *memb_alloc(struct memb_blocks *m); + +/** + * Deallocate a memory block from a memory block previously declared + * with MEMB(). + * + * \param m m A memory block previosly declared with MEMB(). + * + * \param ptr A pointer to the memory block that is to be deallocated. + * + * \return The new reference count for the memory block (should be 0 + * if successfully deallocated) or -1 if the pointer "ptr" did not + * point to a legal memory block. + */ +char memb_free(struct memb_blocks *m, void *ptr); + +/** @} */ + +#endif /* __MEMB_H__ */ diff --git a/bundles/uip/uip-1.0-changelog.txt b/bundles/uip/uip-1.0-changelog.txt new file mode 100644 index 00000000..1e6c61cf --- /dev/null +++ b/bundles/uip/uip-1.0-changelog.txt @@ -0,0 +1,98 @@ +* A new API: protosockets that are similar to BSD sockets but does not + require any underlying multithreading system. + +* Very rudimentary IPv6 support + +* New application: DHCP client. Web server rewritten with protosockets. + +* Removed uIP zero-copy functionality in order to simplify uIP device + driver coding: outbound packets are now *always* stored in full in + the uip_buf buffer. + +* Checksum computation is now part of uip.c, but it still is possible + to implement them in assembly code by specifying a configuration + option. Checksum code now runs on architectures with 2-byte alignment. + +* Added TCP persistent timer. + +* Made all IP address representations use the new uip_ipaddr_ip + datatype for clarity. + +* Updated window behavior so that sending to a host with a small open + window works better now. + +* UDP API change: uip_udp_new() now takes port numbers in network byte + order like TCP functions. + +* Allow reception of packets when no IP address is configured to make + DHCP work. + +* Moved Ethernet address into main uIP module from ARP module. + +* Made constants explicit #defines and moved them out of the code + (header sizes, TCP options, TCP header length field). + +* If uip_len is less than that reported by the IP header, the packet + is discarded. If uip_len is greater than the length reported by the + IP header, uip_len is adjusted. + +* Moved header size definitions into header file. + +* Added uIP call for polling an application without triggering any + timer events. Removed redundant assignments of uip_len and uip_slen. + +* Removed compiler warning about icmp_input label being defined when + UIP_PINGADDRCONF was not used. + +* Added UIP_APPDATA_SIZE macro that holds the available buffer size + for user data. + +* Added uip_udp_bind() call. + +* Moved checksum code into main uIP module. + +* Switched the TCP, UDP and IP header structures to be structs rather + than typedefs. + +* Prefixed TCP state names with UIP_ to avoid name space + contamination. + +* Changed declarations of uip_appdatap and friends to void * to avoid + explicit typecasts. + +* Bugfixes + + o TCP: Fixed bug with high byte of peer window size. + + o TCP: Fixed bug that in some cases prevented concurrent reception and + transmission of TCP data. + + o TCP: uip_connect() didn't correctly calculate age of TIME_WAIT + connections. + + o TCP: Array index for uip_conns[] array was out of bounds in + comparison. Comparison changed to make index within bounds. + + o TCP: if the remote host crashes and tries to reestablish an old + connection, uIP should respond with an ACK with the correct + sequence and acknowledgment numbers, to which the remote host + should respond with an ACK. uIP did not respond with the correct + ACK. + + o TCP: Fixed check for SYNACK segment: now checks only relevant TCP + control flags and discards flags reserved for future expansion. + + o TCP: Fixed bug where uIP did not inform application that a connection + had been aborted during an active open. + + o TCP: FIN segment was accepted even though application had stopped + incoming data with uip_stop(). + + o TCP: A FINACK segment would not always correctly acknowledge data. + + o UDP: checksums are now calculated after all fields have been + filled in. + + o UDP: network byte order on lastport in uip_udp_new(). + + o IP: memset() bugs in IP fragment reassembly code fixed. diff --git a/bundles/uip/uip/Makefile.include b/bundles/uip/uip/Makefile.include new file mode 100644 index 00000000..b4d8a94c --- /dev/null +++ b/bundles/uip/uip/Makefile.include @@ -0,0 +1,47 @@ + + +ifdef APPS + APPDIRS = $(foreach APP, $(APPS), ../apps/$(APP)) + -include $(foreach APP, $(APPS), ../apps/$(APP)/Makefile.$(APP)) + CFLAGS += $(addprefix -I../apps/,$(APPS)) +endif + +ifndef CCDEP + CCDEP = $(CC) +endif +ifndef CCDEPCFLAGS + CCDEPCFLAGS = $(CFLAGS) +endif +ifndef OBJECTDIR + OBJECTDIR = obj +endif + +ifeq (${wildcard $(OBJECTDIR)},) + DUMMY := ${shell mkdir $(OBJECTDIR)} +endif + + +vpath %.c . ../uip ../lib $(APPDIRS) + +$(OBJECTDIR)/%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJECTDIR)/%.d: %.c + @set -e; rm -f $@; \ + $(CCDEP) -MM $(CCDEPCFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +UIP_SOURCES=uip.c uip_arp.c uiplib.c psock.c timer.c uip-neighbor.c + + +ifneq ($(MAKECMDGOALS),clean) +-include $(addprefix $(OBJECTDIR)/,$(UIP_SOURCES:.c=.d) \ + $(APP_SOURCES:.c=.d)) +endif + +uip.a: ${addprefix $(OBJECTDIR)/, $(UIP_SOURCES:.c=.o)} + $(AR) rcf $@ $^ + +apps.a: ${addprefix $(OBJECTDIR)/, $(APP_SOURCES:.c=.o)} + $(AR) rcf $@ $^ diff --git a/bundles/uip/uip/clock.h b/bundles/uip/uip/clock.h new file mode 100644 index 00000000..f34d78fd --- /dev/null +++ b/bundles/uip/uip/clock.h @@ -0,0 +1,88 @@ +/** + * \defgroup clock Clock interface + * + * The clock interface is the interface between the \ref timer "timer library" + * and the platform specific clock functionality. The clock + * interface must be implemented for each platform that uses the \ref + * timer "timer library". + * + * The clock interface does only one this: it measures time. The clock + * interface provides a macro, CLOCK_SECOND, which corresponds to one + * second of system time. + * + * \sa \ref timer "Timer library" + * + * @{ + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "clock-arch.h" + +/** + * Initialize the clock library. + * + * This function initializes the clock library and should be called + * from the main() function of the system. + * + */ +void clock_init(void); + +/** + * Get the current clock time. + * + * This function returns the current system clock time. + * + * \return The current clock time, measured in system ticks. + */ +clock_time_t clock_time(void); + +/** + * A second, measured in system clock time. + * + * \hideinitializer + */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif + +#endif /* __CLOCK_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/lc-addrlabels.h b/bundles/uip/uip/lc-addrlabels.h new file mode 100644 index 00000000..fe1387e5 --- /dev/null +++ b/bundles/uip/uip/lc-addrlabels.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on the "Labels as + * values" feature of gcc + * \author + * Adam Dunkels + * + * This implementation of local continuations is based on a special + * feature of the GCC C compiler called "labels as values". This + * feature allows assigning pointers with the address of the code + * corresponding to a particular C label. + * + * For more information, see the GCC documentation: + * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html + * + * Thanks to dividuum for finding the nice local scope label + * implementation. + */ + +#ifndef __LC_ADDRLABELS_H__ +#define __LC_ADDRLABELS_H__ + +/** \hideinitializer */ +typedef void * lc_t; + +#define LC_INIT(s) s = NULL + + +#define LC_RESUME(s) \ + do { \ + if(s != NULL) { \ + goto *s; \ + } \ + } while(0) + +#define LC_SET(s) \ + do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0) + +#define LC_END(s) + +#endif /* __LC_ADDRLABELS_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/lc-switch.h b/bundles/uip/uip/lc-switch.h new file mode 100644 index 00000000..f32885fd --- /dev/null +++ b/bundles/uip/uip/lc-switch.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on switch() statment + * \author Adam Dunkels + * + * This implementation of local continuations uses the C switch() + * statement to resume execution of a function somewhere inside the + * function's body. The implementation is based on the fact that + * switch() statements are able to jump directly into the bodies of + * control structures such as if() or while() statmenets. + * + * This implementation borrows heavily from Simon Tatham's coroutines + * implementation in C: + * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html + */ + +#ifndef __LC_SWITCH_H__ +#define __LC_SWTICH_H__ + +/* WARNING! lc implementation using switch() does not work if an + LC_SET() is done within another switch() statement! */ + +/** \hideinitializer */ +typedef unsigned short lc_t; + +#define LC_INIT(s) s = 0; + +#define LC_RESUME(s) switch(s) { case 0: + +#define LC_SET(s) s = __LINE__; case __LINE__: + +#define LC_END(s) } + +#endif /* __LC_SWITCH_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/lc.h b/bundles/uip/uip/lc.h new file mode 100644 index 00000000..a9e9d469 --- /dev/null +++ b/bundles/uip/uip/lc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup lc Local continuations + * @{ + * + * Local continuations form the basis for implementing protothreads. A + * local continuation can be set in a specific function to + * capture the state of the function. After a local continuation has + * been set can be resumed in order to restore the state of the + * function at the point where the local continuation was set. + * + * + */ + +/** + * \file lc.h + * Local continuations + * \author + * Adam Dunkels + * + */ + +#ifdef DOXYGEN +/** + * Initialize a local continuation. + * + * This operation initializes the local continuation, thereby + * unsetting any previously set continuation state. + * + * \hideinitializer + */ +#define LC_INIT(lc) + +/** + * Set a local continuation. + * + * The set operation saves the state of the function at the point + * where the operation is executed. As far as the set operation is + * concerned, the state of the function does not include the + * call-stack or local (automatic) variables, but only the program + * counter and such CPU registers that needs to be saved. + * + * \hideinitializer + */ +#define LC_SET(lc) + +/** + * Resume a local continuation. + * + * The resume operation resumes a previously set local continuation, thus + * restoring the state in which the function was when the local + * continuation was set. If the local continuation has not been + * previously set, the resume operation does nothing. + * + * \hideinitializer + */ +#define LC_RESUME(lc) + +/** + * Mark the end of local continuation usage. + * + * The end operation signifies that local continuations should not be + * used any more in the function. This operation is not needed for + * most implementations of local continuation, but is required by a + * few implementations. + * + * \hideinitializer + */ +#define LC_END(lc) + +/** + * \var typedef lc_t; + * + * The local continuation type. + * + * \hideinitializer + */ +#endif /* DOXYGEN */ + +#ifndef __LC_H__ +#define __LC_H__ + +#ifdef LC_CONF_INCLUDE +#include LC_CONF_INCLUDE +#else +#include "lc-switch.h" +#endif /* LC_CONF_INCLUDE */ + +#endif /* __LC_H__ */ + +/** @} */ +/** @} */ diff --git a/bundles/uip/uip/psock.c b/bundles/uip/uip/psock.c new file mode 100644 index 00000000..f284cb90 --- /dev/null +++ b/bundles/uip/uip/psock.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include +#include + +#include "uipopt.h" +#include "psock.h" +#include "uip.h" + +#define STATE_NONE 0 +#define STATE_ACKED 1 +#define STATE_READ 2 +#define STATE_BLOCKED_NEWDATA 3 +#define STATE_BLOCKED_CLOSE 4 +#define STATE_BLOCKED_SEND 5 +#define STATE_DATA_SENT 6 + +/* + * Return value of the buffering functions that indicates that a + * buffer was not filled by incoming data. + * + */ +#define BUF_NOT_FULL 0 +#define BUF_NOT_FOUND 0 + +/* + * Return value of the buffering functions that indicates that a + * buffer was completely filled by incoming data. + * + */ +#define BUF_FULL 1 + +/* + * Return value of the buffering functions that indicates that an + * end-marker byte was found. + * + */ +#define BUF_FOUND 2 + +/*---------------------------------------------------------------------------*/ +static void +buf_setup(struct psock_buf *buf, + u8_t *bufptr, u16_t bufsize) +{ + buf->ptr = bufptr; + buf->left = bufsize; +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufdata(struct psock_buf *buf, u16_t len, + u8_t **dataptr, u16_t *datalen) +{ + if(*datalen < buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left -= *datalen; + *dataptr += *datalen; + *datalen = 0; + return BUF_NOT_FULL; + } else if(*datalen == buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left = 0; + *dataptr += *datalen; + *datalen = 0; + return BUF_FULL; + } else { + memcpy(buf->ptr, *dataptr, buf->left); + buf->ptr += buf->left; + *datalen -= buf->left; + *dataptr += buf->left; + buf->left = 0; + return BUF_FULL; + } +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufto(register struct psock_buf *buf, u8_t endmarker, + register u8_t **dataptr, register u16_t *datalen) +{ + u8_t c; + while(buf->left > 0 && *datalen > 0) { + c = *buf->ptr = **dataptr; + ++*dataptr; + ++buf->ptr; + --*datalen; + --buf->left; + + if(c == endmarker) { + return BUF_FOUND; + } + } + + if(*datalen == 0) { + return BUF_NOT_FOUND; + } + + while(*datalen > 0) { + c = **dataptr; + --*datalen; + ++*dataptr; + + if(c == endmarker) { + return BUF_FOUND | BUF_FULL; + } + } + + return BUF_FULL; +} +/*---------------------------------------------------------------------------*/ +static char +send_data(register struct psock *s) +{ + if(s->state != STATE_DATA_SENT || uip_rexmit()) { + if(s->sendlen > uip_mss()) { + uip_send(s->sendptr, uip_mss()); + } else { + uip_send(s->sendptr, s->sendlen); + } + s->state = STATE_DATA_SENT; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static char +data_acked(register struct psock *s) +{ + if(s->state == STATE_DATA_SENT && uip_acked()) { + if(s->sendlen > uip_mss()) { + s->sendlen -= uip_mss(); + s->sendptr += uip_mss(); + } else { + s->sendptr += s->sendlen; + s->sendlen = 0; + } + s->state = STATE_ACKED; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_send(register struct psock *s, const char *buf, + unsigned int len)) +{ + PT_BEGIN(&s->psockpt); + + /* If there is no data to send, we exit immediately. */ + if(len == 0) { + PT_EXIT(&s->psockpt); + } + + /* Save the length of and a pointer to the data that is to be + sent. */ + s->sendptr = buf; + s->sendlen = len; + + s->state = STATE_NONE; + + /* We loop here until all data is sent. The s->sendlen variable is + updated by the data_sent() function. */ + while(s->sendlen > 0) { + + /* + * The condition for this PT_WAIT_UNTIL is a little tricky: the + * protothread will wait here until all data has been acknowledged + * (data_acked() returns true) and until all data has been sent + * (send_data() returns true). The two functions data_acked() and + * send_data() must be called in succession to ensure that all + * data is sent. Therefore the & operator is used instead of the + * && operator, which would cause only the data_acked() function + * to be called when it returns false. + */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_generator_send(register struct psock *s, + unsigned short (*generate)(void *), void *arg)) +{ + PT_BEGIN(&s->psockpt); + + /* Ensure that there is a generator function to call. */ + if(generate == NULL) { + PT_EXIT(&s->psockpt); + } + + /* Call the generator function to generate the data in the + uip_appdata buffer. */ + s->sendlen = generate(arg); + s->sendptr = uip_appdata; + + s->state = STATE_NONE; + do { + /* Call the generator function again if we are called to perform a + retransmission. */ + if(uip_rexmit()) { + generate(arg); + } + /* Wait until all data is sent and acknowledged. */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } while(s->sendlen > 0); + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +u16_t +psock_datalen(struct psock *psock) +{ + return psock->bufsize - psock->buf.left; +} +/*---------------------------------------------------------------------------*/ +char +psock_newdata(struct psock *s) +{ + if(s->readlen > 0) { + /* There is data in the uip_appdata buffer that has not yet been + read with the PSOCK_READ functions. */ + return 1; + } else if(s->state == STATE_READ) { + /* All data in uip_appdata buffer already consumed. */ + s->state = STATE_BLOCKED_NEWDATA; + return 0; + } else if(uip_newdata()) { + /* There is new data that has not been consumed. */ + return 1; + } else { + /* There is no new data. */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readto(register struct psock *psock, unsigned char c)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while((buf_bufto(&psock->buf, c, + &psock->readptr, + &psock->readlen) & BUF_FOUND) == 0); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readbuf(register struct psock *psock)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + printf("Waited for newdata\n"); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while(buf_bufdata(&psock->buf, psock->bufsize, + &psock->readptr, + &psock->readlen) != BUF_FULL); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +void +psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) +{ + psock->state = STATE_NONE; + psock->readlen = 0; + psock->bufptr = buffer; + psock->bufsize = buffersize; + buf_setup(&psock->buf, buffer, buffersize); + PT_INIT(&psock->pt); + PT_INIT(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/uip/psock.h b/bundles/uip/uip/psock.h new file mode 100644 index 00000000..3dffa735 --- /dev/null +++ b/bundles/uip/uip/psock.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \defgroup psock Protosockets library + * @{ + * + * The protosocket library provides an interface to the uIP stack that is + * similar to the traditional BSD socket interface. Unlike programs + * written for the ordinary uIP event-driven interface, programs + * written with the protosocket library are executed in a sequential + * fashion and does not have to be implemented as explicit state + * machines. + * + * Protosockets only work with TCP connections. + * + * The protosocket library uses \ref pt protothreads to provide + * sequential control flow. This makes the protosockets lightweight in + * terms of memory, but also means that protosockets inherits the + * functional limitations of protothreads. Each protosocket lives only + * within a single function. Automatic variables (stack variables) are + * not retained across a protosocket library function call. + * + * \note Because the protosocket library uses protothreads, local + * variables will not always be saved across a call to a protosocket + * library function. It is therefore advised that local variables are + * used with extreme care. + * + * The protosocket library provides functions for sending data without + * having to deal with retransmissions and acknowledgements, as well + * as functions for reading data without having to deal with data + * being split across more than one TCP segment. + * + * Because each protosocket runs as a protothread, the protosocket has to be + * started with a call to PSOCK_BEGIN() at the start of the function + * in which the protosocket is used. Similarly, the protosocket protothread can + * be terminated by a call to PSOCK_EXIT(). + * + */ + +/** + * \file + * Protosocket library header file + * \author + * Adam Dunkels + * + */ + +#ifndef __PSOCK_H__ +#define __PSOCK_H__ + +#include "uipopt.h" +#include "pt.h" + + /* + * The structure that holds the state of a buffer. + * + * This structure holds the state of a uIP buffer. The structure has + * no user-visible elements, but is used through the functions + * provided by the library. + * + */ +struct psock_buf { + u8_t *ptr; + unsigned short left; +}; + +/** + * The representation of a protosocket. + * + * The protosocket structrure is an opaque structure with no user-visible + * elements. + */ +struct psock { + struct pt pt, psockpt; /* Protothreads - one that's using the psock + functions, and one that runs inside the + psock functions. */ + const u8_t *sendptr; /* Pointer to the next data to be sent. */ + u8_t *readptr; /* Pointer to the next data to be read. */ + + char *bufptr; /* Pointer to the buffer used for buffering + incoming data. */ + + u16_t sendlen; /* The number of bytes left to be sent. */ + u16_t readlen; /* The number of bytes left to be read. */ + + struct psock_buf buf; /* The structure holding the state of the + input buffer. */ + unsigned int bufsize; /* The size of the input buffer. */ + + unsigned char state; /* The state of the protosocket. */ +}; + +void psock_init(struct psock *psock, char *buffer, unsigned int buffersize); +/** + * Initialize a protosocket. + * + * This macro initializes a protosocket and must be called before the + * protosocket is used. The initialization also specifies the input buffer + * for the protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * initialized + * + * \param buffer (char *) A pointer to the input buffer for the + * protosocket. + * + * \param buffersize (unsigned int) The size of the input buffer. + * + * \hideinitializer + */ +#define PSOCK_INIT(psock, buffer, buffersize) \ + psock_init(psock, buffer, buffersize) + +/** + * Start the protosocket protothread in a function. + * + * This macro starts the protothread associated with the protosocket and + * must come before other protosocket calls in the function it is used. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * started. + * + * \hideinitializer + */ +#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) + +PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len)); +/** + * Send data. + * + * This macro sends data over a protosocket. The protosocket protothread blocks + * until all data has been sent and is known to have been received by + * the remote end of the TCP connection. + * + * \param psock (struct psock *) A pointer to the protosocket over which + * data is to be sent. + * + * \param data (char *) A pointer to the data that is to be sent. + * + * \param datalen (unsigned int) The length of the data that is to be + * sent. + * + * \hideinitializer + */ +#define PSOCK_SEND(psock, data, datalen) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) + +/** + * \brief Send a null-terminated string. + * \param psock Pointer to the protosocket. + * \param str The string to be sent. + * + * This function sends a null-terminated string over the + * protosocket. + * + * \hideinitializer + */ +#define PSOCK_SEND_STR(psock, str) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) + +PT_THREAD(psock_generator_send(struct psock *psock, + unsigned short (*f)(void *), void *arg)); + +/** + * \brief Generate data with a function and send it + * \param psock Pointer to the protosocket. + * \param generator Pointer to the generator function + * \param arg Argument to the generator function + * + * This function generates data and sends it over the + * protosocket. This can be used to dynamically generate + * data for a transmission, instead of generating the data + * in a buffer beforehand. This function reduces the need for + * buffer memory. The generator function is implemented by + * the application, and a pointer to the function is given + * as an argument with the call to PSOCK_GENERATOR_SEND(). + * + * The generator function should place the generated data + * directly in the uip_appdata buffer, and return the + * length of the generated data. The generator function is + * called by the protosocket layer when the data first is + * sent, and once for every retransmission that is needed. + * + * \hideinitializer + */ +#define PSOCK_GENERATOR_SEND(psock, generator, arg) \ + PT_WAIT_THREAD(&((psock)->pt), \ + psock_generator_send(psock, generator, arg)) + + +/** + * Close a protosocket. + * + * This macro closes a protosocket and can only be called from within the + * protothread in which the protosocket lives. + * + * \param psock (struct psock *) A pointer to the protosocket that is to + * be closed. + * + * \hideinitializer + */ +#define PSOCK_CLOSE(psock) uip_close() + +PT_THREAD(psock_readbuf(struct psock *psock)); +/** + * Read data until the buffer is full. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is read + * until the buffer is full.. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \hideinitializer + */ +#define PSOCK_READBUF(psock) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) + +PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); +/** + * Read data up to a specified character. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is only + * read until the specifieed character appears in the data stream. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \param c (char) The character at which to stop reading. + * + * \hideinitializer + */ +#define PSOCK_READTO(psock, c) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) + +/** + * The length of the data that was previously read. + * + * This macro returns the length of the data that was previously read + * using PSOCK_READTO() or PSOCK_READ(). + * + * \param psock (struct psock *) A pointer to the protosocket holding the data. + * + * \hideinitializer + */ +#define PSOCK_DATALEN(psock) psock_datalen(psock) + +u16_t psock_datalen(struct psock *psock); + +/** + * Exit the protosocket's protothread. + * + * This macro terminates the protothread of the protosocket and should + * almost always be used in conjunction with PSOCK_CLOSE(). + * + * \sa PSOCK_CLOSE_EXIT() + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) + +/** + * Close a protosocket and exit the protosocket's protothread. + * + * This macro closes a protosocket and exits the protosocket's protothread. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_CLOSE_EXIT(psock) \ + do { \ + PSOCK_CLOSE(psock); \ + PSOCK_EXIT(psock); \ + } while(0) + +/** + * Declare the end of a protosocket's protothread. + * + * This macro is used for declaring that the protosocket's protothread + * ends. It must always be used together with a matching PSOCK_BEGIN() + * macro. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_END(psock) PT_END(&((psock)->pt)) + +char psock_newdata(struct psock *s); + +/** + * Check if new data has arrived on a protosocket. + * + * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() + * macro to check if data has arrived on a protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_NEWDATA(psock) psock_newdata(psock) + +/** + * Wait until a condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. The macro PSOCK_NEWDATA() can be used to check if new data + * arrives when the protosocket is waiting. + * + * Typically, this macro is used as follows: + * + \code + PT_THREAD(thread(struct psock *s, struct timer *t)) + { + PSOCK_BEGIN(s); + + PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); + + if(PSOCK_NEWDATA(s)) { + PSOCK_READTO(s, '\n'); + } else { + handle_timed_out(s); + } + + PSOCK_END(s); + } + \endcode + * + * \param psock (struct psock *) A pointer to the protosocket. + * \param condition The condition to wait for. + * + * \hideinitializer + */ +#define PSOCK_WAIT_UNTIL(psock, condition) \ + PT_WAIT_UNTIL(&((psock)->pt), (condition)); + +#define PSOCK_WAIT_THREAD(psock, condition) \ + PT_WAIT_THREAD(&((psock)->pt), (condition)) + +#endif /* __PSOCK_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/pt.h b/bundles/uip/uip/pt.h new file mode 100644 index 00000000..9f1f64da --- /dev/null +++ b/bundles/uip/uip/pt.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \file + * Protothreads implementation. + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_H__ +#define __PT_H__ + +#include "lc.h" + +struct pt { + lc_t lc; +}; + +#define PT_WAITING 0 +#define PT_EXITED 1 +#define PT_ENDED 2 +#define PT_YIELDED 3 + +/** + * \name Initialization + * @{ + */ + +/** + * Initialize a protothread. + * + * Initializes a protothread. Initialization must be done prior to + * starting to execute the protothread. + * + * \param pt A pointer to the protothread control structure. + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_INIT(pt) LC_INIT((pt)->lc) + +/** @} */ + +/** + * \name Declaration and definition + * @{ + */ + +/** + * Declaration of a protothread. + * + * This macro is used to declare a protothread. All protothreads must + * be declared with this macro. + * + * \param name_args The name and arguments of the C function + * implementing the protothread. + * + * \hideinitializer + */ +#define PT_THREAD(name_args) char name_args + +/** + * Declare the start of a protothread inside the C function + * implementing the protothread. + * + * This macro is used to declare the starting point of a + * protothread. It should be placed at the start of the function in + * which the protothread runs. All C statements above the PT_BEGIN() + * invokation will be executed each time the protothread is scheduled. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) + +/** + * Declare the end of a protothread. + * + * This macro is used for declaring that a protothread ends. It must + * always be used together with a matching PT_BEGIN() macro. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ + PT_INIT(pt); return PT_ENDED; } + +/** @} */ + +/** + * \name Blocked wait + * @{ + */ + +/** + * Block and wait until condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. + * + * \param pt A pointer to the protothread control structure. + * \param condition The condition. + * + * \hideinitializer + */ +#define PT_WAIT_UNTIL(pt, condition) \ + do { \ + LC_SET((pt)->lc); \ + if(!(condition)) { \ + return PT_WAITING; \ + } \ + } while(0) + +/** + * Block and wait while condition is true. + * + * This function blocks and waits while condition is true. See + * PT_WAIT_UNTIL(). + * + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * \hideinitializer + */ +#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) + +/** @} */ + +/** + * \name Hierarchical protothreads + * @{ + */ + +/** + * Block and wait until a child protothread completes. + * + * This macro schedules a child protothread. The current protothread + * will block until the child protothread completes. + * + * \note The child protothread must be manually initialized with the + * PT_INIT() function before this function is used. + * + * \param pt A pointer to the protothread control structure. + * \param thread The child protothread with arguments + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) + +/** + * Spawn a child protothread and wait until it exits. + * + * This macro spawns a child protothread and waits until it exits. The + * macro can only be used within a protothread. + * + * \param pt A pointer to the protothread control structure. + * \param child A pointer to the child protothread's control structure. + * \param thread The child protothread with arguments + * + * \hideinitializer + */ +#define PT_SPAWN(pt, child, thread) \ + do { \ + PT_INIT((child)); \ + PT_WAIT_THREAD((pt), (thread)); \ + } while(0) + +/** @} */ + +/** + * \name Exiting and restarting + * @{ + */ + +/** + * Restart the protothread. + * + * This macro will block and cause the running protothread to restart + * its execution at the place of the PT_BEGIN() call. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_RESTART(pt) \ + do { \ + PT_INIT(pt); \ + return PT_WAITING; \ + } while(0) + +/** + * Exit the protothread. + * + * This macro causes the protothread to exit. If the protothread was + * spawned by another protothread, the parent protothread will become + * unblocked and can continue to run. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_EXIT(pt) \ + do { \ + PT_INIT(pt); \ + return PT_EXITED; \ + } while(0) + +/** @} */ + +/** + * \name Calling a protothread + * @{ + */ + +/** + * Schedule a protothread. + * + * This function shedules a protothread. The return value of the + * function is non-zero if the protothread is running or zero if the + * protothread has exited. + * + * \param f The call to the C function implementing the protothread to + * be scheduled + * + * \hideinitializer + */ +#define PT_SCHEDULE(f) ((f) == PT_WAITING) + +/** @} */ + +/** + * \name Yielding from a protothread + * @{ + */ + +/** + * Yield from the current protothread. + * + * This function will yield the protothread, thereby allowing other + * processing to take place in the system. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_YIELD(pt) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if(PT_YIELD_FLAG == 0) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** + * \brief Yield from the protothread until a condition occurs. + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * This function will yield the protothread, until the + * specified condition evaluates to true. + * + * + * \hideinitializer + */ +#define PT_YIELD_UNTIL(pt, cond) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if((PT_YIELD_FLAG == 0) || !(cond)) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** @} */ + +#endif /* __PT_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/timer.c b/bundles/uip/uip/timer.c new file mode 100644 index 00000000..74eedf61 --- /dev/null +++ b/bundles/uip/uip/timer.c @@ -0,0 +1,127 @@ +/** + * \addtogroup timer + * @{ + */ + +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include "clock.h" +#include "timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +timer_set(struct timer *t, clock_time_t interval) +{ + t->interval = interval; + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_rester() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +timer_reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +timer_restart(struct timer *t) +{ + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +timer_expired(struct timer *t) +{ + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/bundles/uip/uip/timer.h b/bundles/uip/uip/timer.h new file mode 100644 index 00000000..057bea49 --- /dev/null +++ b/bundles/uip/uip/timer.h @@ -0,0 +1,86 @@ +/** + * \defgroup timer Timer library + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * @{ + */ + + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $ + */ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "clock.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct timer { + clock_time_t start; + clock_time_t interval; +}; + +void timer_set(struct timer *t, clock_time_t interval); +void timer_reset(struct timer *t); +void timer_restart(struct timer *t); +int timer_expired(struct timer *t); + +#endif /* __TIMER_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/uip-fw.c b/bundles/uip/uip/uip-fw.c new file mode 100644 index 00000000..01858ea7 --- /dev/null +++ b/bundles/uip/uip/uip-fw.c @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipfw uIP packet forwarding + * @{ + * + */ + +/** + * \file + * uIP packet forwarding. + * \author Adam Dunkels + * + * This file implements a number of simple functions which do packet + * forwarding over multiple network interfaces with uIP. + * + */ + +#include "uip.h" +#include "uip_arch.h" +#include "uip-fw.h" + +#include /* for memcpy() */ + +/* + * The list of registered network interfaces. + */ +static struct uip_fw_netif *netifs = NULL; + +/* + * A pointer to the default network interface. + */ +static struct uip_fw_netif *defaultnetif = NULL; + +struct tcpip_hdr { + /* IP header. */ + u8_t vhl, + tos; + u16_t len, + ipid, + ipoffset; + u8_t ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; + + /* TCP header. */ + u16_t srcport, + destport; + u8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +struct icmpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; + /* ICMP (echo) header. */ + u8_t type, icode; + u16_t icmpchksum; + u16_t id, seqno; + u8_t payload[1]; +}; + +/* ICMP ECHO. */ +#define ICMP_ECHO 8 + +/* ICMP TIME-EXCEEDED. */ +#define ICMP_TE 11 + +/* + * Pointer to the TCP/IP headers of the packet in the uip_buf buffer. + */ +#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer. + */ +#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Certain fields of an IP packet that are used for identifying + * duplicate packets. + */ +struct fwcache_entry { + u16_t timer; + + u16_t srcipaddr[2]; + u16_t destipaddr[2]; + u16_t ipid; + u8_t proto; + u8_t unused; + +#if notdef + u16_t payload[2]; +#endif + +#if UIP_REASSEMBLY > 0 + u16_t len, offset; +#endif +}; + +/* + * The number of packets to remember when looking for duplicates. + */ +#ifdef UIP_CONF_FWCACHE_SIZE +#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE +#else +#define FWCACHE_SIZE 2 +#endif + + +/* + * A cache of packet header fields which are used for + * identifying duplicate packets. + */ +static struct fwcache_entry fwcache[FWCACHE_SIZE]; + +/** + * \internal + * The time that a packet cache is active. + */ +#define FW_TIME 20 + +/*------------------------------------------------------------------------------*/ +/** + * Initialize the uIP packet forwarding module. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_init(void) +{ + struct uip_fw_netif *t; + defaultnetif = NULL; + while(netifs != NULL) { + t = netifs; + netifs = netifs->next; + t->next = NULL; + } +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Check if an IP address is within the network defined by an IP + * address and a netmask. + * + * \param ipaddr The IP address to be checked. + * \param netipaddr The IP address of the network. + * \param netmask The netmask of the network. + * + * \return Non-zero if IP address is in network, zero otherwise. + */ +/*------------------------------------------------------------------------------*/ +static unsigned char +ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask) +{ + return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && + (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Send out an ICMP TIME-EXCEEDED message. + * + * This function replaces the packet in the uip_buf buffer with the + * ICMP packet. + */ +/*------------------------------------------------------------------------------*/ +static void +time_exceeded(void) +{ + u16_t tmp16; + + /* We don't send out ICMP errors for ICMP messages. */ + if(ICMPBUF->proto == UIP_PROTO_ICMP) { + uip_len = 0; + return; + } + /* Copy fields from packet header into payload of this ICMP packet. */ + memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28); + + /* Set the ICMP type and code. */ + ICMPBUF->type = ICMP_TE; + ICMPBUF->icode = 0; + + /* Calculate the ICMP checksum. */ + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); + + /* Set the IP destination address to be the source address of the + original packet. */ + tmp16= BUF->destipaddr[0]; + BUF->destipaddr[0] = BUF->srcipaddr[0]; + BUF->srcipaddr[0] = tmp16; + tmp16 = BUF->destipaddr[1]; + BUF->destipaddr[1] = BUF->srcipaddr[1]; + BUF->srcipaddr[1] = tmp16; + + /* Set our IP address as the source address. */ + BUF->srcipaddr[0] = uip_hostaddr[0]; + BUF->srcipaddr[1] = uip_hostaddr[1]; + + /* The size of the ICMP time exceeded packet is 36 + the size of the + IP header (20) = 56. */ + uip_len = 56; + ICMPBUF->len[0] = 0; + ICMPBUF->len[1] = uip_len; + + /* Fill in the other fields in the IP header. */ + ICMPBUF->vhl = 0x45; + ICMPBUF->tos = 0; + ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0; + ICMPBUF->ttl = UIP_TTL; + ICMPBUF->proto = UIP_PROTO_ICMP; + + /* Calculate IP checksum. */ + ICMPBUF->ipchksum = 0; + ICMPBUF->ipchksum = ~(uip_ipchksum()); + + +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Register a packet in the forwarding cache so that it won't be + * forwarded again. + */ +/*------------------------------------------------------------------------------*/ +static void +fwcache_register(void) +{ + struct fwcache_entry *fw; + int i, oldest; + + oldest = FW_TIME; + fw = NULL; + + /* Find the oldest entry in the cache. */ + for(i = 0; i < FWCACHE_SIZE; ++i) { + if(fwcache[i].timer == 0) { + fw = &fwcache[i]; + break; + } else if(fwcache[i].timer <= oldest) { + fw = &fwcache[i]; + oldest = fwcache[i].timer; + } + } + + fw->timer = FW_TIME; + fw->ipid = BUF->ipid; + fw->srcipaddr[0] = BUF->srcipaddr[0]; + fw->srcipaddr[1] = BUF->srcipaddr[1]; + fw->destipaddr[0] = BUF->destipaddr[0]; + fw->destipaddr[1] = BUF->destipaddr[1]; + fw->proto = BUF->proto; +#if notdef + fw->payload[0] = BUF->srcport; + fw->payload[1] = BUF->destport; +#endif +#if UIP_REASSEMBLY > 0 + fw->len = BUF->len; + fw->offset = BUF->ipoffset; +#endif +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Find a network interface for the IP packet in uip_buf. + */ +/*------------------------------------------------------------------------------*/ +static struct uip_fw_netif * +find_netif(void) +{ + struct uip_fw_netif *netif; + + /* Walk through every network interface to check for a match. */ + for(netif = netifs; netif != NULL; netif = netif->next) { + if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr, + netif->netmask)) { + /* If there was a match, we break the loop. */ + return netif; + } + } + + /* If no matching netif was found, we use default netif. */ + return defaultnetif; +} +/*------------------------------------------------------------------------------*/ +/** + * Output an IP packet on the correct network interface. + * + * The IP packet should be present in the uip_buf buffer and its + * length in the global uip_len variable. + * + * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet + * transmission was attempted and that no packet was sent. + * + * \retval UIP_FW_NOROUTE No suitable network interface could be found + * for the outbound packet, and the packet was not sent. + * + * \return The return value from the actual network interface output + * function is passed unmodified as a return value. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_output(void) +{ + struct uip_fw_netif *netif; + + if(uip_len == 0) { + return UIP_FW_ZEROLEN; + } + + fwcache_register(); + +#if UIP_BROADCAST + /* Link local broadcasts go out on all interfaces. */ + if(/*BUF->proto == UIP_PROTO_UDP &&*/ + BUF->destipaddr[0] == 0xffff && + BUF->destipaddr[1] == 0xffff) { + if(defaultnetif != NULL) { + defaultnetif->output(); + } + for(netif = netifs; netif != NULL; netif = netif->next) { + netif->output(); + } + return UIP_FW_OK; + } +#endif /* UIP_BROADCAST */ + + netif = find_netif(); + /* printf("uip_fw_output: netif %p ->output %p len %d\n", netif, + netif->output, + uip_len);*/ + + if(netif == NULL) { + return UIP_FW_NOROUTE; + } + /* If we now have found a suitable network interface, we call its + output function to send out the packet. */ + return netif->output(); +} +/*------------------------------------------------------------------------------*/ +/** + * Forward an IP packet in the uip_buf buffer. + * + * + * + * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if + * the packet should be processed locally. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_forward(void) +{ + struct fwcache_entry *fw; + + /* First check if the packet is destined for ourselves and return 0 + to indicate that the packet should be processed locally. */ + if(BUF->destipaddr[0] == uip_hostaddr[0] && + BUF->destipaddr[1] == uip_hostaddr[1]) { + return UIP_FW_LOCAL; + } + + /* If we use ping IP address configuration, and our IP address is + not yet configured, we should intercept all ICMP echo packets. */ +#if UIP_PINGADDRCONF + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 && + BUF->proto == UIP_PROTO_ICMP && + ICMPBUF->type == ICMP_ECHO) { + return UIP_FW_LOCAL; + } +#endif /* UIP_PINGADDRCONF */ + + /* Check if the packet is in the forwarding cache already, and if so + we drop it. */ + + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer != 0 && +#if UIP_REASSEMBLY > 0 + fw->len == BUF->len && + fw->offset == BUF->ipoffset && +#endif + fw->ipid == BUF->ipid && + fw->srcipaddr[0] == BUF->srcipaddr[0] && + fw->srcipaddr[1] == BUF->srcipaddr[1] && + fw->destipaddr[0] == BUF->destipaddr[0] && + fw->destipaddr[1] == BUF->destipaddr[1] && +#if notdef + fw->payload[0] == BUF->srcport && + fw->payload[1] == BUF->destport && +#endif + fw->proto == BUF->proto) { + /* Drop packet. */ + return UIP_FW_FORWARDED; + } + } + + /* If the TTL reaches zero we produce an ICMP time exceeded message + in the uip_buf buffer and forward that packet back to the sender + of the packet. */ + if(BUF->ttl <= 1) { + /* No time exceeded for broadcasts and multicasts! */ + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } + time_exceeded(); + } + + /* Decrement the TTL (time-to-live) value in the IP header */ + BUF->ttl = BUF->ttl - 1; + + /* Update the IP checksum. */ + if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; + } else { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); + } + + if(uip_len > 0) { + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; + uip_fw_output(); + } + +#if UIP_BROADCAST + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } +#endif /* UIP_BROADCAST */ + + /* Return non-zero to indicate that the packet was forwarded and that no + other processing should be made. */ + return UIP_FW_FORWARDED; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a network interface with the forwarding module. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_register(struct uip_fw_netif *netif) +{ + netif->next = netifs; + netifs = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a default network interface. + * + * All packets that don't go out on any of the other interfaces will + * be routed to the default interface. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_default(struct uip_fw_netif *netif) +{ + defaultnetif = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Perform periodic processing. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_periodic(void) +{ + struct fwcache_entry *fw; + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer > 0) { + --fw->timer; + } + } +} +/*------------------------------------------------------------------------------*/ diff --git a/bundles/uip/uip/uip-fw.h b/bundles/uip/uip/uip-fw.h new file mode 100644 index 00000000..90338509 --- /dev/null +++ b/bundles/uip/uip/uip-fw.h @@ -0,0 +1,176 @@ +/** + * \addtogroup uipfw + * @{ + */ + +/** + * \file + * uIP packet forwarding header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +#ifndef __UIP_FW_H__ +#define __UIP_FW_H__ + +#include "uip.h" + +/** + * Representation of a uIP network interface. + */ +struct uip_fw_netif { + struct uip_fw_netif *next; /**< Pointer to the next interface when + linked in a list. */ + u16_t ipaddr[2]; /**< The IP address of this interface. */ + u16_t netmask[2]; /**< The netmask of the interface. */ + u8_t (* output)(void); + /**< A pointer to the function that + sends a packet. */ +}; + +/** + * Intantiating macro for a uIP network interface. + * + * Example: + \code + struct uip_fw_netif slipnetif = + {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)}; + \endcode + * \param ip1,ip2,ip3,ip4 The IP address of the network interface. + * + * \param nm1,nm2,nm3,nm4 The netmask of the network interface. + * + * \param outputfunc A pointer to the output function of the network interface. + * + * \hideinitializer + */ +#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \ + NULL, \ + {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \ + {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \ + outputfunc + +/** + * Set the IP address of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address. + * + * \hideinitializer + */ +#define uip_fw_setipaddr(netif, addr) \ + do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \ + (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0) +/** + * Set the netmask of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address representing the netmask. + * + * \hideinitializer + */ +#define uip_fw_setnetmask(netif, addr) \ + do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \ + (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0) + +void uip_fw_init(void); +u8_t uip_fw_forward(void); +u8_t uip_fw_output(void); +void uip_fw_register(struct uip_fw_netif *netif); +void uip_fw_default(struct uip_fw_netif *netif); +void uip_fw_periodic(void); + + +/** + * A non-error message that indicates that a packet should be + * processed locally. + * + * \hideinitializer + */ +#define UIP_FW_LOCAL 0 + +/** + * A non-error message that indicates that something went OK. + * + * \hideinitializer + */ +#define UIP_FW_OK 0 + +/** + * A non-error message that indicates that a packet was forwarded. + * + * \hideinitializer + */ +#define UIP_FW_FORWARDED 1 + +/** + * A non-error message that indicates that a zero-length packet + * transmission was attempted, and that no packet was sent. + * + * \hideinitializer + */ +#define UIP_FW_ZEROLEN 2 + +/** + * An error message that indicates that a packet that was too large + * for the outbound network interface was detected. + * + * \hideinitializer + */ +#define UIP_FW_TOOLARGE 3 + +/** + * An error message that indicates that no suitable interface could be + * found for an outbound packet. + * + * \hideinitializer + */ +#define UIP_FW_NOROUTE 4 + +/** + * An error message that indicates that a packet that should be + * forwarded or output was dropped. + * + * \hideinitializer + */ +#define UIP_FW_DROPPED 5 + + +#endif /* __UIP_FW_H__ */ + +/** @} */ diff --git a/bundles/uip/uip/uip-neighbor.c b/bundles/uip/uip/uip-neighbor.c new file mode 100644 index 00000000..739c03e9 --- /dev/null +++ b/bundles/uip/uip/uip-neighbor.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \file + * Database of link-local neighbors, used by IPv6 code and + * to be used by a future ARP code rewrite. + * \author + * Adam Dunkels + */ + +#include "uip-neighbor.h" + +#include + +#define MAX_TIME 128 + +#ifdef UIP_NEIGHBOR_CONF_ENTRIES +#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES +#else /* UIP_NEIGHBOR_CONF_ENTRIES */ +#define ENTRIES 8 +#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ + +struct neighbor_entry { + uip_ipaddr_t ipaddr; + struct uip_neighbor_addr addr; + u8_t time; +}; +static struct neighbor_entry entries[ENTRIES]; + +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_init(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + entries[i].time = MAX_TIME; + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_periodic(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time < MAX_TIME) { + entries[i].time++; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) +{ + int i, oldest; + u8_t oldest_time; + + printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], + addr->addr.addr[4], addr->addr.addr[5]); + + /* Find the first unused entry or the oldest used entry. */ + oldest_time = 0; + oldest = 0; + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time == MAX_TIME) { + oldest = i; + break; + } + if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { + oldest = i; + break; + } + if(entries[i].time > oldest_time) { + oldest = i; + oldest_time = entries[i].time; + } + } + + /* Use the oldest or first free entry (either pointed to by the + "oldest" variable). */ + entries[oldest].time = 0; + uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); + memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); +} +/*---------------------------------------------------------------------------*/ +static struct neighbor_entry * +find_entry(uip_ipaddr_t ipaddr) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { + return &entries[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_update(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + e->time = 0; + } +} +/*---------------------------------------------------------------------------*/ +struct uip_neighbor_addr * +uip_neighbor_lookup(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], + e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ + + return &e->addr; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/uip/uip-neighbor.h b/bundles/uip/uip/uip-neighbor.h new file mode 100644 index 00000000..d3b351c2 --- /dev/null +++ b/bundles/uip/uip/uip-neighbor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +/** + * \file + * Header file for database of link-local neighbors, used by + * IPv6 code and to be used by future ARP code. + * \author + * Adam Dunkels + */ + +#ifndef __UIP_NEIGHBOR_H__ +#define __UIP_NEIGHBOR_H__ + +#include "uip.h" + +struct uip_neighbor_addr { +#if UIP_NEIGHBOR_CONF_ADDRTYPE + UIP_NEIGHBOR_CONF_ADDRTYPE addr; +#else + struct uip_eth_addr addr; +#endif +}; + +void uip_neighbor_init(void); +void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); +void uip_neighbor_update(uip_ipaddr_t ipaddr); +struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); +void uip_neighbor_periodic(void); + +#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/bundles/uip/uip/uip-split.c b/bundles/uip/uip/uip-split.c new file mode 100644 index 00000000..a910ee62 --- /dev/null +++ b/bundles/uip/uip/uip-split.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ + +#include + +#include "uip-split.h" +#include "uip.h" +#include "uip-fw.h" +#include "uip_arch.h" + + + +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/*-----------------------------------------------------------------------------*/ +void +uip_split_output(void) +{ + u16_t tcplen, len1, len2; + + /* We only try to split maximum sized TCP segments. */ + if(BUF->proto == UIP_PROTO_TCP && + uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { + + tcplen = uip_len - UIP_TCPIP_HLEN; + /* Split the segment in two. If the original packet length was + odd, we make the second packet one byte larger. */ + len1 = len2 = tcplen / 2; + if(len1 + len2 < tcplen) { + ++len2; + } + + /* Create the first packet. This is done by altering the length + field of the IP header and updating the checksums. */ + uip_len = len1 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the first packet. */ + /* uip_fw_output();*/ + tcpip_output(); + + /* Now, create the second packet. To do this, it is not enough to + just alter the length field, but we must also update the TCP + sequence number and point the uip_appdata to a new place in + memory. This place is detemined by the length of the first + packet (len1). */ + uip_len = len2 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* uip_appdata += len1;*/ + memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); + + uip_add32(BUF->seqno, len1); + BUF->seqno[0] = uip_acc32[0]; + BUF->seqno[1] = uip_acc32[1]; + BUF->seqno[2] = uip_acc32[2]; + BUF->seqno[3] = uip_acc32[3]; + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the second packet. */ + /* uip_fw_output();*/ + tcpip_output(); + } else { + /* uip_fw_output();*/ + tcpip_output(); + } + +} +/*-----------------------------------------------------------------------------*/ diff --git a/bundles/uip/uip/uip-split.h b/bundles/uip/uip/uip-split.h new file mode 100644 index 00000000..c2c1789c --- /dev/null +++ b/bundles/uip/uip/uip-split.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * Author: Adam Dunkels + * + * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipsplit uIP TCP throughput booster hack + * @{ + * + * The basic uIP TCP implementation only allows each TCP connection to + * have a single TCP segment in flight at any given time. Because of + * the delayed ACK algorithm employed by most TCP receivers, uIP's + * limit on the amount of in-flight TCP segments seriously reduces the + * maximum achievable throughput for sending data from uIP. + * + * The uip-split module is a hack which tries to remedy this + * situation. By splitting maximum sized outgoing TCP segments into + * two, the delayed ACK algorithm is not invoked at TCP + * receivers. This improves the throughput when sending data from uIP + * by orders of magnitude. + * + * The uip-split module uses the uip-fw module (uIP IP packet + * forwarding) for sending packets. Therefore, the uip-fw module must + * be set up with the appropriate network interfaces for this module + * to work. + */ + + +/** + * \file + * Module for splitting outbound TCP segments in two to avoid the + * delayed ACK throughput degradation. + * \author + * Adam Dunkels + * + */ + +#ifndef __UIP_SPLIT_H__ +#define __UIP_SPLIT_H__ + +/** + * Handle outgoing packets. + * + * This function inspects an outgoing packet in the uip_buf buffer and + * sends it out using the uip_fw_output() function. If the packet is a + * full-sized TCP segment it will be split into two segments and + * transmitted separately. This function should be called instead of + * the actual device driver output function, or the uip_fw_output() + * function. + * + * The headers of the outgoing packet is assumed to be in the uip_buf + * buffer and the payload is assumed to be wherever uip_appdata + * points. The length of the outgoing packet is assumed to be in the + * uip_len variable. + * + */ +void uip_split_output(void); + +#endif /* __UIP_SPLIT_H__ */ + +/** @} */ +/** @} */ diff --git a/bundles/uip/uip/uip.c b/bundles/uip/uip/uip.c new file mode 100644 index 00000000..ee885143 --- /dev/null +++ b/bundles/uip/uip/uip.c @@ -0,0 +1,1897 @@ +#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ + +/** + * \defgroup uip The uIP TCP/IP stack + * @{ + * + * uIP is an implementation of the TCP/IP protocol stack intended for + * small 8-bit and 16-bit microcontrollers. + * + * uIP provides the necessary protocols for Internet communication, + * with a very small code footprint and RAM requirements - the uIP + * code size is on the order of a few kilobytes and RAM usage is on + * the order of a few hundred bytes. + */ + +/** + * \file + * The uIP TCP/IP stack code. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $ + * + */ + +/* + * uIP is a small implementation of the IP, UDP and TCP protocols (as + * well as some basic ICMP stuff). The implementation couples the IP, + * UDP, TCP and the application layers very tightly. To keep the size + * of the compiled code down, this code frequently uses the goto + * statement. While it would be possible to break the uip_process() + * function into many smaller functions, this would increase the code + * size because of the overhead of parameter passing and the fact that + * the optimier would not be as efficient. + * + * The principle is that we have a small buffer, called the uip_buf, + * in which the device driver puts an incoming packet. The TCP/IP + * stack parses the headers in the packet, and calls the + * application. If the remote host has sent data to the application, + * this data is present in the uip_buf and the application read the + * data from there. It is up to the application to put this data into + * a byte stream if needed. The application will not be fed with data + * that is out of sequence. + * + * If the application whishes to send data to the peer, it should put + * its data into the uip_buf. The uip_appdata pointer points to the + * first available byte. The TCP/IP stack will calculate the + * checksums, and fill in the necessary header fields and finally send + * the packet back to the peer. +*/ + +#include "uip.h" +#include "uipopt.h" +#include "uip_arch.h" + +#if UIP_CONF_IPV6 +#include "uip-neighbor.h" +#endif /* UIP_CONF_IPV6 */ + +#include + +/*---------------------------------------------------------------------------*/ +/* Variable definitions. */ + + +/* The IP address of this host. If it is defined to be fixed (by + setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set + here. Otherwise, the address */ +#if UIP_FIXEDADDR > 0 +const uip_ipaddr_t uip_hostaddr = + {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), + HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; +const uip_ipaddr_t uip_draddr = + {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), + HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; +const uip_ipaddr_t uip_netmask = + {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), + HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; +#else +uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; +#endif /* UIP_FIXEDADDR */ + +static const uip_ipaddr_t all_ones_addr = +#if UIP_CONF_IPV6 + {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; +#else /* UIP_CONF_IPV6 */ + {0xffff,0xffff}; +#endif /* UIP_CONF_IPV6 */ +static const uip_ipaddr_t all_zeroes_addr = +#if UIP_CONF_IPV6 + {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; +#else /* UIP_CONF_IPV6 */ + {0x0000,0x0000}; +#endif /* UIP_CONF_IPV6 */ + + +#if UIP_FIXEDETHADDR +const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, + UIP_ETHADDR1, + UIP_ETHADDR2, + UIP_ETHADDR3, + UIP_ETHADDR4, + UIP_ETHADDR5}}; +#else +struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; +#endif + +#ifndef UIP_CONF_EXTERNAL_BUFFER +u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains + incoming packets. */ +#endif /* UIP_CONF_EXTERNAL_BUFFER */ + +void *uip_appdata; /* The uip_appdata pointer points to + application data. */ +void *uip_sappdata; /* The uip_appdata pointer points to + the application data which is to + be sent. */ +#if UIP_URGDATA > 0 +void *uip_urgdata; /* The uip_urgdata pointer points to + urgent data (out-of-band data), if + present. */ +u16_t uip_urglen, uip_surglen; +#endif /* UIP_URGDATA > 0 */ + +u16_t uip_len, uip_slen; + /* The uip_len is either 8 or 16 bits, + depending on the maximum packet + size. */ + +u8_t uip_flags; /* The uip_flags variable is used for + communication between the TCP/IP stack + and the application program. */ +struct uip_conn *uip_conn; /* uip_conn always points to the current + connection. */ + +struct uip_conn uip_conns[UIP_CONNS]; + /* The uip_conns array holds all TCP + connections. */ +u16_t uip_listenports[UIP_LISTENPORTS]; + /* The uip_listenports list all currently + listning ports. */ +#if UIP_UDP +struct uip_udp_conn *uip_udp_conn; +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; +#endif /* UIP_UDP */ + +static u16_t ipid; /* Ths ipid variable is an increasing + number that is used for the IP ID + field. */ + +void uip_setipid(u16_t id) { ipid = id; } + +static u8_t iss[4]; /* The iss variable is used for the TCP + initial sequence number. */ + +#if UIP_ACTIVE_OPEN +static u16_t lastport; /* Keeps track of the last port used for + a new connection. */ +#endif /* UIP_ACTIVE_OPEN */ + +/* Temporary variables. */ +u8_t uip_acc32[4]; +static u8_t c, opt; +static u16_t tmp16; + +/* Structures and definitions. */ +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 +#define TCP_PSH 0x08 +#define TCP_ACK 0x10 +#define TCP_URG 0x20 +#define TCP_CTL 0x3f + +#define TCP_OPT_END 0 /* End of TCP options list */ +#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ +#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ + +#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ + +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 + +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_ECHO 128 +#define ICMP6_NEIGHBOR_SOLICITATION 135 +#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 + +#define ICMP6_FLAG_S (1 << 6) + +#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 +#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 + + +/* Macros. */ +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) +#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) + + +#if UIP_STATISTICS == 1 +struct uip_stats uip_stat; +#define UIP_STAT(s) s +#else +#define UIP_STAT(s) +#endif /* UIP_STATISTICS == 1 */ + +#if UIP_LOGGING == 1 +#include +void uip_log(char *msg); +#define UIP_LOG(m) uip_log(m) +#else +#define UIP_LOG(m) +#endif /* UIP_LOGGING == 1 */ + +#if ! UIP_ARCH_ADD32 +void +uip_add32(u8_t *op32, u16_t op16) +{ + uip_acc32[3] = op32[3] + (op16 & 0xff); + uip_acc32[2] = op32[2] + (op16 >> 8); + uip_acc32[1] = op32[1]; + uip_acc32[0] = op32[0]; + + if(uip_acc32[2] < (op16 >> 8)) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + + + if(uip_acc32[3] < (op16 & 0xff)) { + ++uip_acc32[2]; + if(uip_acc32[2] == 0) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + } +} + +#endif /* UIP_ARCH_ADD32 */ + +#if ! UIP_ARCH_CHKSUM +/*---------------------------------------------------------------------------*/ +static u16_t +chksum(u16_t sum, const u8_t *data, u16_t len) +{ + u16_t t; + const u8_t *dataptr; + const u8_t *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while(dataptr < last_byte) { /* At least two more bytes */ + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + dataptr += 2; + } + + if(dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; +} +/*---------------------------------------------------------------------------*/ +u16_t +uip_chksum(u16_t *data, u16_t len) +{ + return htons(chksum(0, (u8_t *)data, len)); +} +/*---------------------------------------------------------------------------*/ +#ifndef UIP_ARCH_IPCHKSUM +u16_t +uip_ipchksum(void) +{ + u16_t sum; + + sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); + DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); + return (sum == 0) ? 0xffff : htons(sum); +} +#endif +/*---------------------------------------------------------------------------*/ +static u16_t +upper_layer_chksum(u8_t proto) +{ + u16_t upper_layer_len; + u16_t sum; + +#if UIP_CONF_IPV6 + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); +#else /* UIP_CONF_IPV6 */ + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; +#endif /* UIP_CONF_IPV6 */ + + /* First sum pseudoheader. */ + + /* IP protocol and length fields. This addition cannot carry. */ + sum = upper_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); + + /* Sum TCP header and data. */ + sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], + upper_layer_len); + + return (sum == 0) ? 0xffff : htons(sum); +} +/*---------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +u16_t +uip_icmp6chksum(void) +{ + return upper_layer_chksum(UIP_PROTO_ICMP6); + +} +#endif /* UIP_CONF_IPV6 */ +/*---------------------------------------------------------------------------*/ +u16_t +uip_tcpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_TCP); +} +/*---------------------------------------------------------------------------*/ +#if UIP_UDP_CHECKSUMS +u16_t +uip_udpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_UDP); +} +#endif /* UIP_UDP_CHECKSUMS */ +#endif /* UIP_ARCH_CHKSUM */ +/*---------------------------------------------------------------------------*/ +void +uip_init(void) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + uip_listenports[c] = 0; + } + for(c = 0; c < UIP_CONNS; ++c) { + uip_conns[c].tcpstateflags = UIP_CLOSED; + } +#if UIP_ACTIVE_OPEN + lastport = 1024; +#endif /* UIP_ACTIVE_OPEN */ + +#if UIP_UDP + for(c = 0; c < UIP_UDP_CONNS; ++c) { + uip_udp_conns[c].lport = 0; + } +#endif /* UIP_UDP */ + + + /* IPv4 initialization. */ +#if UIP_FIXEDADDR == 0 + /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ +#endif /* UIP_FIXEDADDR */ + +} +/*---------------------------------------------------------------------------*/ +#if UIP_ACTIVE_OPEN +struct uip_conn * +uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) +{ + register struct uip_conn *conn, *cconn; + + /* Find an unused local port. */ + again: + ++lastport; + + if(lastport >= 32000) { + lastport = 4096; + } + + /* Check if this port is already in use, and if so try to find + another one. */ + for(c = 0; c < UIP_CONNS; ++c) { + conn = &uip_conns[c]; + if(conn->tcpstateflags != UIP_CLOSED && + conn->lport == htons(lastport)) { + goto again; + } + } + + conn = 0; + for(c = 0; c < UIP_CONNS; ++c) { + cconn = &uip_conns[c]; + if(cconn->tcpstateflags == UIP_CLOSED) { + conn = cconn; + break; + } + if(cconn->tcpstateflags == UIP_TIME_WAIT) { + if(conn == 0 || + cconn->timer > conn->timer) { + conn = cconn; + } + } + } + + if(conn == 0) { + return 0; + } + + conn->tcpstateflags = UIP_SYN_SENT; + + conn->snd_nxt[0] = iss[0]; + conn->snd_nxt[1] = iss[1]; + conn->snd_nxt[2] = iss[2]; + conn->snd_nxt[3] = iss[3]; + + conn->initialmss = conn->mss = UIP_TCP_MSS; + + conn->len = 1; /* TCP length of the SYN is one. */ + conn->nrtx = 0; + conn->timer = 1; /* Send the SYN next time around. */ + conn->rto = UIP_RTO; + conn->sa = 0; + conn->sv = 16; /* Initial value of the RTT variance. */ + conn->lport = htons(lastport); + conn->rport = rport; + uip_ipaddr_copy(&conn->ripaddr, ripaddr); + + return conn; +} +#endif /* UIP_ACTIVE_OPEN */ +/*---------------------------------------------------------------------------*/ +#if UIP_UDP +struct uip_udp_conn * +uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) +{ + register struct uip_udp_conn *conn; + + /* Find an unused local port. */ + again: + ++lastport; + + if(lastport >= 32000) { + lastport = 4096; + } + + for(c = 0; c < UIP_UDP_CONNS; ++c) { + if(uip_udp_conns[c].lport == htons(lastport)) { + goto again; + } + } + + + conn = 0; + for(c = 0; c < UIP_UDP_CONNS; ++c) { + if(uip_udp_conns[c].lport == 0) { + conn = &uip_udp_conns[c]; + break; + } + } + + if(conn == 0) { + return 0; + } + + conn->lport = HTONS(lastport); + conn->rport = rport; + if(ripaddr == NULL) { + memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); + } else { + uip_ipaddr_copy(&conn->ripaddr, ripaddr); + } + conn->ttl = UIP_TTL; + + return conn; +} +#endif /* UIP_UDP */ +/*---------------------------------------------------------------------------*/ +void +uip_unlisten(u16_t port) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(uip_listenports[c] == port) { + uip_listenports[c] = 0; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_listen(u16_t port) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(uip_listenports[c] == 0) { + uip_listenports[c] = port; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +/* XXX: IP fragment reassembly: not well-tested. */ + +#if UIP_REASSEMBLY && !UIP_CONF_IPV6 +#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) +static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; +static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; +static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, + 0x0f, 0x07, 0x03, 0x01}; +static u16_t uip_reasslen; +static u8_t uip_reassflags; +#define UIP_REASS_FLAG_LASTFRAG 0x01 +static u8_t uip_reasstmr; + +#define IP_MF 0x20 + +static u8_t +uip_reass(void) +{ + u16_t offset, len; + u16_t i; + + /* If ip_reasstmr is zero, no packet is present in the buffer, so we + write the IP header of the fragment into the reassembly + buffer. The timer is updated with the maximum age. */ + if(uip_reasstmr == 0) { + memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); + uip_reasstmr = UIP_REASS_MAXAGE; + uip_reassflags = 0; + /* Clear the bitmap. */ + memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); + } + + /* Check if the incoming fragment matches the one currently present + in the reasembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && + BUF->srcipaddr[1] == FBUF->srcipaddr[1] && + BUF->destipaddr[0] == FBUF->destipaddr[0] && + BUF->destipaddr[1] == FBUF->destipaddr[1] && + BUF->ipid[0] == FBUF->ipid[0] && + BUF->ipid[1] == FBUF->ipid[1]) { + + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; + + /* If the offset or the offset + fragment length overflows the + reassembly buffer, we discard the entire packet. */ + if(offset > UIP_REASS_BUFSIZE || + offset + len > UIP_REASS_BUFSIZE) { + uip_reasstmr = 0; + goto nullreturn; + } + + /* Copy the fragment into the reassembly buffer, at the right + offset. */ + memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], + (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), + len); + + /* Update the bitmap. */ + if(offset / (8 * 8) == (offset + len) / (8 * 8)) { + /* If the two endpoints are in the same byte, we only update + that byte. */ + + uip_reassbitmap[offset / (8 * 8)] |= + bitmap_bits[(offset / 8 ) & 7] & + ~bitmap_bits[((offset + len) / 8 ) & 7]; + } else { + /* If the two endpoints are in different bytes, we update the + bytes in the endpoints and fill the stuff inbetween with + 0xff. */ + uip_reassbitmap[offset / (8 * 8)] |= + bitmap_bits[(offset / 8 ) & 7]; + for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { + uip_reassbitmap[i] = 0xff; + } + uip_reassbitmap[(offset + len) / (8 * 8)] |= + ~bitmap_bits[((offset + len) / 8 ) & 7]; + } + + /* If this fragment has the More Fragments flag set to zero, we + know that this is the last fragment, so we can calculate the + size of the entire packet. We also set the + IP_REASS_FLAG_LASTFRAG flag to indicate that we have received + the final fragment. */ + + if((BUF->ipoffset[0] & IP_MF) == 0) { + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; + uip_reasslen = offset + len; + } + + /* Finally, we check if we have a full packet in the buffer. We do + this by checking if we have the last fragment and if all bits + in the bitmap are set. */ + if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { + /* Check all bytes up to and including all but the last byte in + the bitmap. */ + for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { + if(uip_reassbitmap[i] != 0xff) { + goto nullreturn; + } + } + /* Check the last byte in the bitmap. It should contain just the + right amount of bits. */ + if(uip_reassbitmap[uip_reasslen / (8 * 8)] != + (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { + goto nullreturn; + } + + /* If we have come this far, we have a full packet in the + buffer, so we allocate a pbuf and copy the packet into it. We + also reset the timer. */ + uip_reasstmr = 0; + memcpy(BUF, FBUF, uip_reasslen); + + /* Pretend to be a "normal" (i.e., not fragmented) IP packet + from now on. */ + BUF->ipoffset[0] = BUF->ipoffset[1] = 0; + BUF->len[0] = uip_reasslen >> 8; + BUF->len[1] = uip_reasslen & 0xff; + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); + + return uip_reasslen; + } + } + + nullreturn: + return 0; +} +#endif /* UIP_REASSEMBLY */ +/*---------------------------------------------------------------------------*/ +static void +uip_add_rcv_nxt(u16_t n) +{ + uip_add32(uip_conn->rcv_nxt, n); + uip_conn->rcv_nxt[0] = uip_acc32[0]; + uip_conn->rcv_nxt[1] = uip_acc32[1]; + uip_conn->rcv_nxt[2] = uip_acc32[2]; + uip_conn->rcv_nxt[3] = uip_acc32[3]; +} +/*---------------------------------------------------------------------------*/ +void +uip_process(u8_t flag) +{ + register struct uip_conn *uip_connr = uip_conn; + +#if UIP_UDP + if(flag == UIP_UDP_SEND_CONN) { + goto udp_send; + } +#endif /* UIP_UDP */ + + uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; + + /* Check if we were invoked because of a poll request for a + particular connection. */ + if(flag == UIP_POLL_REQUEST) { + if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && + !uip_outstanding(uip_connr)) { + uip_flags = UIP_POLL; + UIP_APPCALL(); + goto appsend; + } + goto drop; + + /* Check if we were invoked because of the perodic timer fireing. */ + } else if(flag == UIP_TIMER) { +#if UIP_REASSEMBLY + if(uip_reasstmr != 0) { + --uip_reasstmr; + } +#endif /* UIP_REASSEMBLY */ + /* Increase the initial sequence number. */ + if(++iss[3] == 0) { + if(++iss[2] == 0) { + if(++iss[1] == 0) { + ++iss[0]; + } + } + } + + /* Reset the length variables. */ + uip_len = 0; + uip_slen = 0; + + /* Check if the connection is in a state in which we simply wait + for the connection to time out. If so, we increase the + connection's timer and remove the connection if it times + out. */ + if(uip_connr->tcpstateflags == UIP_TIME_WAIT || + uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { + ++(uip_connr->timer); + if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { + uip_connr->tcpstateflags = UIP_CLOSED; + } + } else if(uip_connr->tcpstateflags != UIP_CLOSED) { + /* If the connection has outstanding data, we increase the + connection's timer and see if it has reached the RTO value + in which case we retransmit. */ + if(uip_outstanding(uip_connr)) { + if(uip_connr->timer-- == 0) { + if(uip_connr->nrtx == UIP_MAXRTX || + ((uip_connr->tcpstateflags == UIP_SYN_SENT || + uip_connr->tcpstateflags == UIP_SYN_RCVD) && + uip_connr->nrtx == UIP_MAXSYNRTX)) { + uip_connr->tcpstateflags = UIP_CLOSED; + + /* We call UIP_APPCALL() with uip_flags set to + UIP_TIMEDOUT to inform the application that the + connection has timed out. */ + uip_flags = UIP_TIMEDOUT; + UIP_APPCALL(); + + /* We also send a reset packet to the remote host. */ + BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } + + /* Exponential backoff. */ + uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? + 4: + uip_connr->nrtx); + ++(uip_connr->nrtx); + + /* Ok, so we need to retransmit. We do this differently + depending on which state we are in. In ESTABLISHED, we + call upon the application so that it may prepare the + data for the retransmit. In SYN_RCVD, we resend the + SYNACK that we sent earlier and in LAST_ACK we have to + retransmit our FINACK. */ + UIP_STAT(++uip_stat.tcp.rexmit); + switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + case UIP_SYN_RCVD: + /* In the SYN_RCVD state, we should retransmit our + SYNACK. */ + goto tcp_send_synack; + +#if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In the SYN_SENT state, we retransmit out SYN. */ + BUF->flags = 0; + goto tcp_send_syn; +#endif /* UIP_ACTIVE_OPEN */ + + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application + to do the actual retransmit after which we jump into + the code for sending out the packet (the apprexmit + label). */ + uip_flags = UIP_REXMIT; + UIP_APPCALL(); + goto apprexmit; + + case UIP_FIN_WAIT_1: + case UIP_CLOSING: + case UIP_LAST_ACK: + /* In all these states we should retransmit a FINACK. */ + goto tcp_send_finack; + + } + } + } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { + /* If there was no need for a retransmission, we poll the + application for new data. */ + uip_flags = UIP_POLL; + UIP_APPCALL(); + goto appsend; + } + } + goto drop; + } +#if UIP_UDP + if(flag == UIP_UDP_TIMER) { + if(uip_udp_conn->lport != 0) { + uip_conn = NULL; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + uip_len = uip_slen = 0; + uip_flags = UIP_POLL; + UIP_UDP_APPCALL(); + goto udp_send; + } else { + goto drop; + } + } +#endif + + /* This is where the input processing starts. */ + UIP_STAT(++uip_stat.ip.recv); + + /* Start of IP input header processing code. */ + +#if UIP_CONF_IPV6 + /* Check validity of the IP header. */ + if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.vhlerr); + UIP_LOG("ipv6: invalid version."); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* Check validity of the IP header. */ + if(BUF->vhl != 0x45) { /* IP version and header length. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.vhlerr); + UIP_LOG("ip: invalid version or header length."); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + + /* Check the size of the packet. If the size reported to us in + uip_len is smaller the size reported in the IP header, we assume + that the packet has been corrupted in transit. If the size of + uip_len is larger than the size reported in the IP packet header, + the packet has been padded and we set uip_len to the correct + value.. */ + + if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { + uip_len = (BUF->len[0] << 8) + BUF->len[1]; +#if UIP_CONF_IPV6 + uip_len += 40; /* The length reported in the IPv6 header is the + length of the payload that follows the + header. However, uIP uses the uip_len variable + for holding the size of the entire packet, + including the IP header. For IPv4 this is not a + problem as the length field in the IPv4 header + contains the length of the entire packet. But + for IPv6 we need to add the size of the IPv6 + header (40 bytes). */ +#endif /* UIP_CONF_IPV6 */ + } else { + UIP_LOG("ip: packet shorter than reported in IP header."); + goto drop; + } + +#if !UIP_CONF_IPV6 + /* Check the fragment flag. */ + if((BUF->ipoffset[0] & 0x3f) != 0 || + BUF->ipoffset[1] != 0) { +#if UIP_REASSEMBLY + uip_len = uip_reass(); + if(uip_len == 0) { + goto drop; + } +#else /* UIP_REASSEMBLY */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.fragerr); + UIP_LOG("ip: fragment dropped."); + goto drop; +#endif /* UIP_REASSEMBLY */ + } +#endif /* UIP_CONF_IPV6 */ + + if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { + /* If we are configured to use ping IP address configuration and + hasn't been assigned an IP address yet, we accept all ICMP + packets. */ +#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 + if(BUF->proto == UIP_PROTO_ICMP) { + UIP_LOG("ip: possible ping config packet received."); + goto icmp_input; + } else { + UIP_LOG("ip: packet dropped since no address assigned."); + goto drop; + } +#endif /* UIP_PINGADDRCONF */ + + } else { + /* If IP broadcast support is configured, we check for a broadcast + UDP packet, which may be destined to us. */ +#if UIP_BROADCAST + DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); + if(BUF->proto == UIP_PROTO_UDP && + uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr) + /*&& + uip_ipchksum() == 0xffff*/) { + goto udp_input; + } +#endif /* UIP_BROADCAST */ + + /* Check if the packet is destined for our IP address. */ +#if !UIP_CONF_IPV6 + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* For IPv6, packet reception is a little trickier as we need to + make sure that we listen to certain multicast addresses (all + hosts multicast address, and the solicited-node multicast + address) as well. However, we will cheat here and accept all + multicast packets that are sent to the ff02::/16 addresses. */ + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && + BUF->destipaddr[0] != HTONS(0xff02)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + } + +#if !UIP_CONF_IPV6 + if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header + checksum. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.chkerr); + UIP_LOG("ip: bad checksum."); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + + if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, + proceed with TCP input + processing. */ + goto tcp_input; + } + +#if UIP_UDP + if(BUF->proto == UIP_PROTO_UDP) { + goto udp_input; + } +#endif /* UIP_UDP */ + +#if !UIP_CONF_IPV6 + /* ICMPv4 processing code follows. */ + if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from + here. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.protoerr); + UIP_LOG("ip: neither tcp nor icmp."); + goto drop; + } + +#if UIP_PINGADDRCONF + icmp_input: +#endif /* UIP_PINGADDRCONF */ + UIP_STAT(++uip_stat.icmp.recv); + + /* ICMP echo (i.e., ping) processing. This is simple, we only change + the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP + checksum before we return the packet. */ + if(ICMPBUF->type != ICMP_ECHO) { + UIP_STAT(++uip_stat.icmp.drop); + UIP_STAT(++uip_stat.icmp.typeerr); + UIP_LOG("icmp: not icmp echo."); + goto drop; + } + + /* If we are configured to use ping IP address assignment, we use + the destination IP address of this ping packet and assign it to + ourself. */ +#if UIP_PINGADDRCONF + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { + uip_hostaddr[0] = BUF->destipaddr[0]; + uip_hostaddr[1] = BUF->destipaddr[1]; + } +#endif /* UIP_PINGADDRCONF */ + + ICMPBUF->type = ICMP_ECHO_REPLY; + + if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; + } else { + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); + } + + /* Swap IP addresses. */ + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + + UIP_STAT(++uip_stat.icmp.sent); + goto send; + + /* End of IPv4 input header processing code. */ +#else /* !UIP_CONF_IPV6 */ + + /* This is IPv6 ICMPv6 processing code. */ + DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); + + if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from + here. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.protoerr); + UIP_LOG("ip: neither tcp nor icmp6."); + goto drop; + } + + UIP_STAT(++uip_stat.icmp.recv); + + /* If we get a neighbor solicitation for our address we should send + a neighbor advertisement message back. */ + if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { + if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { + + if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { + /* Save the sender's address in our neighbor list. */ + uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); + } + + /* We should now send a neighbor advertisement back to where the + neighbor solicication came from. */ + ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; + ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ + + ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; + + uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); + uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); + ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; + ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ + memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + goto send; + + } + goto drop; + } else if(ICMPBUF->type == ICMP6_ECHO) { + /* ICMP echo (i.e., ping) processing. This is simple, we only + change the ICMP type from ECHO to ECHO_REPLY and update the + ICMP checksum before we return the packet. */ + + ICMPBUF->type = ICMP6_ECHO_REPLY; + + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.icmp.sent); + goto send; + } else { + DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); + UIP_STAT(++uip_stat.icmp.drop); + UIP_STAT(++uip_stat.icmp.typeerr); + UIP_LOG("icmp: unknown ICMP message."); + goto drop; + } + + /* End of IPv6 ICMP processing. */ + +#endif /* !UIP_CONF_IPV6 */ + +#if UIP_UDP + /* UDP input processing. */ + udp_input: + /* UDP processing is really just a hack. We don't do anything to the + UDP/IP headers, but let the UDP application do all the hard + work. If the application sets uip_slen, it has a packet to + send. */ +#if UIP_UDP_CHECKSUMS + uip_len = uip_len - UIP_IPUDPH_LEN; + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { + UIP_STAT(++uip_stat.udp.drop); + UIP_STAT(++uip_stat.udp.chkerr); + UIP_LOG("udp: bad checksum."); + goto drop; + } +#else /* UIP_UDP_CHECKSUMS */ + uip_len = uip_len - UIP_IPUDPH_LEN; +#endif /* UIP_UDP_CHECKSUMS */ + + /* Demultiplex this UDP packet between the UDP "connections". */ + for(uip_udp_conn = &uip_udp_conns[0]; + uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; + ++uip_udp_conn) { + /* If the local UDP port is non-zero, the connection is considered + to be used. If so, the local port number is checked against the + destination port number in the received packet. If the two port + numbers match, the remote port number is checked if the + connection is bound to a remote port. Finally, if the + connection is bound to a remote IP address, the source IP + address of the packet is checked. */ + if(uip_udp_conn->lport != 0 && + UDPBUF->destport == uip_udp_conn->lport && + (uip_udp_conn->rport == 0 || + UDPBUF->srcport == uip_udp_conn->rport) && + (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || + uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) || + uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { + goto udp_found; + } + } + UIP_LOG("udp: no matching connection found"); + goto drop; + + udp_found: + uip_conn = NULL; + uip_flags = UIP_NEWDATA; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + uip_slen = 0; + UIP_UDP_APPCALL(); + udp_send: + if(uip_slen == 0) { + goto drop; + } + uip_len = uip_slen + UIP_IPUDPH_LEN; + +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = (uip_len >> 8); + BUF->len[1] = (uip_len & 0xff); +#endif /* UIP_CONF_IPV6 */ + + BUF->ttl = uip_udp_conn->ttl; + BUF->proto = UIP_PROTO_UDP; + + UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); + UDPBUF->udpchksum = 0; + + BUF->srcport = uip_udp_conn->lport; + BUF->destport = uip_udp_conn->rport; + + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); + + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; + +#if UIP_UDP_CHECKSUMS + /* Calculate UDP checksum. */ + UDPBUF->udpchksum = ~(uip_udpchksum()); + if(UDPBUF->udpchksum == 0) { + UDPBUF->udpchksum = 0xffff; + } +#endif /* UIP_UDP_CHECKSUMS */ + + goto ip_send_nolen; +#endif /* UIP_UDP */ + + /* TCP input processing. */ + tcp_input: + UIP_STAT(++uip_stat.tcp.recv); + + /* Start of TCP input header processing code. */ + + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP + checksum. */ + UIP_STAT(++uip_stat.tcp.drop); + UIP_STAT(++uip_stat.tcp.chkerr); + UIP_LOG("tcp: bad checksum."); + goto drop; + } + + + /* Demultiplex this segment. */ + /* First check any active connections. */ + for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; + ++uip_connr) { + if(uip_connr->tcpstateflags != UIP_CLOSED && + BUF->destport == uip_connr->lport && + BUF->srcport == uip_connr->rport && + uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { + goto found; + } + } + + /* If we didn't find and active connection that expected the packet, + either this packet is an old duplicate, or this is a SYN packet + destined for a connection in LISTEN. If the SYN flag isn't set, + it is an old packet and we send a RST. */ + if((BUF->flags & TCP_CTL) != TCP_SYN) { + goto reset; + } + + tmp16 = BUF->destport; + /* Next, check listening connections. */ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(tmp16 == uip_listenports[c]) + goto found_listen; + } + + /* No matching connection found, so we send a RST packet. */ + UIP_STAT(++uip_stat.tcp.synrst); + reset: + + /* We do not send resets in response to resets. */ + if(BUF->flags & TCP_RST) { + goto drop; + } + + UIP_STAT(++uip_stat.tcp.rst); + + BUF->flags = TCP_RST | TCP_ACK; + uip_len = UIP_IPTCPH_LEN; + BUF->tcpoffset = 5 << 4; + + /* Flip the seqno and ackno fields in the TCP header. */ + c = BUF->seqno[3]; + BUF->seqno[3] = BUF->ackno[3]; + BUF->ackno[3] = c; + + c = BUF->seqno[2]; + BUF->seqno[2] = BUF->ackno[2]; + BUF->ackno[2] = c; + + c = BUF->seqno[1]; + BUF->seqno[1] = BUF->ackno[1]; + BUF->ackno[1] = c; + + c = BUF->seqno[0]; + BUF->seqno[0] = BUF->ackno[0]; + BUF->ackno[0] = c; + + /* We also have to increase the sequence number we are + acknowledging. If the least significant byte overflowed, we need + to propagate the carry to the other bytes as well. */ + if(++BUF->ackno[3] == 0) { + if(++BUF->ackno[2] == 0) { + if(++BUF->ackno[1] == 0) { + ++BUF->ackno[0]; + } + } + } + + /* Swap port numbers. */ + tmp16 = BUF->srcport; + BUF->srcport = BUF->destport; + BUF->destport = tmp16; + + /* Swap IP addresses. */ + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + + /* And send out the RST packet! */ + goto tcp_send_noconn; + + /* This label will be jumped to if we matched the incoming packet + with a connection in LISTEN. In that case, we should create a new + connection and send a SYNACK in return. */ + found_listen: + /* First we check if there are any connections avaliable. Unused + connections are kept in the same table as used connections, but + unused ones have the tcpstate set to CLOSED. Also, connections in + TIME_WAIT are kept track of and we'll use the oldest one if no + CLOSED connections are found. Thanks to Eddie C. Dost for a very + nice algorithm for the TIME_WAIT search. */ + uip_connr = 0; + for(c = 0; c < UIP_CONNS; ++c) { + if(uip_conns[c].tcpstateflags == UIP_CLOSED) { + uip_connr = &uip_conns[c]; + break; + } + if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { + if(uip_connr == 0 || + uip_conns[c].timer > uip_connr->timer) { + uip_connr = &uip_conns[c]; + } + } + } + + if(uip_connr == 0) { + /* All connections are used already, we drop packet and hope that + the remote end will retransmit the packet at a time when we + have more spare connections. */ + UIP_STAT(++uip_stat.tcp.syndrop); + UIP_LOG("tcp: found no unused connections."); + goto drop; + } + uip_conn = uip_connr; + + /* Fill in the necessary fields for the new connection. */ + uip_connr->rto = uip_connr->timer = UIP_RTO; + uip_connr->sa = 0; + uip_connr->sv = 4; + uip_connr->nrtx = 0; + uip_connr->lport = BUF->destport; + uip_connr->rport = BUF->srcport; + uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); + uip_connr->tcpstateflags = UIP_SYN_RCVD; + + uip_connr->snd_nxt[0] = iss[0]; + uip_connr->snd_nxt[1] = iss[1]; + uip_connr->snd_nxt[2] = iss[2]; + uip_connr->snd_nxt[3] = iss[3]; + uip_connr->len = 1; + + /* rcv_nxt should be the seqno from the incoming packet + 1. */ + uip_connr->rcv_nxt[3] = BUF->seqno[3]; + uip_connr->rcv_nxt[2] = BUF->seqno[2]; + uip_connr->rcv_nxt[1] = BUF->seqno[1]; + uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_add_rcv_nxt(1); + + /* Parse the TCP MSS option, if present. */ + if((BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; + uip_connr->initialmss = uip_connr->mss = + tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; + + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily + can skip past them. */ + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed + and we don't process them further. */ + break; + } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + } + } + } + + /* Our response will be a SYNACK. */ +#if UIP_ACTIVE_OPEN + tcp_send_synack: + BUF->flags = TCP_ACK; + + tcp_send_syn: + BUF->flags |= TCP_SYN; +#else /* UIP_ACTIVE_OPEN */ + tcp_send_synack: + BUF->flags = TCP_SYN | TCP_ACK; +#endif /* UIP_ACTIVE_OPEN */ + + /* We send out the TCP Maximum Segment Size option with our + SYNACK. */ + BUF->optdata[0] = TCP_OPT_MSS; + BUF->optdata[1] = TCP_OPT_MSS_LEN; + BUF->optdata[2] = (UIP_TCP_MSS) / 256; + BUF->optdata[3] = (UIP_TCP_MSS) & 255; + uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; + BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; + goto tcp_send; + + /* This label will be jumped to if we found an active connection. */ + found: + uip_conn = uip_connr; + uip_flags = 0; + /* We do a very naive form of TCP reset processing; we just accept + any RST and kill our connection. We should in fact check if the + sequence number of this reset is wihtin our advertised window + before we accept the reset. */ + if(BUF->flags & TCP_RST) { + uip_connr->tcpstateflags = UIP_CLOSED; + UIP_LOG("tcp: got reset, aborting connection."); + uip_flags = UIP_ABORT; + UIP_APPCALL(); + goto drop; + } + /* Calculated the length of the data, if the application has sent + any data to us. */ + c = (BUF->tcpoffset >> 4) << 2; + /* uip_len will contain the length of the actual TCP data. This is + calculated by subtracing the length of the TCP header (in + c) and the length of the IP header (20 bytes). */ + uip_len = uip_len - c - UIP_IPH_LEN; + + /* First, check if the sequence number of the incoming packet is + what we're expecting next. If not, we send out an ACK with the + correct numbers in. */ + if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && + ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { + if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && + (BUF->seqno[0] != uip_connr->rcv_nxt[0] || + BUF->seqno[1] != uip_connr->rcv_nxt[1] || + BUF->seqno[2] != uip_connr->rcv_nxt[2] || + BUF->seqno[3] != uip_connr->rcv_nxt[3])) { + goto tcp_send_ack; + } + } + + /* Next, check if the incoming segment acknowledges any outstanding + data. If so, we update the sequence number, reset the length of + the outstanding data, calculate RTT estimations, and reset the + retransmission timer. */ + if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { + uip_add32(uip_connr->snd_nxt, uip_connr->len); + + if(BUF->ackno[0] == uip_acc32[0] && + BUF->ackno[1] == uip_acc32[1] && + BUF->ackno[2] == uip_acc32[2] && + BUF->ackno[3] == uip_acc32[3]) { + /* Update sequence number. */ + uip_connr->snd_nxt[0] = uip_acc32[0]; + uip_connr->snd_nxt[1] = uip_acc32[1]; + uip_connr->snd_nxt[2] = uip_acc32[2]; + uip_connr->snd_nxt[3] = uip_acc32[3]; + + + /* Do RTT estimation, unless we have done retransmissions. */ + if(uip_connr->nrtx == 0) { + signed char m; + m = uip_connr->rto - uip_connr->timer; + /* This is taken directly from VJs original code in his paper */ + m = m - (uip_connr->sa >> 3); + uip_connr->sa += m; + if(m < 0) { + m = -m; + } + m = m - (uip_connr->sv >> 2); + uip_connr->sv += m; + uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; + + } + /* Set the acknowledged flag. */ + uip_flags = UIP_ACKDATA; + /* Reset the retransmission timer. */ + uip_connr->timer = uip_connr->rto; + + /* Reset length of outstanding data. */ + uip_connr->len = 0; + } + + } + + /* Do different things depending on in what state the connection is. */ + switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not + implemented, since we force the application to close when the + peer sends a FIN (hence the application goes directly from + ESTABLISHED to LAST_ACK). */ + case UIP_SYN_RCVD: + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and + we are waiting for an ACK that acknowledges the data we sent + out the last time. Therefore, we want to have the UIP_ACKDATA + flag set. If so, we enter the ESTABLISHED state. */ + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_flags = UIP_CONNECTED; + uip_connr->len = 0; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + goto drop; +#if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In SYN_SENT, we wait for a SYNACK that is sent in response to + our SYN. The rcv_nxt is set to sequence number in the SYNACK + plus one, and we send an ACK. We move into the ESTABLISHED + state. */ + if((uip_flags & UIP_ACKDATA) && + (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { + + /* Parse the TCP MSS option, if present. */ + if((BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; + uip_connr->initialmss = + uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; + + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily + can skip past them. */ + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed + and we don't process them further. */ + break; + } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + } + } + } + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_connr->rcv_nxt[1] = BUF->seqno[1]; + uip_connr->rcv_nxt[2] = BUF->seqno[2]; + uip_connr->rcv_nxt[3] = BUF->seqno[3]; + uip_add_rcv_nxt(1); + uip_flags = UIP_CONNECTED | UIP_NEWDATA; + uip_connr->len = 0; + uip_len = 0; + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; + UIP_APPCALL(); + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; + goto reset; +#endif /* UIP_ACTIVE_OPEN */ + + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application to feed + data into the uip_buf. If the UIP_ACKDATA flag is set, the + application should put new data into the buffer, otherwise we are + retransmitting an old segment, and the application should put that + data into the buffer. + + If the incoming packet is a FIN, we should close the connection on + this side as well, and we send out a FIN and enter the LAST_ACK + state. We require that there is no outstanding data; otherwise the + sequence numbers will be screwed up. */ + + if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + if(uip_outstanding(uip_connr)) { + goto drop; + } + uip_add_rcv_nxt(1 + uip_len); + uip_flags |= UIP_CLOSE; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + } + UIP_APPCALL(); + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_LAST_ACK; + uip_connr->nrtx = 0; + tcp_send_finack: + BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } + + /* Check the URG flag. If this is set, the segment carries urgent + data that we must pass to the application. */ + if((BUF->flags & TCP_URG) != 0) { +#if UIP_URGDATA > 0 + uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; + if(uip_urglen > uip_len) { + /* There is more urgent data in the next segment to come. */ + uip_urglen = uip_len; + } + uip_add_rcv_nxt(uip_urglen); + uip_len -= uip_urglen; + uip_urgdata = uip_appdata; + uip_appdata += uip_urglen; + } else { + uip_urglen = 0; +#else /* UIP_URGDATA > 0 */ + uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); + uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; +#endif /* UIP_URGDATA > 0 */ + } + + /* If uip_len > 0 we have TCP data in the packet, and we flag this + by setting the UIP_NEWDATA flag and update the sequence number + we acknowledge. If the application has stopped the dataflow + using uip_stop(), we must not accept any data packets from the + remote host. */ + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } + + /* Check if the available buffer space advertised by the other end + is smaller than the initial MSS for this connection. If so, we + set the current MSS to the window size to ensure that the + application does not send more data than the other end can + handle. + + If the remote host advertises a zero window, we set the MSS to + the initial MSS so that the application will send an entire MSS + of data. This data will not be acknowledged by the receiver, + and the application will retransmit it. This is called the + "persistent timer" and uses the retransmission mechanim. + */ + tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; + if(tmp16 > uip_connr->initialmss || + tmp16 == 0) { + tmp16 = uip_connr->initialmss; + } + uip_connr->mss = tmp16; + + /* If this packet constitutes an ACK for outstanding data (flagged + by the UIP_ACKDATA flag, we should call the application since it + might want to send more data. If the incoming packet had data + from the peer (as flagged by the UIP_NEWDATA flag), the + application must also be notified. + + When the application is called, the global variable uip_len + contains the length of the incoming data. The application can + access the incoming data through the global pointer + uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN + bytes into the uip_buf array. + + If the application wishes to send any data, this data should be + put into the uip_appdata and the length of the data should be + put into uip_len. If the application don't have any data to + send, uip_len must be set to 0. */ + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { + uip_slen = 0; + UIP_APPCALL(); + + appsend: + + if(uip_flags & UIP_ABORT) { + uip_slen = 0; + uip_connr->tcpstateflags = UIP_CLOSED; + BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } + + if(uip_flags & UIP_CLOSE) { + uip_slen = 0; + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_FIN_WAIT_1; + uip_connr->nrtx = 0; + BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } + + /* If uip_slen > 0, the application has data to be sent. */ + if(uip_slen > 0) { + + /* If the connection has acknowledged data, the contents of + the ->len variable should be discarded. */ + if((uip_flags & UIP_ACKDATA) != 0) { + uip_connr->len = 0; + } + + /* If the ->len variable is non-zero the connection has + already data in transit and cannot send anymore right + now. */ + if(uip_connr->len == 0) { + + /* The application cannot send more than what is allowed by + the mss (the minumum of the MSS and the available + window). */ + if(uip_slen > uip_connr->mss) { + uip_slen = uip_connr->mss; + } + + /* Remember how much data we send out now so that we know + when everything has been acknowledged. */ + uip_connr->len = uip_slen; + } else { + + /* If the application already had unacknowledged data, we + make sure that the application does not send (i.e., + retransmit) out more than it previously sent out. */ + uip_slen = uip_connr->len; + } + } + uip_connr->nrtx = 0; + apprexmit: + uip_appdata = uip_sappdata; + + /* If the application has data to be sent, or if the incoming + packet had new data in it, we must send out a packet. */ + if(uip_slen > 0 && uip_connr->len > 0) { + /* Add the length of the IP and TCP headers. */ + uip_len = uip_connr->len + UIP_TCPIP_HLEN; + /* We always set the ACK flag in response packets. */ + BUF->flags = TCP_ACK | TCP_PSH; + /* Send the packet. */ + goto tcp_send_noopts; + } + /* If there is no data to send, just send out a pure ACK if + there is newdata. */ + if(uip_flags & UIP_NEWDATA) { + uip_len = UIP_TCPIP_HLEN; + BUF->flags = TCP_ACK; + goto tcp_send_noopts; + } + } + goto drop; + case UIP_LAST_ACK: + /* We can close this connection if the peer has acknowledged our + FIN. This is indicated by the UIP_ACKDATA flag. */ + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_CLOSED; + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + } + break; + + case UIP_FIN_WAIT_1: + /* The application has closed the connection, but the remote host + hasn't closed its end yet. Thus we do nothing but wait for a + FIN from the other side. */ + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(BUF->flags & TCP_FIN) { + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_connr->len = 0; + } else { + uip_connr->tcpstateflags = UIP_CLOSING; + } + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } else if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_FIN_WAIT_2; + uip_connr->len = 0; + goto drop; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_FIN_WAIT_2: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(BUF->flags & TCP_FIN) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_TIME_WAIT: + goto tcp_send_ack; + + case UIP_CLOSING: + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + } + } + goto drop; + + + /* We jump here when we are ready to send the packet, and just want + to set the appropriate TCP sequence numbers in the TCP header. */ + tcp_send_ack: + BUF->flags = TCP_ACK; + tcp_send_nodata: + uip_len = UIP_IPTCPH_LEN; + tcp_send_noopts: + BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; + tcp_send: + /* We're done with the input processing. We are now ready to send a + reply. Our job is to fill in all the fields of the TCP and IP + headers before calculating the checksum and finally send the + packet. */ + BUF->ackno[0] = uip_connr->rcv_nxt[0]; + BUF->ackno[1] = uip_connr->rcv_nxt[1]; + BUF->ackno[2] = uip_connr->rcv_nxt[2]; + BUF->ackno[3] = uip_connr->rcv_nxt[3]; + + BUF->seqno[0] = uip_connr->snd_nxt[0]; + BUF->seqno[1] = uip_connr->snd_nxt[1]; + BUF->seqno[2] = uip_connr->snd_nxt[2]; + BUF->seqno[3] = uip_connr->snd_nxt[3]; + + BUF->proto = UIP_PROTO_TCP; + + BUF->srcport = uip_connr->lport; + BUF->destport = uip_connr->rport; + + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); + + if(uip_connr->tcpstateflags & UIP_STOPPED) { + /* If the connection has issued uip_stop(), we advertise a zero + window so that the remote host will stop sending data. */ + BUF->wnd[0] = BUF->wnd[1] = 0; + } else { + BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); + } + + tcp_send_noconn: + BUF->ttl = UIP_TTL; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = (uip_len >> 8); + BUF->len[1] = (uip_len & 0xff); +#endif /* UIP_CONF_IPV6 */ + + BUF->urgp[0] = BUF->urgp[1] = 0; + + /* Calculate TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + + ip_send_nolen: + +#if UIP_CONF_IPV6 + BUF->vtc = 0x60; + BUF->tcflow = 0x00; + BUF->flow = 0x00; +#else /* UIP_CONF_IPV6 */ + BUF->vhl = 0x45; + BUF->tos = 0; + BUF->ipoffset[0] = BUF->ipoffset[1] = 0; + ++ipid; + BUF->ipid[0] = ipid >> 8; + BUF->ipid[1] = ipid & 0xff; + /* Calculate IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); + DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + UIP_STAT(++uip_stat.tcp.sent); + send: + DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, + (BUF->len[0] << 8) | BUF->len[1]); + + UIP_STAT(++uip_stat.ip.sent); + /* Return and let the caller do the actual transmission. */ + uip_flags = 0; + return; + drop: + uip_len = 0; + uip_flags = 0; + return; +} +/*---------------------------------------------------------------------------*/ +u16_t +htons(u16_t val) +{ + return HTONS(val); +} +/*---------------------------------------------------------------------------*/ +void +uip_send(const void *data, int len) +{ + if(len > 0) { + uip_slen = len; + if(data != uip_sappdata) { + memcpy(uip_sappdata, (data), uip_slen); + } + } +} +/** @} */ diff --git a/bundles/uip/uip/uip.h b/bundles/uip/uip/uip.h new file mode 100644 index 00000000..4216e9b8 --- /dev/null +++ b/bundles/uip/uip/uip.h @@ -0,0 +1,1603 @@ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \file + * Header file for the uIP TCP/IP stack. + * \author Adam Dunkels + * + * The uIP TCP/IP stack header file contains definitions for a number + * of C macros that are used by uIP programs as well as internal uIP + * structures, TCP/IP header structures and function declarations. + * + */ + + +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ + * + */ + +#ifndef __UIP_H__ +#define __UIP_H__ + +#include "uipopt.h" + +/** + * Repressentation of an IP address. + * + */ +typedef u16_t uip_ip4addr_t[2]; +typedef u16_t uip_ip6addr_t[8]; +#if UIP_CONF_IPV6 +typedef uip_ip6addr_t uip_ipaddr_t; +#else /* UIP_CONF_IPV6 */ +typedef uip_ip4addr_t uip_ipaddr_t; +#endif /* UIP_CONF_IPV6 */ + +/*---------------------------------------------------------------------------*/ +/* First, the functions that should be called from the + * system. Initialization, the periodic timer and incoming packets are + * handled by the following three functions. + */ + +/** + * \defgroup uipconffunc uIP configuration functions + * @{ + * + * The uIP configuration functions are used for setting run-time + * parameters in uIP such as IP addresses. + */ + +/** + * Set the IP address of this host. + * + * The IP address is represented as a 4-byte array where the first + * octet of the IP address is put in the first member of the 4-byte + * array. + * + * Example: + \code + + uip_ipaddr_t addr; + + uip_ipaddr(&addr, 192,168,1,2); + uip_sethostaddr(&addr); + + \endcode + * \param addr A pointer to an IP address of type uip_ipaddr_t; + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) + +/** + * Get the IP address of this host. + * + * The IP address is represented as a 4-byte array where the first + * octet of the IP address is put in the first member of the 4-byte + * array. + * + * Example: + \code + uip_ipaddr_t hostaddr; + + uip_gethostaddr(&hostaddr); + \endcode + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the currently configured IP address. + * + * \hideinitializer + */ +#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) + +/** + * Set the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the default router. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) + +/** + * Set the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the netmask. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) + + +/** + * Get the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address of the default router. + * + * \hideinitializer + */ +#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) + +/** + * Get the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the value of the netmask. + * + * \hideinitializer + */ +#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) + +/** @} */ + +/** + * \defgroup uipinit uIP initialization functions + * @{ + * + * The uIP initialization functions are used for booting uIP. + */ + +/** + * uIP initialization function. + * + * This function should be called at boot up to initilize the uIP + * TCP/IP stack. + */ +void uip_init(void); + +/** + * uIP initialization function. + * + * This function may be used at boot time to set the initial ip_id. + */ +void uip_setipid(u16_t id); + +/** @} */ + +/** + * \defgroup uipdevfunc uIP device driver functions + * @{ + * + * These functions are used by a network device driver for interacting + * with uIP. + */ + +/** + * Process an incoming packet. + * + * This function should be called when the device driver has received + * a packet from the network. The packet from the device driver must + * be present in the uip_buf buffer, and the length of the packet + * should be placed in the uip_len variable. + * + * When the function returns, there may be an outbound packet placed + * in the uip_buf packet buffer. If so, the uip_len variable is set to + * the length of the packet. If no packet is to be sent out, the + * uip_len variable is set to 0. + * + * The usual way of calling the function is presented by the source + * code below. + \code + uip_len = devicedriver_poll(); + if(uip_len > 0) { + uip_input(); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note If you are writing a uIP device driver that needs ARP + * (Address Resolution Protocol), e.g., when running uIP over + * Ethernet, you will need to call the uIP ARP code before calling + * this function: + \code + #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + uip_len = ethernet_devicedrver_poll(); + if(uip_len > 0) { + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if(uip_len > 0) { + ethernet_devicedriver_send(); + } + } + \endcode + * + * \hideinitializer + */ +#define uip_input() uip_process(UIP_DATA) + +/** + * Periodic processing for a connection identified by its number. + * + * This function does the necessary periodic processing (timers, + * polling) for a uIP TCP conneciton, and should be called when the + * periodic uIP timer goes off. It should be called for every + * connection, regardless of whether they are open of closed. + * + * When the function returns, it may have an outbound packet waiting + * for service in the uIP packet buffer, and if so the uip_len + * variable is set to a value larger than zero. The device driver + * should be called to send out the packet. + * + * The ususal way of calling the function is through a for() loop like + * this: + \code + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note If you are writing a uIP device driver that needs ARP + * (Address Resolution Protocol), e.g., when running uIP over + * Ethernet, you will need to call the uip_arp_out() function before + * calling the device driver: + \code + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } + \endcode + * + * \param conn The number of the connection which is to be periodically polled. + * + * \hideinitializer + */ +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ + uip_process(UIP_TIMER); } while (0) + +/** + * + * + */ +#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) + +/** + * Perform periodic processing for a connection identified by a pointer + * to its structure. + * + * Same as uip_periodic() but takes a pointer to the actual uip_conn + * struct instead of an integer as its argument. This function can be + * used to force periodic processing of a specific connection. + * + * \param conn A pointer to the uip_conn struct for the connection to + * be processed. + * + * \hideinitializer + */ +#define uip_periodic_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_TIMER); } while (0) + +/** + * Reuqest that a particular connection should be polled. + * + * Similar to uip_periodic_conn() but does not perform any timer + * processing. The application is polled for new data. + * + * \param conn A pointer to the uip_conn struct for the connection to + * be processed. + * + * \hideinitializer + */ +#define uip_poll_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_POLL_REQUEST); } while (0) + + +#if UIP_UDP +/** + * Periodic processing for a UDP connection identified by its number. + * + * This function is essentially the same as uip_periodic(), but for + * UDP connections. It is called in a similar fashion as the + * uip_periodic() function: + \code + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note As for the uip_periodic() function, special care has to be + * taken when using uIP together with ARP and Ethernet: + \code + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } + \endcode + * + * \param conn The number of the UDP connection to be processed. + * + * \hideinitializer + */ +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ + uip_process(UIP_UDP_TIMER); } while (0) + +/** + * Periodic processing for a UDP connection identified by a pointer to + * its structure. + * + * Same as uip_udp_periodic() but takes a pointer to the actual + * uip_conn struct instead of an integer as its argument. This + * function can be used to force periodic processing of a specific + * connection. + * + * \param conn A pointer to the uip_udp_conn struct for the connection + * to be processed. + * + * \hideinitializer + */ +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ + uip_process(UIP_UDP_TIMER); } while (0) + + +#endif /* UIP_UDP */ + +/** + * The uIP packet buffer. + * + * The uip_buf array is used to hold incoming and outgoing + * packets. The device driver should place incoming data into this + * buffer. When sending data, the device driver should read the link + * level headers and the TCP/IP headers from this buffer. The size of + * the link level headers is configured by the UIP_LLH_LEN define. + * + * \note The application data need not be placed in this buffer, so + * the device driver must read it from the place pointed to by the + * uip_appdata pointer as illustrated by the following example: + \code + void + devicedriver_send(void) + { + hwsend(&uip_buf[0], UIP_LLH_LEN); + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); + } else { + hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); + hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); + } + } + \endcode + */ +#ifndef UIP_CONF_EXTERNAL_BUFFER +extern u8_t uip_buf[UIP_BUFSIZE+2]; +#endif /* UIP_CONF_EXTERNAL_BUFFER */ + +/** @} */ + +/*---------------------------------------------------------------------------*/ +/* Functions that are used by the uIP application program. Opening and + * closing connections, sending and receiving data, etc. is all + * handled by the functions below. +*/ +/** + * \defgroup uipappfunc uIP application functions + * @{ + * + * Functions used by an application running of top of uIP. + */ + +/** + * Start listening to the specified port. + * + * \note Since this function expects the port number in network byte + * order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_listen(HTONS(80)); + \endcode + * + * \param port A 16-bit port number in network byte order. + */ +void uip_listen(u16_t port); + +/** + * Stop listening to the specified port. + * + * \note Since this function expects the port number in network byte + * order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_unlisten(HTONS(80)); + \endcode + * + * \param port A 16-bit port number in network byte order. + */ +void uip_unlisten(u16_t port); + +/** + * Connect to a remote host using TCP. + * + * This function is used to start a new connection to the specified + * port on the specied host. It allocates a new connection identifier, + * sets the connection to the SYN_SENT state and sets the + * retransmission timer to 0. This will cause a TCP SYN segment to be + * sent out the next time this connection is periodically processed, + * which usually is done within 0.5 seconds after the call to + * uip_connect(). + * + * \note This function is avaliable only if support for active open + * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. + * + * \note Since this function requires the port number to be in network + * byte order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_ipaddr_t ipaddr; + + uip_ipaddr(&ipaddr, 192,168,1,2); + uip_connect(&ipaddr, HTONS(80)); + \endcode + * + * \param ripaddr The IP address of the remote hot. + * + * \param port A 16-bit port number in network byte order. + * + * \return A pointer to the uIP connection identifier for the new connection, + * or NULL if no connection could be allocated. + * + */ +struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); + + + +/** + * \internal + * + * Check if a connection has outstanding (i.e., unacknowledged) data. + * + * \param conn A pointer to the uip_conn structure for the connection. + * + * \hideinitializer + */ +#define uip_outstanding(conn) ((conn)->len) + +/** + * Send data on the current connection. + * + * This function is used to send out a single segment of TCP + * data. Only applications that have been invoked by uIP for event + * processing can send data. + * + * The amount of data that actually is sent out after a call to this + * funcion is determined by the maximum amount of data TCP allows. uIP + * will automatically crop the data so that only the appropriate + * amount of data is sent. The function uip_mss() can be used to query + * uIP for the amount of data that actually will be sent. + * + * \note This function does not guarantee that the sent data will + * arrive at the destination. If the data is lost in the network, the + * application will be invoked with the uip_rexmit() event being + * set. The application will then have to resend the data using this + * function. + * + * \param data A pointer to the data which is to be sent. + * + * \param len The maximum amount of data bytes to be sent. + * + * \hideinitializer + */ +void uip_send(const void *data, int len); + +/** + * The length of any incoming data that is currently avaliable (if avaliable) + * in the uip_appdata buffer. + * + * The test function uip_data() must first be used to check if there + * is any data available at all. + * + * \hideinitializer + */ +/*void uip_datalen(void);*/ +#define uip_datalen() uip_len + +/** + * The length of any out-of-band data (urgent data) that has arrived + * on the connection. + * + * \note The configuration parameter UIP_URGDATA must be set for this + * function to be enabled. + * + * \hideinitializer + */ +#define uip_urgdatalen() uip_urglen + +/** + * Close the current connection. + * + * This function will close the current connection in a nice way. + * + * \hideinitializer + */ +#define uip_close() (uip_flags = UIP_CLOSE) + +/** + * Abort the current connection. + * + * This function will abort (reset) the current connection, and is + * usually used when an error has occured that prevents using the + * uip_close() function. + * + * \hideinitializer + */ +#define uip_abort() (uip_flags = UIP_ABORT) + +/** + * Tell the sending host to stop sending data. + * + * This function will close our receiver's window so that we stop + * receiving data for the current connection. + * + * \hideinitializer + */ +#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) + +/** + * Find out if the current connection has been previously stopped with + * uip_stop(). + * + * \hideinitializer + */ +#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) + +/** + * Restart the current connection, if is has previously been stopped + * with uip_stop(). + * + * This function will open the receiver's window again so that we + * start receiving data for the current connection. + * + * \hideinitializer + */ +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ + uip_conn->tcpstateflags &= ~UIP_STOPPED; \ + } while(0) + + +/* uIP tests that can be made to determine in what state the current + connection is, and what the application function should do. */ + +/** + * Is the current connection a UDP connection? + * + * This function checks whether the current connection is a UDP connection. + * + * \hideinitializer + * + */ +#define uip_udpconnection() (uip_conn == NULL) + +/** + * Is new incoming data available? + * + * Will reduce to non-zero if there is new data for the application + * present at the uip_appdata pointer. The size of the data is + * avaliable through the uip_len variable. + * + * \hideinitializer + */ +#define uip_newdata() (uip_flags & UIP_NEWDATA) + +/** + * Has previously sent data been acknowledged? + * + * Will reduce to non-zero if the previously sent data has been + * acknowledged by the remote host. This means that the application + * can send new data. + * + * \hideinitializer + */ +#define uip_acked() (uip_flags & UIP_ACKDATA) + +/** + * Has the connection just been connected? + * + * Reduces to non-zero if the current connection has been connected to + * a remote host. This will happen both if the connection has been + * actively opened (with uip_connect()) or passively opened (with + * uip_listen()). + * + * \hideinitializer + */ +#define uip_connected() (uip_flags & UIP_CONNECTED) + +/** + * Has the connection been closed by the other end? + * + * Is non-zero if the connection has been closed by the remote + * host. The application may then do the necessary clean-ups. + * + * \hideinitializer + */ +#define uip_closed() (uip_flags & UIP_CLOSE) + +/** + * Has the connection been aborted by the other end? + * + * Non-zero if the current connection has been aborted (reset) by the + * remote host. + * + * \hideinitializer + */ +#define uip_aborted() (uip_flags & UIP_ABORT) + +/** + * Has the connection timed out? + * + * Non-zero if the current connection has been aborted due to too many + * retransmissions. + * + * \hideinitializer + */ +#define uip_timedout() (uip_flags & UIP_TIMEDOUT) + +/** + * Do we need to retransmit previously data? + * + * Reduces to non-zero if the previously sent data has been lost in + * the network, and the application should retransmit it. The + * application should send the exact same data as it did the last + * time, using the uip_send() function. + * + * \hideinitializer + */ +#define uip_rexmit() (uip_flags & UIP_REXMIT) + +/** + * Is the connection being polled by uIP? + * + * Is non-zero if the reason the application is invoked is that the + * current connection has been idle for a while and should be + * polled. + * + * The polling event can be used for sending data without having to + * wait for the remote host to send data. + * + * \hideinitializer + */ +#define uip_poll() (uip_flags & UIP_POLL) + +/** + * Get the initial maxium segment size (MSS) of the current + * connection. + * + * \hideinitializer + */ +#define uip_initialmss() (uip_conn->initialmss) + +/** + * Get the current maxium segment size that can be sent on the current + * connection. + * + * The current maxiumum segment size that can be sent on the + * connection is computed from the receiver's window and the MSS of + * the connection (which also is available by calling + * uip_initialmss()). + * + * \hideinitializer + */ +#define uip_mss() (uip_conn->mss) + +/** + * Set up a new UDP connection. + * + * This function sets up a new UDP connection. The function will + * automatically allocate an unused local port for the new + * connection. However, another port can be chosen by using the + * uip_udp_bind() call, after the uip_udp_new() function has been + * called. + * + * Example: + \code + uip_ipaddr_t addr; + struct uip_udp_conn *c; + + uip_ipaddr(&addr, 192,168,2,1); + c = uip_udp_new(&addr, HTONS(12345)); + if(c != NULL) { + uip_udp_bind(c, HTONS(12344)); + } + \endcode + * \param ripaddr The IP address of the remote host. + * + * \param rport The remote port number in network byte order. + * + * \return The uip_udp_conn structure for the new connection or NULL + * if no connection could be allocated. + */ +struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); + +/** + * Removed a UDP connection. + * + * \param conn A pointer to the uip_udp_conn structure for the connection. + * + * \hideinitializer + */ +#define uip_udp_remove(conn) (conn)->lport = 0 + +/** + * Bind a UDP connection to a local port. + * + * \param conn A pointer to the uip_udp_conn structure for the + * connection. + * + * \param port The local port number, in network byte order. + * + * \hideinitializer + */ +#define uip_udp_bind(conn, port) (conn)->lport = port + +/** + * Send a UDP datagram of length len on the current connection. + * + * This function can only be called in response to a UDP event (poll + * or newdata). The data must be present in the uip_buf buffer, at the + * place pointed to by the uip_appdata pointer. + * + * \param len The length of the data in the uip_buf buffer. + * + * \hideinitializer + */ +#define uip_udp_send(len) uip_send((char *)uip_appdata, len) + +/** @} */ + +/* uIP convenience and converting functions. */ + +/** + * \defgroup uipconvfunc uIP conversion functions + * @{ + * + * These functions can be used for converting between different data + * formats used by uIP. + */ + +/** + * Construct an IP address from four bytes. + * + * This function constructs an IP address of the type that uIP handles + * internally from four bytes. The function is handy for specifying IP + * addresses to use with e.g. the uip_connect() function. + * + * Example: + \code + uip_ipaddr_t ipaddr; + struct uip_conn *c; + + uip_ipaddr(&ipaddr, 192,168,1,2); + c = uip_connect(&ipaddr, HTONS(80)); + \endcode + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address. + * + * \param addr0 The first octet of the IP address. + * \param addr1 The second octet of the IP address. + * \param addr2 The third octet of the IP address. + * \param addr3 The forth octet of the IP address. + * + * \hideinitializer + */ +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ + ((u16_t *)(addr))[0] = htons(((addr0) << 8) | (addr1)); \ + ((u16_t *)(addr))[1] = htons(((addr2) << 8) | (addr3)); \ + } while(0) + +/** + * Construct an IPv6 address from eight 16-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ + ((u16_t *)(addr))[0] = HTONS((addr0)); \ + ((u16_t *)(addr))[1] = HTONS((addr1)); \ + ((u16_t *)(addr))[2] = HTONS((addr2)); \ + ((u16_t *)(addr))[3] = HTONS((addr3)); \ + ((u16_t *)(addr))[4] = HTONS((addr4)); \ + ((u16_t *)(addr))[5] = HTONS((addr5)); \ + ((u16_t *)(addr))[6] = HTONS((addr6)); \ + ((u16_t *)(addr))[7] = HTONS((addr7)); \ + } while(0) + +/** + * Copy an IP address to another IP address. + * + * Copies an IP address from one place to another. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr_copy(&ipaddr2, &ipaddr1); + \endcode + * + * \param dest The destination for the copy. + * \param src The source from where to copy. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_copy(dest, src) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ + } while(0) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses + * + * Compares two IP addresses. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ + ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses with netmasks + * + * Compares two IP addresses with netmasks. The masks are used to mask + * out the bits that are to be compared. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, mask; + + uip_ipaddr(&mask, 255,255,255,0); + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&ipaddr2, 192,16,1,3); + if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ + (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ + (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ + ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ + (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) + + +/** + * Mask out the network part of an IP address. + * + * Masks out the network part of an IP address, given the address and + * the netmask. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, netmask; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&netmask, 255,255,255,0); + uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); + \endcode + * + * In the example above, the variable "ipaddr2" will contain the IP + * address 192.168.1.0. + * + * \param dest Where the result is to be placed. + * \param src The IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_mask(dest, src, mask) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ + } while(0) + +/** + * Pick the first octet of an IP address. + * + * Picks out the first octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr1(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 1. + * + * \hideinitializer + */ +#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) + +/** + * Pick the second octet of an IP address. + * + * Picks out the second octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr2(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 2. + * + * \hideinitializer + */ +#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) + +/** + * Pick the third octet of an IP address. + * + * Picks out the third octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr3(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 3. + * + * \hideinitializer + */ +#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) + +/** + * Pick the fourth octet of an IP address. + * + * Picks out the fourth octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr4(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 4. + * + * \hideinitializer + */ +#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) + +/** + * Convert 16-bit quantity from host byte order to network byte order. + * + * This macro is primarily used for converting constants from host + * byte order to network byte order. For converting variables to + * network byte order, use the htons() function instead. + * + * \hideinitializer + */ +#ifndef HTONS +# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN +# define HTONS(n) (n) +# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +#else +#error "HTONS already defined!" +#endif /* HTONS */ + +/** + * Convert 16-bit quantity from host byte order to network byte order. + * + * This function is primarily used for converting variables from host + * byte order to network byte order. For converting constants to + * network byte order, use the HTONS() macro instead. + */ +#ifndef htons +u16_t htons(u16_t val); +#endif /* htons */ +#ifndef ntohs +#define ntohs htons +#endif + +/** @} */ + +/** + * Pointer to the application data in the packet buffer. + * + * This pointer points to the application data when the application is + * called. If the application wishes to send data, the application may + * use this space to write the data into before calling uip_send(). + */ +extern void *uip_appdata; + +#if UIP_URGDATA > 0 +/* u8_t *uip_urgdata: + * + * This pointer points to any urgent data that has been received. Only + * present if compiled with support for urgent data (UIP_URGDATA). + */ +extern void *uip_urgdata; +#endif /* UIP_URGDATA > 0 */ + + +/** + * \defgroup uipdrivervars Variables used in uIP device drivers + * @{ + * + * uIP has a few global variables that are used in device drivers for + * uIP. + */ + +/** + * The length of the packet in the uip_buf buffer. + * + * The global variable uip_len holds the length of the packet in the + * uip_buf buffer. + * + * When the network device driver calls the uIP input function, + * uip_len should be set to the length of the packet in the uip_buf + * buffer. + * + * When sending packets, the device driver should use the contents of + * the uip_len variable to determine the length of the outgoing + * packet. + * + */ +extern u16_t uip_len; + +/** @} */ + +#if UIP_URGDATA > 0 +extern u16_t uip_urglen, uip_surglen; +#endif /* UIP_URGDATA > 0 */ + + +/** + * Representation of a uIP TCP connection. + * + * The uip_conn structure is used for identifying a connection. All + * but one field in the structure are to be considered read-only by an + * application. The only exception is the appstate field whos purpose + * is to let the application store application-specific state (e.g., + * file pointers) for the connection. The type of this field is + * configured in the "uipopt.h" header file. + */ +struct uip_conn { + uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */ + + u16_t lport; /**< The local TCP port, in network byte order. */ + u16_t rport; /**< The local remote TCP port, in network byte + order. */ + + u8_t rcv_nxt[4]; /**< The sequence number that we expect to + receive next. */ + u8_t snd_nxt[4]; /**< The sequence number that was last sent by + us. */ + u16_t len; /**< Length of the data that was previously sent. */ + u16_t mss; /**< Current maximum segment size for the + connection. */ + u16_t initialmss; /**< Initial maximum segment size for the + connection. */ + u8_t sa; /**< Retransmission time-out calculation state + variable. */ + u8_t sv; /**< Retransmission time-out calculation state + variable. */ + u8_t rto; /**< Retransmission time-out. */ + u8_t tcpstateflags; /**< TCP state and flags. */ + u8_t timer; /**< The retransmission timer. */ + u8_t nrtx; /**< The number of retransmissions for the last + segment sent. */ + + /** The application state. */ + uip_tcp_appstate_t appstate; +}; + + +/** + * Pointer to the current TCP connection. + * + * The uip_conn pointer can be used to access the current TCP + * connection. + */ +extern struct uip_conn *uip_conn; +/* The array containing all uIP connections. */ +extern struct uip_conn uip_conns[UIP_CONNS]; +/** + * \addtogroup uiparch + * @{ + */ + +/** + * 4-byte array used for the 32-bit sequence number calculations. + */ +extern u8_t uip_acc32[4]; + +/** @} */ + + +#if UIP_UDP +/** + * Representation of a uIP UDP connection. + */ +struct uip_udp_conn { + uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */ + u16_t lport; /**< The local port number in network byte order. */ + u16_t rport; /**< The remote port number in network byte order. */ + u8_t ttl; /**< Default time-to-live. */ + + /** The application state. */ + uip_udp_appstate_t appstate; +}; + +/** + * The current UDP connection. + */ +extern struct uip_udp_conn *uip_udp_conn; +extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; +#endif /* UIP_UDP */ + +/** + * The structure holding the TCP/IP statistics that are gathered if + * UIP_STATISTICS is set to 1. + * + */ +struct uip_stats { + struct { + uip_stats_t drop; /**< Number of dropped packets at the IP + layer. */ + uip_stats_t recv; /**< Number of received packets at the IP + layer. */ + uip_stats_t sent; /**< Number of sent packets at the IP + layer. */ + uip_stats_t vhlerr; /**< Number of packets dropped due to wrong + IP version or header length. */ + uip_stats_t hblenerr; /**< Number of packets dropped due to wrong + IP length, high byte. */ + uip_stats_t lblenerr; /**< Number of packets dropped due to wrong + IP length, low byte. */ + uip_stats_t fragerr; /**< Number of packets dropped since they + were IP fragments. */ + uip_stats_t chkerr; /**< Number of packets dropped due to IP + checksum errors. */ + uip_stats_t protoerr; /**< Number of packets dropped since they + were neither ICMP, UDP nor TCP. */ + } ip; /**< IP statistics. */ + struct { + uip_stats_t drop; /**< Number of dropped ICMP packets. */ + uip_stats_t recv; /**< Number of received ICMP packets. */ + uip_stats_t sent; /**< Number of sent ICMP packets. */ + uip_stats_t typeerr; /**< Number of ICMP packets with a wrong + type. */ + } icmp; /**< ICMP statistics. */ + struct { + uip_stats_t drop; /**< Number of dropped TCP segments. */ + uip_stats_t recv; /**< Number of recived TCP segments. */ + uip_stats_t sent; /**< Number of sent TCP segments. */ + uip_stats_t chkerr; /**< Number of TCP segments with a bad + checksum. */ + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK + number. */ + uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */ + uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ + uip_stats_t syndrop; /**< Number of dropped SYNs due to too few + connections was avaliable. */ + uip_stats_t synrst; /**< Number of SYNs for closed ports, + triggering a RST. */ + } tcp; /**< TCP statistics. */ +#if UIP_UDP + struct { + uip_stats_t drop; /**< Number of dropped UDP segments. */ + uip_stats_t recv; /**< Number of recived UDP segments. */ + uip_stats_t sent; /**< Number of sent UDP segments. */ + uip_stats_t chkerr; /**< Number of UDP segments with a bad + checksum. */ + } udp; /**< UDP statistics. */ +#endif /* UIP_UDP */ +}; + +/** + * The uIP TCP/IP statistics. + * + * This is the variable in which the uIP TCP/IP statistics are gathered. + */ +extern struct uip_stats uip_stat; + + +/*---------------------------------------------------------------------------*/ +/* All the stuff below this point is internal to uIP and should not be + * used directly by an application or by a device driver. + */ +/*---------------------------------------------------------------------------*/ +/* u8_t uip_flags: + * + * When the application is called, uip_flags will contain the flags + * that are defined in this file. Please read below for more + * infomation. + */ +extern u8_t uip_flags; + +/* The following flags may be set in the global variable uip_flags + before calling the application callback. The UIP_ACKDATA, + UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time, + whereas the others are mutualy exclusive. Note that these flags + should *NOT* be accessed directly, but only through the uIP + functions/macros. */ + +#define UIP_ACKDATA 1 /* Signifies that the outstanding data was + acked and the application should send + out new data instead of retransmitting + the last data. */ +#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent + us new data. */ +#define UIP_REXMIT 4 /* Tells the application to retransmit the + data that was last sent. */ +#define UIP_POLL 8 /* Used for polling the application, to + check if the application has data that + it wants to send. */ +#define UIP_CLOSE 16 /* The remote host has closed the + connection, thus the connection has + gone away. Or the application signals + that it wants to close the + connection. */ +#define UIP_ABORT 32 /* The remote host has aborted the + connection, thus the connection has + gone away. Or the application signals + that it wants to abort the + connection. */ +#define UIP_CONNECTED 64 /* We have got a connection from a remote + host and have set up a new connection + for it, or an active connection has + been successfully established. */ + +#define UIP_TIMEDOUT 128 /* The connection has been aborted due to + too many retransmissions. */ + +/* uip_process(flag): + * + * The actual uIP function which does all the work. + */ +void uip_process(u8_t flag); + +/* The following flags are passed as an argument to the uip_process() + function. They are used to distinguish between the two cases where + uip_process() is called. It can be called either because we have + incoming data that should be processed, or because the periodic + timer has fired. These values are never used directly, but only in + the macrose defined in this file. */ + +#define UIP_DATA 1 /* Tells uIP that there is incoming + data in the uip_buf buffer. The + length of the data is stored in the + global variable uip_len. */ +#define UIP_TIMER 2 /* Tells uIP that the periodic timer + has fired. */ +#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should + be polled. */ +#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram + should be constructed in the + uip_buf buffer. */ +#if UIP_UDP +#define UIP_UDP_TIMER 5 +#endif /* UIP_UDP */ + +/* The TCP states used in the uip_conn->tcpstateflags. */ +#define UIP_CLOSED 0 +#define UIP_SYN_RCVD 1 +#define UIP_SYN_SENT 2 +#define UIP_ESTABLISHED 3 +#define UIP_FIN_WAIT_1 4 +#define UIP_FIN_WAIT_2 5 +#define UIP_CLOSING 6 +#define UIP_TIME_WAIT 7 +#define UIP_LAST_ACK 8 +#define UIP_TS_MASK 15 + +#define UIP_STOPPED 16 + +/* The TCP and IP headers. */ +struct uip_tcpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcflow; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* TCP header. */ + u16_t srcport, + destport; + u8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +/* The ICMP and IP headers. */ +struct uip_icmpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* ICMP (echo) header. */ + u8_t type, icode; + u16_t icmpchksum; +#if !UIP_CONF_IPV6 + u16_t id, seqno; +#else /* !UIP_CONF_IPV6 */ + u8_t flags, reserved1, reserved2, reserved3; + u8_t icmp6data[16]; + u8_t options[1]; +#endif /* !UIP_CONF_IPV6 */ +}; + + +/* The UDP and IP headers. */ +struct uip_udpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* UDP header. */ + u16_t srcport, + destport; + u16_t udplen; + u16_t udpchksum; +}; + + + +/** + * The buffer size available for user data in the \ref uip_buf buffer. + * + * This macro holds the available size for user data in the \ref + * uip_buf buffer. The macro is intended to be used for checking + * bounds of available user data. + * + * Example: + \code + snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); + \endcode + * + * \hideinitializer + */ +#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + + +#define UIP_PROTO_ICMP 1 +#define UIP_PROTO_TCP 6 +#define UIP_PROTO_UDP 17 +#define UIP_PROTO_ICMP6 58 + +/* Header sizes. */ +#if UIP_CONF_IPV6 +#define UIP_IPH_LEN 40 +#else /* UIP_CONF_IPV6 */ +#define UIP_IPH_LEN 20 /* Size of IP header */ +#endif /* UIP_CONF_IPV6 */ +#define UIP_UDPH_LEN 8 /* Size of UDP header */ +#define UIP_TCPH_LEN 20 /* Size of TCP header */ +#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + + UDP + header */ +#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + + TCP + header */ +#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN + + +#if UIP_FIXEDADDR +extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +#else /* UIP_FIXEDADDR */ +extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +#endif /* UIP_FIXEDADDR */ + + + +/** + * Representation of a 48-bit Ethernet address. + */ +struct uip_eth_addr { + u8_t addr[6]; +}; + +/** + * Calculate the Internet checksum over a buffer. + * + * The Internet checksum is the one's complement of the one's + * complement sum of all 16-bit words in the buffer. + * + * See RFC1071. + * + * \param buf A pointer to the buffer over which the checksum is to be + * computed. + * + * \param len The length of the buffer over which the checksum is to + * be computed. + * + * \return The Internet checksum of the buffer. + */ +u16_t uip_chksum(u16_t *buf, u16_t len); + +/** + * Calculate the IP header checksum of the packet header in uip_buf. + * + * The IP header checksum is the Internet checksum of the 20 bytes of + * the IP header. + * + * \return The IP header checksum of the IP header in the uip_buf + * buffer. + */ +u16_t uip_ipchksum(void); + +/** + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. + * + * The TCP checksum is the Internet checksum of data contents of the + * TCP segment, and a pseudo-header as defined in RFC793. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +/** + * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. + * + * The UDP checksum is the Internet checksum of data contents of the + * UDP segment, and a pseudo-header as defined in RFC768. + * + * \return The UDP checksum of the UDP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_udpchksum(void); + + +#endif /* __UIP_H__ */ + + +/** @} */ diff --git a/bundles/uip/uip/uip_arch.h b/bundles/uip/uip/uip_arch.h new file mode 100644 index 00000000..71fd84bf --- /dev/null +++ b/bundles/uip/uip/uip_arch.h @@ -0,0 +1,138 @@ +/** + * \addtogroup uip + * {@ + */ + +/** + * \defgroup uiparch Architecture specific uIP functions + * @{ + * + * The functions in the architecture specific module implement the IP + * check sum and 32-bit additions. + * + * The IP checksum calculation is the most computationally expensive + * operation in the TCP/IP stack and it therefore pays off to + * implement this in efficient assembler. The purpose of the uip-arch + * module is to let the checksum functions to be implemented in + * architecture specific assembler. + * + */ + +/** + * \file + * Declarations of architecture specific functions. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $ + * + */ + +#ifndef __UIP_ARCH_H__ +#define __UIP_ARCH_H__ + +#include "uip.h" + +/** + * Carry out a 32-bit addition. + * + * Because not all architectures for which uIP is intended has native + * 32-bit arithmetic, uIP uses an external C function for doing the + * required 32-bit additions in the TCP protocol processing. This + * function should add the two arguments and place the result in the + * global variable uip_acc32. + * + * \note The 32-bit integer pointed to by the op32 parameter and the + * result in the uip_acc32 variable are in network byte order (big + * endian). + * + * \param op32 A pointer to a 4-byte array representing a 32-bit + * integer in network byte order (big endian). + * + * \param op16 A 16-bit integer in host byte order. + */ +void uip_add32(u8_t *op32, u16_t op16); + +/** + * Calculate the Internet checksum over a buffer. + * + * The Internet checksum is the one's complement of the one's + * complement sum of all 16-bit words in the buffer. + * + * See RFC1071. + * + * \note This function is not called in the current version of uIP, + * but future versions might make use of it. + * + * \param buf A pointer to the buffer over which the checksum is to be + * computed. + * + * \param len The length of the buffer over which the checksum is to + * be computed. + * + * \return The Internet checksum of the buffer. + */ +u16_t uip_chksum(u16_t *buf, u16_t len); + +/** + * Calculate the IP header checksum of the packet header in uip_buf. + * + * The IP header checksum is the Internet checksum of the 20 bytes of + * the IP header. + * + * \return The IP header checksum of the IP header in the uip_buf + * buffer. + */ +u16_t uip_ipchksum(void); + +/** + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. + * + * The TCP checksum is the Internet checksum of data contents of the + * TCP segment, and a pseudo-header as defined in RFC793. + * + * \note The uip_appdata pointer that points to the packet data may + * point anywhere in memory, so it is not possible to simply calculate + * the Internet checksum of the contents of the uip_buf buffer. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +u16_t uip_udpchksum(void); + +/** @} */ +/** @} */ + +#endif /* __UIP_ARCH_H__ */ diff --git a/bundles/uip/uip/uip_arp.c b/bundles/uip/uip/uip_arp.c new file mode 100644 index 00000000..75ade649 --- /dev/null +++ b/bundles/uip/uip/uip_arp.c @@ -0,0 +1,423 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uiparp uIP Address Resolution Protocol + * @{ + * + * The Address Resolution Protocol ARP is used for mapping between IP + * addresses and link level addresses such as the Ethernet MAC + * addresses. ARP uses broadcast queries to ask for the link level + * address of a known IP address and the host which is configured with + * the IP address for which the query was meant, will respond with its + * link level address. + * + * \note This ARP implementation only supports Ethernet. + */ + +/** + * \file + * Implementation of the ARP Address Resolution Protocol. + * \author Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $ + * + */ + + +#include "uip_arp.h" + +#include + +struct arp_hdr { + struct uip_eth_hdr ethhdr; + u16_t hwtype; + u16_t protocol; + u8_t hwlen; + u8_t protolen; + u16_t opcode; + struct uip_eth_addr shwaddr; + u16_t sipaddr[2]; + struct uip_eth_addr dhwaddr; + u16_t dipaddr[2]; +}; + +struct ethip_hdr { + struct uip_eth_hdr ethhdr; + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +}; + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +#define ARP_HWTYPE_ETH 1 + +struct arp_entry { + u16_t ipaddr[2]; + struct uip_eth_addr ethaddr; + u8_t time; +}; + +static const struct uip_eth_addr broadcast_ethaddr = + {{0xff,0xff,0xff,0xff,0xff,0xff}}; +static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; + +static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; +static u16_t ipaddr[2]; +static u8_t i, c; + +static u8_t arptime; +static u8_t tmpage; + +#define BUF ((struct arp_hdr *)&uip_buf[0]) +#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) +/*-----------------------------------------------------------------------------------*/ +/** + * Initialize the ARP module. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_init(void) +{ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + memset(arp_table[i].ipaddr, 0, 4); + } +} +/*-----------------------------------------------------------------------------------*/ +/** + * Periodic ARP processing function. + * + * This function performs periodic timer processing in the ARP module + * and should be called at regular intervals. The recommended interval + * is 10 seconds between the calls. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_timer(void) +{ + struct arp_entry *tabptr; + + ++arptime; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && + arptime - tabptr->time >= UIP_ARP_MAXAGE) { + memset(tabptr->ipaddr, 0, 4); + } + } + +} +/*-----------------------------------------------------------------------------------*/ +static void +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) +{ + register struct arp_entry *tabptr; + /* Walk through the ARP mapping table and try to find an entry to + update. If none is found, the IP -> MAC address mapping is + inserted in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + + tabptr = &arp_table[i]; + /* Only check those entries that are actually in use. */ + if(tabptr->ipaddr[0] != 0 && + tabptr->ipaddr[1] != 0) { + + /* Check if the source IP address of the incoming packet matches + the IP address in this ARP table entry. */ + if(ipaddr[0] == tabptr->ipaddr[0] && + ipaddr[1] == tabptr->ipaddr[1]) { + + /* An old entry found, update this and return. */ + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; + + return; + } + } + } + + /* If we get here, no existing ARP table entry was found, so we + create one. */ + + /* First, we try to find an unused entry in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(tabptr->ipaddr[0] == 0 && + tabptr->ipaddr[1] == 0) { + break; + } + } + + /* If no unused entry is found, we try to find the oldest entry and + throw it away. */ + if(i == UIP_ARPTAB_SIZE) { + tmpage = 0; + c = 0; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(arptime - tabptr->time > tmpage) { + tmpage = arptime - tabptr->time; + c = i; + } + } + i = c; + tabptr = &arp_table[i]; + } + + /* Now, i is the ARP table entry which we will fill with the new + information. */ + memcpy(tabptr->ipaddr, ipaddr, 4); + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; +} +/*-----------------------------------------------------------------------------------*/ +/** + * ARP processing for incoming IP packets + * + * This function should be called by the device driver when an IP + * packet has been received. The function will check if the address is + * in the ARP cache, and if so the ARP cache entry will be + * refreshed. If no ARP cache entry was found, a new one is created. + * + * This function expects an IP packet with a prepended Ethernet header + * in the uip_buf[] buffer, and the length of the packet in the global + * variable uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +#if 0 +void +uip_arp_ipin(void) +{ + uip_len -= sizeof(struct uip_eth_hdr); + + /* Only insert/update an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + if((IPBUF->srcipaddr[0] & uip_netmask[0]) != + (uip_hostaddr[0] & uip_netmask[0])) { + return; + } + if((IPBUF->srcipaddr[1] & uip_netmask[1]) != + (uip_hostaddr[1] & uip_netmask[1])) { + return; + } + uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); + + return; +} +#endif /* 0 */ +/*-----------------------------------------------------------------------------------*/ +/** + * ARP processing for incoming ARP packets. + * + * This function should be called by the device driver when an ARP + * packet has been received. The function will act differently + * depending on the ARP packet type: if it is a reply for a request + * that we previously sent out, the ARP cache will be filled in with + * the values from the ARP reply. If the incoming ARP packet is an ARP + * request for our IP address, an ARP reply packet is created and put + * into the uip_buf[] buffer. + * + * When the function returns, the value of the global variable uip_len + * indicates whether the device driver should send out a packet or + * not. If uip_len is zero, no packet should be sent. If uip_len is + * non-zero, it contains the length of the outbound packet that is + * present in the uip_buf[] buffer. + * + * This function expects an ARP packet with a prepended Ethernet + * header in the uip_buf[] buffer, and the length of the packet in the + * global variable uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_arpin(void) +{ + + if(uip_len < sizeof(struct arp_hdr)) { + uip_len = 0; + return; + } + uip_len = 0; + + switch(BUF->opcode) { + case HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + reply. */ + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + /* First, we register the one who made the request in our ARP + table, since it is likely that we will do more communication + with this host in the future. */ + uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + + /* The reply opcode is 2. */ + BUF->opcode = HTONS(2); + + memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); + + BUF->dipaddr[0] = BUF->sipaddr[0]; + BUF->dipaddr[1] = BUF->sipaddr[1]; + BUF->sipaddr[0] = uip_hostaddr[0]; + BUF->sipaddr[1] = uip_hostaddr[1]; + + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + uip_len = sizeof(struct arp_hdr); + } + break; + case HTONS(ARP_REPLY): + /* ARP reply. We insert or update the ARP table if it was meant + for us. */ + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + } + break; + } + + return; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Prepend Ethernet header to an outbound IP packet and see if we need + * to send out an ARP request. + * + * This function should be called before sending out an IP packet. The + * function checks the destination IP address of the IP packet to see + * what Ethernet MAC address that should be used as a destination MAC + * address on the Ethernet. + * + * If the destination IP address is in the local network (determined + * by logical ANDing of netmask and our IP address), the function + * checks the ARP cache to see if an entry for the destination IP + * address is found. If so, an Ethernet header is prepended and the + * function returns. If no ARP cache entry is found for the + * destination IP address, the packet in the uip_buf[] is replaced by + * an ARP request packet for the IP address. The IP packet is dropped + * and it is assumed that they higher level protocols (e.g., TCP) + * eventually will retransmit the dropped packet. + * + * If the destination IP address is not on the local network, the IP + * address of the default router is used instead. + * + * When the function returns, a packet is present in the uip_buf[] + * buffer, and the length of the packet is in the global variable + * uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_out(void) +{ + struct arp_entry *tabptr; + + /* Find the destination IP address in the ARP table and construct + the Ethernet header. If the destination IP addres isn't on the + local network, we use the default router's IP address instead. + + If not ARP table entry is found, we overwrite the original IP + packet with an ARP request for the IP address. */ + + /* First check if destination is a local broadcast. */ + if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { + memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); + } else { + /* Check if the destination address is on the local network. */ + if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ipaddr_copy(ipaddr, uip_draddr); + } else { + /* Else, we use the destination IP address. */ + uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); + } + + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { + break; + } + } + + if(i == UIP_ARPTAB_SIZE) { + /* The destination address was not in our ARP table, so we + overwrite the IP packet with an ARP request. */ + + memset(BUF->ethhdr.dest.addr, 0xff, 6); + memset(BUF->dhwaddr.addr, 0x00, 6); + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); + + uip_ipaddr_copy(BUF->dipaddr, ipaddr); + uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); + BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ + BUF->hwtype = HTONS(ARP_HWTYPE_ETH); + BUF->protocol = HTONS(UIP_ETHTYPE_IP); + BUF->hwlen = 6; + BUF->protolen = 4; + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + + uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; + + uip_len = sizeof(struct arp_hdr); + return; + } + + /* Build an ethernet header. */ + memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); + } + memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + + IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); + + uip_len += sizeof(struct uip_eth_hdr); +} +/*-----------------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/bundles/uip/uip/uip_arp.h b/bundles/uip/uip/uip_arp.h new file mode 100644 index 00000000..e32594da --- /dev/null +++ b/bundles/uip/uip/uip_arp.h @@ -0,0 +1,144 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \addtogroup uiparp + * @{ + */ + +/** + * \file + * Macros and definitions for the ARP module. + * \author Adam Dunkels + */ + + +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $ + * + */ + +#ifndef __UIP_ARP_H__ +#define __UIP_ARP_H__ + +#include "uip.h" + + +extern struct uip_eth_addr uip_ethaddr; + +/** + * The Ethernet header. + */ +struct uip_eth_hdr { + struct uip_eth_addr dest; + struct uip_eth_addr src; + u16_t type; +}; + +#define UIP_ETHTYPE_ARP 0x0806 +#define UIP_ETHTYPE_IP 0x0800 +#define UIP_ETHTYPE_IP6 0x86dd + + +/* The uip_arp_init() function must be called before any of the other + ARP functions. */ +void uip_arp_init(void); + +/* The uip_arp_ipin() function should be called whenever an IP packet + arrives from the Ethernet. This function refreshes the ARP table or + inserts a new mapping if none exists. The function assumes that an + IP packet with an Ethernet header is present in the uip_buf buffer + and that the length of the packet is in the uip_len variable. */ +/*void uip_arp_ipin(void);*/ +#define uip_arp_ipin() + +/* The uip_arp_arpin() should be called when an ARP packet is received + by the Ethernet driver. This function also assumes that the + Ethernet frame is present in the uip_buf buffer. When the + uip_arp_arpin() function returns, the contents of the uip_buf + buffer should be sent out on the Ethernet if the uip_len variable + is > 0. */ +void uip_arp_arpin(void); + +/* The uip_arp_out() function should be called when an IP packet + should be sent out on the Ethernet. This function creates an + Ethernet header before the IP header in the uip_buf buffer. The + Ethernet header will have the correct Ethernet MAC destination + address filled in if an ARP table entry for the destination IP + address (or the IP address of the default router) is present. If no + such table entry is found, the IP packet is overwritten with an ARP + request and we rely on TCP to retransmit the packet that was + overwritten. In any case, the uip_len variable holds the length of + the Ethernet frame that should be transmitted. */ +void uip_arp_out(void); + +/* The uip_arp_timer() function should be called every ten seconds. It + is responsible for flushing old entries in the ARP table. */ +void uip_arp_timer(void); + +/** @} */ + +/** + * \addtogroup uipconffunc + * @{ + */ + + +/** + * Specifiy the Ethernet MAC address. + * + * The ARP code needs to know the MAC address of the Ethernet card in + * order to be able to respond to ARP queries and to generate working + * Ethernet headers. + * + * \note This macro only specifies the Ethernet MAC address to the ARP + * code. It cannot be used to change the MAC address of the Ethernet + * card. + * + * \param eaddr A pointer to a struct uip_eth_addr containing the + * Ethernet MAC address of the Ethernet card. + * + * \hideinitializer + */ +#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \ + uip_ethaddr.addr[1] = eaddr.addr[1];\ + uip_ethaddr.addr[2] = eaddr.addr[2];\ + uip_ethaddr.addr[3] = eaddr.addr[3];\ + uip_ethaddr.addr[4] = eaddr.addr[4];\ + uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) + +/** @} */ +/** @} */ + +#endif /* __UIP_ARP_H__ */ diff --git a/bundles/uip/uip/uiplib.c b/bundles/uip/uip/uiplib.c new file mode 100644 index 00000000..cb5af2cd --- /dev/null +++ b/bundles/uip/uip/uiplib.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of + * Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $ + * + */ + + +#include "uip.h" +#include "uiplib.h" + + +/*-----------------------------------------------------------------------------------*/ +unsigned char +uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr) +{ + unsigned char tmp; + char c; + unsigned char i, j; + + tmp = 0; + + for(i = 0; i < 4; ++i) { + j = 0; + do { + c = *addrstr; + ++j; + if(j > 4) { + return 0; + } + if(c == '.' || c == 0) { + *ipaddr = tmp; + ++ipaddr; + tmp = 0; + } else if(c >= '0' && c <= '9') { + tmp = (tmp * 10) + (c - '0'); + } else { + return 0; + } + ++addrstr; + } while(c != '.' && c != 0); + } + return 1; +} + +/*-----------------------------------------------------------------------------------*/ diff --git a/bundles/uip/uip/uiplib.h b/bundles/uip/uip/uiplib.h new file mode 100644 index 00000000..c676849e --- /dev/null +++ b/bundles/uip/uip/uiplib.h @@ -0,0 +1,71 @@ +/** + * \file + * Various uIP library functions. + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2002, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $ + * + */ +#ifndef __UIPLIB_H__ +#define __UIPLIB_H__ + +/** + * \addtogroup uipconvfunc + * @{ + */ + +/** + * Convert a textual representation of an IP address to a numerical representation. + * + * This function takes a textual representation of an IP address in + * the form a.b.c.d and converts it into a 4-byte array that can be + * used by other uIP functions. + * + * \param addrstr A pointer to a string containing the IP address in + * textual form. + * + * \param addr A pointer to a 4-byte array that will be filled in with + * the numerical representation of the address. + * + * \retval 0 If the IP address could not be parsed. + * \retval Non-zero If the IP address was parsed. + */ +unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr); + +/** @} */ + +#endif /* __UIPLIB_H__ */ diff --git a/bundles/uip/uip/uipopt.h b/bundles/uip/uip/uipopt.h new file mode 100644 index 00000000..ae263652 --- /dev/null +++ b/bundles/uip/uip/uipopt.h @@ -0,0 +1,541 @@ +/** + * \defgroup uipopt Configuration options for uIP + * @{ + * + * uIP is configured using the per-project configuration file + * uipopt.h. This file contains all compile-time options for uIP and + * should be tweaked to match each specific project. The uIP + * distribution contains a documented example "uipopt.h" that can be + * copied and modified for each project. + * + * \note Most of the configuration options in the uipopt.h should not + * be changed, but rather the per-project uip-conf.h file. + */ + +/** + * \file + * Configuration options for uIP. + * \author Adam Dunkels + * + * This file is used for tweaking various configuration options for + * uIP. You should make a copy of this file into one of your project's + * directories instead of editing this example "uipopt.h" file that + * comes with the uIP distribution. + */ + +/* + * Copyright (c) 2001-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $ + * + */ + +#ifndef __UIPOPT_H__ +#define __UIPOPT_H__ + +#ifndef UIP_LITTLE_ENDIAN +#define UIP_LITTLE_ENDIAN 3412 +#endif /* UIP_LITTLE_ENDIAN */ +#ifndef UIP_BIG_ENDIAN +#define UIP_BIG_ENDIAN 1234 +#endif /* UIP_BIG_ENDIAN */ + +#include "uip-conf.h" + +/*------------------------------------------------------------------------------*/ + +/** + * \name Static configuration options + * @{ + * + * These configuration options can be used for setting the IP address + * settings statically, but only if UIP_FIXEDADDR is set to 1. The + * configuration options for a specific node includes IP address, + * netmask and default router as well as the Ethernet address. The + * netmask, default router and Ethernet address are appliciable only + * if uIP should be run over Ethernet. + * + * All of these should be changed to suit your project. +*/ + +/** + * Determines if uIP should use a fixed IP address or not. + * + * If uIP should use a fixed IP address, the settings are set in the + * uipopt.h file. If not, the macros uip_sethostaddr(), + * uip_setdraddr() and uip_setnetmask() should be used instead. + * + * \hideinitializer + */ +#define UIP_FIXEDADDR 0 + +/** + * Ping IP address asignment. + * + * uIP uses a "ping" packets for setting its own IP address if this + * option is set. If so, uIP will start with an empty IP address and + * the destination IP address of the first incoming "ping" (ICMP echo) + * packet will be used for setting the hosts IP address. + * + * \note This works only if UIP_FIXEDADDR is 0. + * + * \hideinitializer + */ +#ifdef UIP_CONF_PINGADDRCONF +#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF +#else /* UIP_CONF_PINGADDRCONF */ +#define UIP_PINGADDRCONF 0 +#endif /* UIP_CONF_PINGADDRCONF */ + + +/** + * Specifies if the uIP ARP module should be compiled with a fixed + * Ethernet MAC address or not. + * + * If this configuration option is 0, the macro uip_setethaddr() can + * be used to specify the Ethernet address at run-time. + * + * \hideinitializer + */ +#define UIP_FIXEDETHADDR 0 + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \name IP configuration options + * @{ + * + */ +/** + * The IP TTL (time to live) of IP packets sent by uIP. + * + * This should normally not be changed. + */ +#define UIP_TTL 64 + +/** + * Turn on support for IP packet reassembly. + * + * uIP supports reassembly of fragmented IP packets. This features + * requires an additonal amount of RAM to hold the reassembly buffer + * and the reassembly code size is approximately 700 bytes. The + * reassembly buffer is of the same size as the uip_buf buffer + * (configured by UIP_BUFSIZE). + * + * \note IP packet reassembly is not heavily tested. + * + * \hideinitializer + */ +#define UIP_REASSEMBLY 0 + +/** + * The maximum time an IP fragment should wait in the reassembly + * buffer before it is dropped. + * + */ +#define UIP_REASS_MAXAGE 40 + +/** @} */ + +/*------------------------------------------------------------------------------*/ +/** + * \name UDP configuration options + * @{ + */ + +/** + * Toggles wether UDP support should be compiled in or not. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP +#define UIP_UDP UIP_CONF_UDP +#else /* UIP_CONF_UDP */ +#define UIP_UDP 0 +#endif /* UIP_CONF_UDP */ + +/** + * Toggles if UDP checksums should be used or not. + * + * \note Support for UDP checksums is currently not included in uIP, + * so this option has no function. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP_CHECKSUMS +#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS +#else +#define UIP_UDP_CHECKSUMS 0 +#endif + +/** + * The maximum amount of concurrent UDP connections. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP_CONNS +#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS +#else /* UIP_CONF_UDP_CONNS */ +#define UIP_UDP_CONNS 10 +#endif /* UIP_CONF_UDP_CONNS */ + +/** + * The name of the function that should be called when UDP datagrams arrive. + * + * \hideinitializer + */ + + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \name TCP configuration options + * @{ + */ + +/** + * Determines if support for opening connections from uIP should be + * compiled in. + * + * If the applications that are running on top of uIP for this project + * do not need to open outgoing TCP connections, this configration + * option can be turned off to reduce the code size of uIP. + * + * \hideinitializer + */ +#define UIP_ACTIVE_OPEN 1 + +/** + * The maximum number of simultaneously open TCP connections. + * + * Since the TCP connections are statically allocated, turning this + * configuration knob down results in less RAM used. Each TCP + * connection requires approximatly 30 bytes of memory. + * + * \hideinitializer + */ +#ifndef UIP_CONF_MAX_CONNECTIONS +#define UIP_CONNS 10 +#else /* UIP_CONF_MAX_CONNECTIONS */ +#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS +#endif /* UIP_CONF_MAX_CONNECTIONS */ + + +/** + * The maximum number of simultaneously listening TCP ports. + * + * Each listening TCP port requires 2 bytes of memory. + * + * \hideinitializer + */ +#ifndef UIP_CONF_MAX_LISTENPORTS +#define UIP_LISTENPORTS 20 +#else /* UIP_CONF_MAX_LISTENPORTS */ +#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS +#endif /* UIP_CONF_MAX_LISTENPORTS */ + +/** + * Determines if support for TCP urgent data notification should be + * compiled in. + * + * Urgent data (out-of-band data) is a rarely used TCP feature that + * very seldom would be required. + * + * \hideinitializer + */ +#define UIP_URGDATA 0 + +/** + * The initial retransmission timeout counted in timer pulses. + * + * This should not be changed. + */ +#define UIP_RTO 3 + +/** + * The maximum number of times a segment should be retransmitted + * before the connection should be aborted. + * + * This should not be changed. + */ +#define UIP_MAXRTX 8 + +/** + * The maximum number of times a SYN segment should be retransmitted + * before a connection request should be deemed to have been + * unsuccessful. + * + * This should not need to be changed. + */ +#define UIP_MAXSYNRTX 5 + +/** + * The TCP maximum segment size. + * + * This is should not be to set to more than + * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. + */ +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + +/** + * The size of the advertised receiver's window. + * + * Should be set low (i.e., to the size of the uip_buf buffer) is the + * application is slow to process incoming data, or high (32768 bytes) + * if the application processes data quickly. + * + * \hideinitializer + */ +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_RECEIVE_WINDOW UIP_TCP_MSS +#else +#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW +#endif + +/** + * How long a connection should stay in the TIME_WAIT state. + * + * This configiration option has no real implication, and it should be + * left untouched. + */ +#define UIP_TIME_WAIT_TIMEOUT 120 + + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \name ARP configuration options + * @{ + */ + +/** + * The size of the ARP table. + * + * This option should be set to a larger value if this uIP node will + * have many connections from the local network. + * + * \hideinitializer + */ +#ifdef UIP_CONF_ARPTAB_SIZE +#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE +#else +#define UIP_ARPTAB_SIZE 8 +#endif + +/** + * The maxium age of ARP table entries measured in 10ths of seconds. + * + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD + * default). + */ +#define UIP_ARP_MAXAGE 120 + +/** @} */ + +/*------------------------------------------------------------------------------*/ + +/** + * \name General configuration options + * @{ + */ + +/** + * The size of the uIP packet buffer. + * + * The uIP packet buffer should not be smaller than 60 bytes, and does + * not need to be larger than 1500 bytes. Lower size results in lower + * TCP throughput, larger size results in higher TCP throughput. + * + * \hideinitializer + */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_BUFSIZE 400 +#else /* UIP_CONF_BUFFER_SIZE */ +#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE +#endif /* UIP_CONF_BUFFER_SIZE */ + + +/** + * Determines if statistics support should be compiled in. + * + * The statistics is useful for debugging and to show the user. + * + * \hideinitializer + */ +#ifndef UIP_CONF_STATISTICS +#define UIP_STATISTICS 0 +#else /* UIP_CONF_STATISTICS */ +#define UIP_STATISTICS UIP_CONF_STATISTICS +#endif /* UIP_CONF_STATISTICS */ + +/** + * Determines if logging of certain events should be compiled in. + * + * This is useful mostly for debugging. The function uip_log() + * must be implemented to suit the architecture of the project, if + * logging is turned on. + * + * \hideinitializer + */ +#ifndef UIP_CONF_LOGGING +#define UIP_LOGGING 0 +#else /* UIP_CONF_LOGGING */ +#define UIP_LOGGING UIP_CONF_LOGGING +#endif /* UIP_CONF_LOGGING */ + +/** + * Broadcast support. + * + * This flag configures IP broadcast support. This is useful only + * together with UDP. + * + * \hideinitializer + * + */ +#ifndef UIP_CONF_BROADCAST +#define UIP_BROADCAST 0 +#else /* UIP_CONF_BROADCAST */ +#define UIP_BROADCAST UIP_CONF_BROADCAST +#endif /* UIP_CONF_BROADCAST */ + +/** + * Print out a uIP log message. + * + * This function must be implemented by the module that uses uIP, and + * is called by uIP whenever a log message is generated. + */ +void uip_log(char *msg); + +/** + * The link level header length. + * + * This is the offset into the uip_buf where the IP header can be + * found. For Ethernet, this should be set to 14. For SLIP, this + * should be set to 0. + * + * \hideinitializer + */ +#ifdef UIP_CONF_LLH_LEN +#define UIP_LLH_LEN UIP_CONF_LLH_LEN +#else /* UIP_CONF_LLH_LEN */ +#define UIP_LLH_LEN 14 +#endif /* UIP_CONF_LLH_LEN */ + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \name CPU architecture configuration + * @{ + * + * The CPU architecture configuration is where the endianess of the + * CPU on which uIP is to be run is specified. Most CPUs today are + * little endian, and the most notable exception are the Motorolas + * which are big endian. The BYTE_ORDER macro should be changed to + * reflect the CPU architecture on which uIP is to be run. + */ + +/** + * The byte order of the CPU architecture on which uIP is to be run. + * + * This option can be either BIG_ENDIAN (Motorola byte order) or + * LITTLE_ENDIAN (Intel byte order). + * + * \hideinitializer + */ +#if 0 +#ifdef UIP_CONF_BYTE_ORDER +#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER +#else /* UIP_CONF_BYTE_ORDER */ +#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN +#endif /* UIP_CONF_BYTE_ORDER */ +#endif + +/** @} */ +/*------------------------------------------------------------------------------*/ + +/** + * \name Appication specific configurations + * @{ + * + * An uIP application is implemented using a single application + * function that is called by uIP whenever a TCP/IP event occurs. The + * name of this function must be registered with uIP at compile time + * using the UIP_APPCALL definition. + * + * uIP applications can store the application state within the + * uip_conn structure by specifying the type of the application + * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. + * + * The file containing the definitions must be included in the + * uipopt.h file. + * + * The following example illustrates how this can look. + \code + +void httpd_appcall(void); +#define UIP_APPCALL httpd_appcall + +struct httpd_state { + u8_t state; + u16_t count; + char *dataptr; + char *script; +}; +typedef struct httpd_state uip_tcp_appstate_t + \endcode + */ + +/** + * \var #define UIP_APPCALL + * + * The name of the application function that uIP should call in + * response to TCP/IP events. + * + */ + +/** + * \var typedef uip_tcp_appstate_t + * + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. + */ + +/** + * \var typedef uip_udp_appstate_t + * + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. + */ +/** @} */ +/** @} */ + +#endif /* __UIPOPT_H__ */ diff --git a/bundles/uip/unix/Makefile b/bundles/uip/unix/Makefile new file mode 100644 index 00000000..ed64927b --- /dev/null +++ b/bundles/uip/unix/Makefile @@ -0,0 +1,44 @@ +# Copyright (c) 2001, Adam Dunkels. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# This file is part of the uIP TCP/IP stack. +# +# $Id: Makefile,v 1.13 2006/06/11 21:55:03 adam Exp $ +# + +all: uip + +CC = gcc +AR = ar +APPS = webserver +CFLAGS = -Wall -g -I../uip -I. -fpack-struct -Os +-include ../uip/Makefile.include + +uip: $(addprefix $(OBJECTDIR)/, main.o tapdev.o clock-arch.o) apps.a uip.a + +clean: + rm -fr *.o *~ *core uip $(OBJECTDIR) *.a diff --git a/bundles/uip/unix/clock-arch.c b/bundles/uip/unix/clock-arch.c new file mode 100644 index 00000000..d140aaf7 --- /dev/null +++ b/bundles/uip/unix/clock-arch.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * Implementation of architecture-specific clock functionality + * \author + * Adam Dunkels + */ + +#include "clock-arch.h" +#include + +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/unix/clock-arch.h b/bundles/uip/unix/clock-arch.h new file mode 100644 index 00000000..e51eee93 --- /dev/null +++ b/bundles/uip/unix/clock-arch.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $ + */ + +#ifndef __CLOCK_ARCH_H__ +#define __CLOCK_ARCH_H__ + +typedef int clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#endif /* __CLOCK_ARCH_H__ */ diff --git a/bundles/uip/unix/main.c b/bundles/uip/unix/main.c new file mode 100644 index 00000000..e4130e9d --- /dev/null +++ b/bundles/uip/unix/main.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: main.c,v 1.16 2006/06/11 21:55:03 adam Exp $ + * + */ + + +#include "uip.h" +#include "uip_arp.h" +#include "tapdev.h" + +#include "timer.h" + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + int i; + uip_ipaddr_t ipaddr; + struct timer periodic_timer, arp_timer; + + timer_set(&periodic_timer, CLOCK_SECOND / 2); + timer_set(&arp_timer, CLOCK_SECOND * 10); + + tapdev_init(); + uip_init(); + + uip_ipaddr(ipaddr, 192,168,0,2); + uip_sethostaddr(ipaddr); + uip_ipaddr(ipaddr, 192,168,0,1); + uip_setdraddr(ipaddr); + uip_ipaddr(ipaddr, 255,255,255,0); + uip_setnetmask(ipaddr); + + httpd_init(); + + /* telnetd_init();*/ + + /* hello_world_init();*/ + + /* { + u8_t mac[6] = {1,2,3,4,5,6}; + dhcpc_init(&mac, 6); + }*/ + + /*uip_ipaddr(ipaddr, 127,0,0,1); + smtp_configure("localhost", ipaddr); + SMTP_SEND("adam@sics.se", NULL, "uip-testing@example.com", + "Testing SMTP from uIP", + "Test message sent by uIP\r\n");*/ + + /* + webclient_init(); + resolv_init(); + uip_ipaddr(ipaddr, 195,54,122,204); + resolv_conf(ipaddr); + resolv_query("www.sics.se");*/ + + + + while(1) { + uip_len = tapdev_read(); + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + tapdev_send(); + } + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_send(); + } + } + + } else if(timer_expired(&periodic_timer)) { + timer_reset(&periodic_timer); + for(i = 0; i < UIP_CONNS; i++) { + uip_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + tapdev_send(); + } + } + +#if UIP_UDP + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + tapdev_send(); + } + } +#endif /* UIP_UDP */ + + /* Call the ARP timer function every 10 seconds. */ + if(timer_expired(&arp_timer)) { + timer_reset(&arp_timer); + uip_arp_timer(); + } + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +uip_log(char *m) +{ + printf("uIP log message: %s\n", m); +} +void +resolv_found(char *name, u16_t *ipaddr) +{ + u16_t *ipaddr2; + + if(ipaddr == NULL) { + printf("Host '%s' not found.\n", name); + } else { + printf("Found name '%s' = %d.%d.%d.%d\n", name, + htons(ipaddr[0]) >> 8, + htons(ipaddr[0]) & 0xff, + htons(ipaddr[1]) >> 8, + htons(ipaddr[1]) & 0xff); + /* webclient_get("www.sics.se", 80, "/~adam/uip");*/ + } +} +#ifdef __DHCPC_H__ +void +dhcpc_configured(const struct dhcpc_state *s) +{ + uip_sethostaddr(s->ipaddr); + uip_setnetmask(s->netmask); + uip_setdraddr(s->default_router); + resolv_conf(s->dnsaddr); +} +#endif /* __DHCPC_H__ */ +void +smtp_done(unsigned char code) +{ + printf("SMTP done with code %d\n", code); +} +void +webclient_closed(void) +{ + printf("Webclient: connection closed\n"); +} +void +webclient_aborted(void) +{ + printf("Webclient: connection aborted\n"); +} +void +webclient_timedout(void) +{ + printf("Webclient: connection timed out\n"); +} +void +webclient_connected(void) +{ + printf("Webclient: connected, waiting for data...\n"); +} +void +webclient_datahandler(char *data, u16_t len) +{ + printf("Webclient: got %d bytes of data.\n", len); +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/unix/tapdev.c b/bundles/uip/unix/tapdev.c new file mode 100644 index 00000000..417b2888 --- /dev/null +++ b/bundles/uip/unix/tapdev.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Adam Dunkels + * + * $Id: tapdev.c,v 1.8 2006/06/07 08:39:58 adam Exp $ + */ + +#define UIP_DRIPADDR0 192 +#define UIP_DRIPADDR1 168 +#define UIP_DRIPADDR2 0 +#define UIP_DRIPADDR3 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef linux +#include +#include +#include +#define DEVTAP "/dev/net/tun" +#else /* linux */ +#define DEVTAP "/dev/tap0" +#endif /* linux */ + +#include "uip.h" + +static int drop = 0; +static int fd; + + +/*---------------------------------------------------------------------------*/ +void +tapdev_init(void) +{ + char buf[1024]; + + fd = open(DEVTAP, O_RDWR); + if(fd == -1) { + perror("tapdev: tapdev_init: open"); + exit(1); + } + +#ifdef linux + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + perror(buf); + exit(1); + } + } +#endif /* Linux */ + + snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d", + UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3); + system(buf); + +} +/*---------------------------------------------------------------------------*/ +unsigned int +tapdev_read(void) +{ + fd_set fdset; + struct timeval tv, now; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = 1000; + + + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + + ret = select(fd + 1, &fdset, NULL, NULL, &tv); + if(ret == 0) { + return 0; + } + ret = read(fd, uip_buf, UIP_BUFSIZE); + if(ret == -1) { + perror("tap_dev: tapdev_read: read"); + } + + /* printf("--- tap_dev: tapdev_read: read %d bytes\n", ret);*/ + /* { + int i; + for(i = 0; i < 20; i++) { + printf("%x ", uip_buf[i]); + } + printf("\n"); + }*/ + /* check_checksum(uip_buf, ret);*/ + return ret; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_send(void) +{ + int ret; + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ + + /* drop++; + if(drop % 8 == 7) { + printf("Dropped a packet!\n"); + return; + }*/ + ret = write(fd, uip_buf, uip_len); + if(ret == -1) { + perror("tap_dev: tapdev_send: writev"); + exit(1); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/bundles/uip/unix/tapdev.h b/bundles/uip/unix/tapdev.h new file mode 100644 index 00000000..280bc52b --- /dev/null +++ b/bundles/uip/unix/tapdev.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack. + * + * $Id: tapdev.h,v 1.1 2002/01/10 06:22:56 adam Exp $ + * + */ + +#ifndef __TAPDEV_H__ +#define __TAPDEV_H__ + +void tapdev_init(void); +unsigned int tapdev_read(void); +void tapdev_send(void); + +#endif /* __TAPDEV_H__ */ diff --git a/bundles/uip/unix/uip-conf.h b/bundles/uip/unix/uip-conf.h new file mode 100644 index 00000000..2878c85b --- /dev/null +++ b/bundles/uip/unix/uip-conf.h @@ -0,0 +1,157 @@ +/** + * \addtogroup uipopt + * @{ + */ + +/** + * \name Project-specific configuration options + * @{ + * + * uIP has a number of configuration options that can be overridden + * for each project. These are kept in a project-specific uip-conf.h + * file and all configuration names have the prefix UIP_CONF. + */ + +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the uIP TCP/IP stack + * + * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $ + */ + +/** + * \file + * An example uIP configuration file + * \author + * Adam Dunkels + */ + +#ifndef __UIP_CONF_H__ +#define __UIP_CONF_H__ + +#include + +/** + * 8 bit datatype + * + * This typedef defines the 8-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint8_t u8_t; + +/** + * 16 bit datatype + * + * This typedef defines the 16-bit type used throughout uIP. + * + * \hideinitializer + */ +typedef uint16_t u16_t; + +/** + * Statistics datatype + * + * This typedef defines the dataype used for keeping statistics in + * uIP. + * + * \hideinitializer + */ +typedef unsigned short uip_stats_t; + +/** + * Maximum number of TCP connections. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_CONNECTIONS 40 + +/** + * Maximum number of listening TCP ports. + * + * \hideinitializer + */ +#define UIP_CONF_MAX_LISTENPORTS 40 + +/** + * uIP buffer size. + * + * \hideinitializer + */ +#define UIP_CONF_BUFFER_SIZE 420 + +/** + * CPU byte order. + * + * \hideinitializer + */ +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +/** + * Logging on or off + * + * \hideinitializer + */ +#define UIP_CONF_LOGGING 1 + +/** + * UDP support on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP 0 + +/** + * UDP checksums on or off + * + * \hideinitializer + */ +#define UIP_CONF_UDP_CHECKSUMS 1 + +/** + * uIP statistics on or off + * + * \hideinitializer + */ +#define UIP_CONF_STATISTICS 1 + +/* Here we include the header file for the application(s) we use in + our project. */ +/*#include "smtp.h"*/ +/*#include "hello-world.h"*/ +/*#include "telnetd.h"*/ +#include "webserver.h" +/*#include "dhcpc.h"*/ +/*#include "resolv.h"*/ +/*#include "webclient.h"*/ + +#endif /* __UIP_CONF_H__ */ + +/** @} */ +/** @} */ diff --git a/link.bat b/link.bat new file mode 100644 index 00000000..3a04decb --- /dev/null +++ b/link.bat @@ -0,0 +1,27 @@ +@echo off + +call:chklink n2n_v1 bundles\n2n_meyerd\n2n_v1 +call:chklink n2n_v2 bundles\n2n_ntop_v2 +call:chklink n2n_v2s bundles\n2n_meyerd\n2n_v2 +call:chklink n2n_v3 bundles\n2n_ntop_v3 +call:chklink uip bundles\uip\uip +call:chklink tun2tap bundles\tun2tap +call:chklink slog bundles\slog +pushd Hin2n\src\main\cpp +call:chklink n2n_v1 ..\..\..\..\bundles\n2n_meyerd\n2n_v1 +call:chklink n2n_v2 ..\..\..\..\bundles\n2n_ntop_v2 +call:chklink n2n_v2s ..\..\..\..\bundles\n2n_meyerd\n2n_v2 +call:chklink n2n_v3 ..\..\..\..\bundles\n2n_ntop_v3 +call:chklink uip ..\..\..\..\bundles\uip\uip +call:chklink tun2tap ..\..\..\..\bundles\tun2tap +call:chklink slog ..\..\..\..\bundles\slog +popd +goto:eof + +:chklink +if exist %~1 ( + pushd %~1 2>nul && popd || (del /q %~1 & mklink /d %~1 %~2) +) else ( + mklink /d %~1 %~2 +) +goto:eof \ No newline at end of file diff --git a/n2n_v1 b/n2n_v1 new file mode 120000 index 00000000..6182eef8 --- /dev/null +++ b/n2n_v1 @@ -0,0 +1 @@ +bundles/n2n_meyerd/n2n_v1 \ No newline at end of file diff --git a/n2n_v2 b/n2n_v2 new file mode 120000 index 00000000..15470553 --- /dev/null +++ b/n2n_v2 @@ -0,0 +1 @@ +bundles/n2n_ntop_v2 \ No newline at end of file diff --git a/n2n_v2s b/n2n_v2s new file mode 120000 index 00000000..88a13cc4 --- /dev/null +++ b/n2n_v2s @@ -0,0 +1 @@ +bundles/n2n_meyerd/n2n_v2 \ No newline at end of file diff --git a/n2n_v3 b/n2n_v3 new file mode 120000 index 00000000..e38596b4 --- /dev/null +++ b/n2n_v3 @@ -0,0 +1 @@ +bundles/n2n_ntop_v3 \ No newline at end of file diff --git a/slog b/slog new file mode 120000 index 00000000..6bec3e9b --- /dev/null +++ b/slog @@ -0,0 +1 @@ +bundles/slog \ No newline at end of file diff --git a/tun2tap b/tun2tap new file mode 120000 index 00000000..9a89de52 --- /dev/null +++ b/tun2tap @@ -0,0 +1 @@ +bundles/tun2tap \ No newline at end of file diff --git a/uip b/uip new file mode 120000 index 00000000..fb57db9f --- /dev/null +++ b/uip @@ -0,0 +1 @@ +bundles/uip/uip \ No newline at end of file
LocalRemoteStateRetransmissionsTimerFlags